Lambda code does not get zipped during `package` command when using substacks - amazon-web-services

I am using CloudFormation for creating lambda functions. The lambda functions are stored in a separate file and then recreated using aws cloudformation package command. This works fine and the stack gets deployed successfully:
# Filename: auth/auth.yml
# Lambda JS file: auth/lambda-pre-signup.js
Resources:
## Other resources here
MyPreSignupLambda:
Type: AWS::Lambda::Function
Properties:
Architectures:
- arm64
Code: 'lambda-pre-signup.js'
Handler: 'lambda-pre-signup.handler'
Runtime: nodejs16.x
PackageType: Zip
Role: !GetAtt MyRole.Arn
Command:
aws cloudformation package --template-file auth.yml --s3-bucket my-bucket --output-template-file generated-auth.yml
aws cloudformation deploy --template-file generated-auth.yml --stack-name test-stack --capabilities CAPABILITY_IAM
However, when I create a root stack template and reference lambda, I get an error:
Resource handler returned message: "Could not unzip uploaded file. Please check your file, then try to upload again. (Service: Lambda, Status Code: 400, Request ID: xxxxx)"
When I check the S3 bucket for the uploaded file, the source code is there but it is not zipped (I can download and directly view the code without needing to unzip it).
Here is my current CF template for root stack:
# Filename: root.yml
Resources:
MyAuth:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: ./auth/auth.yml
Command:
aws cloudformation package --template-file root.yml --s3-bucket my-bucket --output-template-file generated-root.yml
aws cloudformation deploy --template-file generated-root.yml --stack-name test-root-stack --capabilities CAPABILITY_IAM
Is there some option in the package command to make sure that the uploaded lambda code is zipped?
EDIT: Wrote a wrong argument

Related

AWS SAM package Parameter CodeUri refers to a file or folder that does not exist

I am trying to deploy a lambda function to AWS via codepipeline.
In the pipeline I have a codebuild step which uses SAM to build the function and package it into an S3 bucket.
I keep getting the following error
Error: Unable to upload artifact LambdaMultiRegion referenced by CodeUri parameter of LambdaMultiRegion resource.
Parameter CodeUri of resource LambdaMultiRegion refers to a file or folder that does not exist /codebuild/output/src259622855/src/.aws-sam/build/LambdaMultiRegion
I have confirmed that the bucket does exist and codebuild's IAM role has access to it.
Buildspec file looks like this
version: 0.2
phases:
install:
runtime-versions:
python: 3.7
build:
commands:
- sam build
- sam package --s3-bucket poc-lambdamultiregion --output-template-file outputtemplate.yml
artifacts:
files:
- template.yml
- outputtemplate.yml
template file
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Python function
Resources:
LambdaMultiRegion:
Type: AWS::Serverless::Function
Properties:
Handler: Index.lambda_handler
Runtime: python3.7
FunctionName: PoC-LambdaMultiRegion
CodeUri: ./src
Any idea why sam cannot put the package in S3 bucket?

Cloudformation CLI Parameters Using Deploy Command

I'm having an issue getting the hang of using cli parameters with cloudformation deploy. I'm trying to pass in the name for the S3 bucket that I want to create, and the cli is complaining when I use --parameters to do this:
aws cloudformation deploy --template-file ../infrastructure.yml --stack-name stripe-python --parameters ParameterKey=S3BucketNameParameter,ParameterValue=lambda-artifacts-948d01bc80800b36
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:
aws help
aws <command> help
aws <command> <subcommand> help
aws: error: argument subcommand: Invalid choice, valid choices are:
push | register
deregister | install
Obviously, omitting the parameter doesn't work either:
aws cloudformation deploy --template-file ../infrastructure.yml --stack-name stripe-python
An error occurred (ValidationError) when calling the CreateChangeSet operation: Parameters: [S3BucketNameParameter] must have values
When I look at the documentation for cloudformation deploy, it seems to not support --parameters but instead --parameter-overrides, which I've also tried with no success:
aws cloudformation deploy --template-file ../infrastructure.yml --stack-name stripe-python --parameter-overrides S3BucketNameParameter=lambda-artifacts-948d01bc80800b36
An error occurred (ValidationError) when calling the CreateChangeSet operation: Parameters: [S3BucketNameParameter] must have values
So, I'm kind of stumped here. Here's the template file's contents:
cat ../infrastructure.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Lambda application that calls the Stripe API to tokenize and charge credit cards
Parameters:
S3BucketNameParameter:
Type: String
Description: Bucket name for deployment artifacts
Resources:
S3Bucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
Properties:
BucketName: !Ref S3BucketNameParameter
Any suggestions on the correct approach here?
This works for me:
aws cloudformation deploy --template-file infrastructure.yml --stack-name stripe-python --parameter-overrides S3BucketNameParameter=lambda-artifacts-948d01bc80800b36
It may come down to awscli version (ie check the version you are running and the doc for that)
aws --version
aws-cli/2.0.44 Python/3.8.5 Darwin/18.7.0 source/x86_64

Unable to upload artifact None referenced by CodeUri parameter of HelloWorldFunction resource

I'm following this tutorial to learn how to use SAM.
Here's the code I have:
template.yml:
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs8.10
index.js
exports.handler = async function(event, context) {
return 'Hello World!';
};
When I run
sam package \
--template-file template.yml \
--output-template-file package.yml \
--s3-bucket brian-test-sam
I got the error saying Unable to upload artifact None referenced by CodeUri parameter of HelloWorldFunction resource.
An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
Why does this happen?
I've created the S3 bucket brian-test-sam on my AWS account. I've checked that my IAM user has AmazonS3FullAccess permission.
The command
sam --debug package \ <aws:dev-bionime>
--template-file template.yml \
--output-template-file package.yml \
--s3-bucket brian-test-sam
says that the error was generated by aws cloudformation package --output-template-file package.yml --s3-bucket brian-test-sam --template-file /path/to/my/files/helloworld/template.yml
What is wrong with my cloudformation?
My aws cli version is aws-cli/1.16.169 Python/3.7.3 Darwin/18.6.0 botocore/1.12.159. And my npm version is 6.10.1.
Even I faced this issue, I took following action.
Issue was due to mismatch of bucket in app.py and in sam package command, so corrected bucket name and run the "sam build" and "sam package" commands again, it worked for me !
One more care, If you face time related issue while running "sam package", then there should be invalid system time, get it corrected and run "sam package" again.
I found this error was because I hadn't added S3 access to the service role that runs the build
On the Permissions tab of Role, Select the button "Attach policies" and choose "AmazonS3FullAccess", attach it via "Attach policy" button.
Now re-run your build.
For me the issue was my aws credentials were from the wrong account. aws s3 ls showed the issue pretty quickly.
I faced same issue, while running the below command:
sam package \
--template-file template.yml \
--output-template-file package.yml \
--s3-bucket <your_bucket_name>
Above command was missing AWS credentials with default profile. [I did not have a default profile in AWS configurations] If default profile is not located, you may need to provide profile name in the command as below
sam package \
--template-file template.yml \
--output-template-file package.yml \
--s3-bucket brian-test-sam \
--profile <profile_name>
In general this type of issue is likely to be caused by the account being used for the CloudFormation deployment not having access to a specified S3 bucket that resources need to be uploaded to during the deployment. You can try the following:
Create a new S3 bucket using the same account that the deployment is being run under, and ensure that this is the bucket that's used in the deployment
Ensure the account has full access to S3 as explained in the answer by #JiminyJames - https://stackoverflow.com/a/63532472/1549918
You need to provide the CodeUri property pointing your local directory.
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs8.10
CodeUri: ./code
Uploading to 5ede295b3d735d7cadf2a5368bcff051 124068 / 124068.0 (100.00%)
Successfully packaged artifacts and wrote output template to file package.yaml.
Execute the following command to deploy the packaged template..........
worked for me by applying bucket policies as below
{
"Version": "2012-10-17",
"Id": "Policy1624441771081",
"Statement": [
{
"Sid": "Stmt1624441768741",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "<your_bucket_arn>/*"
}
]
}
This can also happen when you do a sam build followed by a sam deploy and you don't specify the template file that the build step created. If you remove the --template-file or point it to the .aws file that was created in sam build, it fixes this problem.
If you have this issue, and it also shows these error messages:
Error: Unable to upload artifact HelloWorldFunction referenced by CodeUri parameter of HelloWorldFunction resource.
ZIP does not support timestamps before 1980
Then the issue is because the file timestamps are earlier than 1980. It's an easy fix, in terminal, in the folder you are attempting to run "sam deploy" from, just run this to update the timestamps:
touch `find . -type f`

AWS CodePipeline CodeBuild SAM Lambda

I have a PipeLine for Lambda (NodeJS) Auto Deploy from CodeCommit.
My buildspec.yml
version: 0.1
phases:
install:
commands:
- npm install
- aws cloudformation package --template-file samTemplate.yaml --s3-bucket codepipeline-551 --output-template-file outputSamTemplate.yaml
artifacts:
type: zip
files:
- samTemplate.yaml
- outputSamTemplate.yaml
My samTemplate.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Serverless Specification template describing your function.
Resources:
KashIoTLambda:
Type: 'AWS::Serverless::Function'
Properties:
Handler: lambda.handler
Runtime: nodejs8.10
CodeUri: ./
Description: ''
MemorySize: 128
Timeout: 3
Role: 'arn:aws:iam::1234:role/abc-backend'
Events:
Api1:
Type: Api
Properties:
Path: '/{proxy+}'
Method: OPTIONS
Api2:
Type: Api
Properties:
Path: /MyResource
Method: ANY
Environment:
Variables:
REGION: ap-south-1
The policy attached to the role mentioned for CodeBuild gives access to All Resources & All S3 commands.
However, I have the following error from build logs
[Container] 2019/01/03 13:25:39 Running command npm install
added 122 packages in 3.498s
[Container] 2019/01/03 13:25:44 Running command aws cloudformation package --template-file samTemplate.yaml --s3-bucket codepipeline-551 --output-template-file outputSamTemplate.yaml
Unable to upload artifact ./ referenced by CodeUri parameter of ABCLambda resource.
An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
[Container] 2019/01/03 13:25:46 Command did not exit successfully aws cloudformation package --template-file samTemplate.yaml --s3-bucket codepipeline-551 --output-template-file outputSamTemplate.yaml exit status 255
[Container] 2019/01/03 13:25:46 Phase complete: INSTALL Success: false
[Container] 2019/01/03 13:25:46 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: aws cloudformation package --template-file samTemplate.yaml --s3-bucket codepipeline-551 --output-template-file outputSamTemplate.yaml. Reason: exit status 255
Check the policies/permissions on the bucket itself.
If you were like me, you may have selected the default location option as the artifact store in the pipeline settings when you first set it up. In which case, there may be policies on the S3 bucket itself blocking access.
For me, once I removed the bucket policy the unable to upload artifact error was resolved and my build process went on to complete successfully.
I hope this helps you.

How to create and zip a docker container for AWS Lambda

I'm trying to create and then zip a Docker container to upload to S3 to be run by an AWS Lambda function. I was trying to work off an article but the instructions are sparse (https://github.com/abhisuri97/auto-alt-text-lambda-api).
I've installed Docker and the Amazon Linux image but I don't know how to create a Docker container that contains the github repo, and then zip it so that it can be accessed by Lambda.
This is what I've tried to piece together from other tutorials:
git clone https://github.com/abhisuri97/auto-alt-text-lambda-api.git
cd auto-alt-text-lambda-api
docker run -v -it amazonlinux:2017.12
zip -r -9 -q ~/main.zip
Any help would be greatly appreciated.
The instructions aren't clear but I suspect the reference to Docker is just for testing. You don't need Docker to run an AWS Lambda function. You will need an AWS API Gateway API though to execute the Lambda function over HTTPS.
I'd recommend starting with a CloudFormation stack using the AWS Serverless Application Mode (https://docs.aws.amazon.com/lambda/latest/dg/serverless_app.html).
Create an S3 bucket for the zip file and create a CloudFormation template similar to:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
LambdaFunction:
Type: AWS::Serverless::Function
Properties:
Handler: application.predict
Runtime: python2.7
Events:
HttpGet:
Type: Api
Properties:
Path: 'auto-alt-text-api'
Method: get
Package the Lambda function with:
aws cloudformation package --template-file template.yaml --output-template-file template-out.yaml --s3-bucket <your-bucket> --s3-prefix <your-prefix>
Then deploy it with:
aws cloudformation deploy --template-file template-out.yaml --stack-name auto-alt-text-lambda-api-stack --capabilities CAPABILITY_IAM
You will probably have to add IAM roles and Lambda permissions to the template for the application to work properly.