Hey Guys I could use some insight or advice, I ha...
# aws
a
Hey Guys I could use some insight or advice, I have a pulumi script that builds a lambda and is activated by a github action. This action is triggered when someone makes changes to the lambda's code base in the repo and is merged to main. About 20% to 20% of the time I get this error.
Copy code
error: 1 error occurred:
    	* creating Lambda Function (prod-customer-service-lambda-75e83a8): operation error Lambda: CreateFunction, https response error StatusCode: 400, RequestID: 4345617f-2790-46cc-a88e-1ed70eada3c2, InvalidParameterValueException: Uploaded file must be a non-empty zip
So I switched from using the command module to build then zip to the runOutput and AssetArchive option. I found that by adding some console.log I get better results. But still see the above error. Here is the conso.log showing the archive from the same update that produced the error above.
Copy code
}
    lambdaAssetResult Archive: {
      'dist/index.js': FileAsset {
        __pulumiAsset: true,
        path: Promise {
          '../../domains/lambdaName/microservices/lambdaName/dist/index.js'
        }
      }
    }
Here is the snippet of the lambda creation script creating the AssetArchive
Copy code
const lambdaAssetResult = command.local.runOutput({
  command: `npm run build`,
  assetPaths: ["dist/**.js"],
  dir: "../../domains/lambdaName/microservices/lambdaName/"
});

lambdaAssetResult.apply((result)=>{
  //he logging helps it work for production for some reason
  console.log('lambdaAssetResult:', result)
  console.log('lambdaAssetResult Archive:', result?.assets)
})

const lambdaAsset = lambdaAssetResult.apply((result)=>{
  return new pulumi.asset.AssetArchive({'index.js': result!.assets!['dist/index.js']})
});

if (!lambdaAsset) {
  throw new Error("Failed to create archive");
}
Here is the snippet where we define the lambda and apply the AssetArchive for the code.
Copy code
export const myLambda = new aws.lambda.Function(`${env}-customer-service-lambda`, {
  code: lambdaAsset,
  description: `Lambda for things we do. Last updated: ${Date.now()}`,
  role: lambdaRole.arn,
  handler: "index.lambdaEntry",
  runtime: "nodejs18.x",
  kmsKeyArn: encryptionKey.arn,
  environment: {
    variables: {
      RDS: Rds,
      USERNAME: encryptEnv(env == "prod" ? config.requireSecret("USERNAME") : mySqlUser?.user ?? ""),
      PASSWORD: encryptEnv(env == "prod" ? config.requireSecret("PASSWORD") : rdsPassword ?? ""),
      KMS: encryptionKey.arn
    }
  },
  timeout: 10,
  vpcConfig: {
    securityGroupIds: [lambdaSecurityGroup.id],
    subnetIds: privateSubnets,
  },
}, {
  dependsOn: [
    lambdaExecutionPolicyAttachment
  ],
  replaceOnChanges: ["*"]
});
I am open to suggestions. I have tried to add to the dependsOn section the lambdaAsset but I get a slew of issues that I am not able to figure out.
Copy code
Type 'Output<AssetArchive>' is not assignable to type 'Input<Resource>'.
  Type 'Output<AssetArchive>' is not assignable to type 'OutputInstance<Resource>'.
    Types of property 'apply' are incompatible.
      Type '{ <U>(func: (t: AssetArchive) => Promise<U>): Output<U>; <U>(func: (t: AssetArchive) => OutputInstance<U>): Output<...>; <U>(func: (t: AssetArchive) => U): Output<...>; }' is not assignable to type '{ <U>(func: (t: Resource) => Promise<U>): Output<U>; <U>(func: (t: Resource) => OutputInstance<U>): Output<U>; <U>(func: (t: Resource) => U): Output<...>; }'.
        Types of parameters 'func' and 'func' are incompatible.
          Types of parameters 't' and 't' are incompatible.
            Type 'AssetArchive' is missing the following properties from type 'Resource': urn, getProviderts(2322)
const lambdaAsset: pulumi.Output<pulumi.asset.AssetArchive>
I am also thinking of have the github action build the zip archive but I am not clear yet on how to export / import that to the pulumi stack and
code:
value of the aws.lambda.Function. Thank you again for time and advice!
b
Did you figure this out?
Having the same issue
a
Yes. We ended up using the github action to trigger a NPM script to compile the package. Then pass that into the pulumi/actions as a file archive. We never could get pulumi to reliably compile the the lamba code.
Copy code
- name: Install for the lambda code
      run: npm install
      working-directory: ./domains/lambda/code/path

    - name: Package the lambda code for development
      run: npm run package
      working-directory: ./domains/lambda/code/path 

    - name: Test if function.zip file is corrupted (dev)
      run: |
        file ./domains/lambda/code/path/dist/function.zip
        unzip -t ./domains/lambda/code/path/dist/function.zip     

    - uses: pulumi/actions@v4
      with:
        refresh: false
        command: up
       
        upsert: true
        work-dir: ./pulumi/lambdaStack/
        
      env:
        PULUMI_TOKEN: ${{ secrets.PULUMI_TOKEN }}
        LAMBDA_ARCHIVE: /home/runner/work/folders/and/domains/lambda/code/path/dist/function.zip
Here is the script in the package.json file located in the lambdaCode folder.
Copy code
"scripts": {
    "build": "mkdir -p dist && esbuild lambdaCodeFile.ts --bundle --sourcemap --platform=node --target=es2020 --outfile=dist/index.js && echo 'Build complete'",
    "package": "npm run build && (cd dist && zip function.zip index.js)",
  }
b
Yep
same
for some reason I’d get that empty zip error sporadically when using pulumi.archive and fileasset no matter how I structured my code. I assumed it was a race condition so put the archive stuff in a separate custom component resource and made the lambda function depend on it, but still had the issue
I’m now building the zip separately from the pulumi application and am just referencing an s3 path instead
I’ll see if I can find some time to put in an issue for this sometime next week