Reference CodeCommit Filename in CodeBuild buildspec - amazon-web-services

I am trying to create a cloudformation stack from the CodeCommit repository.
I have created build project in CodeBuild.
My Build Command is like this:
build:
commands:
- aws cloudformation create-stack
--stack-name SGStack
--template-body file://security_groups.template
--parameters ParameterKey=VPCID,ParameterValue=vpc-77092d1
I think I have problem with the '--template-body' command.
How can I reference file of codecommit repo in codebuild build command?

In your buildspec, try accessing the template using pwd or using CODEBUILD_SRC_DIR environment variable:
e.g.:
build:
commands:
- aws cloudformation create-stack
--stack-name SGStack
--template-body file://$(pwd)/security_groups.template
--parameters ParameterKey=VPCID,ParameterValue=vpc-77092d1

Related

AWS Cloudformation nested stack deployment template path

I'm trying to deploy nested stack using command
aws cloudformation deploy --stack-name "${STACK_NAME}" --template-file "${S3_ROOT_TEMPLATE}" --parameter-overrides ${PARAMS[#]} --region ${REGION}
But despite the S3_ROOT_TEMPLATE having proper url, I get the error
Invalid template path
https://<s3-bucket-name>.s3.us-east-2.amazonaws.com/sm-domain-templates/main_stack.yaml
Any idea what's wrong with the above?
Even though in the console you have to use S3 path, in the awscli command, it expects the local file path of the root stack file
The following command deploys a template named S3_ROOT_TEMPLATE to a stack named STACK_NAME:
STACK_NAME="cfn-demo"
S3_ROOT_TEMPLATE="cfn-demo.yaml"
REGION="us-east-1"
bucket_name="cfn-demo-bucket"
aws cloudformation deploy --stack-name $STACK_NAME --template-file $S3_ROOT_TEMPLATE --parameter-overrides $PARAMS[#] --region $REGION
If your templates are sized greater than 51,200 bytes, then the name of the S3 bucket where this command uploads your CloudFormation template.
aws cloudformation deploy --stack-name $STACK_NAME --template-file $S3_ROOT_TEMPLATE --parameter-overrides $PARAMS[#] --region $REGION --s3-bucket $bucket_name
For updating the stack, you could upload the template file to the S3 bucket by using copy and then, update the stack by using the S3 object URL as the template source.
aws s3 cp $S3_ROOT_TEMPLATE s3://$bucket_name
aws cloudformation update-stack --stack-name $STACK_NAME --template-url https://$bucket_name.s3.$REGION.amazonaws.com/$S3_ROOT_TEMPLATE

Cloudformation deploy --parameter-overrides doesnt accept file Workaround

I am in process of using setting up pipeline using codebuild and use cloudformation package and cloudformation deploy to spin up the stack which spuns lambda function. Now i know that with cloudformation deploy we cant use parameters file with --parameters-overrides and this feature request is still in open state wit AWS https://github.com/aws/aws-cli/issues/2828 . So i am trying to use a workaround using JQ which is decsribed in this link https://github.com/aws/aws-cli/issues/3274#issuecomment-529155262 like below.
PARAMETERS_FILE="parameters.json" && PARAMS=($(jq -r '.Parameters[] | [.ParameterKey, .ParameterValue] | "\(.[0])=\(.[1])"' ${PARAMETERS_FILE})) - aws cloudformation deploy --template-file /codebuild/output/packaged.yaml --region us-east-2 --stack-name InitialSetup --capabilities CAPABILITY_IAM --parameter-overrides ${PARAMS[#]}
This workaround works well if tested via cli . I also tried this workaround inside a container as buildspec.yaml file creates a container in background which runs these commands , but codebuild doesnt excute the aws cloudformation deploy step and fails . I get error "aws: error: argument --parameter-overrides: expected at least one argument" . I even tried copying the two steps of workaround in shell script and then executing it but i run into error "[Container] 2020/01/21 09:19:14 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: ./test.sh. Reason: exit status 255"
Can someone please guide me here .My buildspec.yaml file is as below :
'''
version: 0.2
phases:
install:
runtime-versions:
java: corretto8
commands:
- wget -O jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
- chmod +x ./jq
- cp jq /usr/bin
- jq --version
pre_build:
commands:
# - echo "[Pre-Build phase]
build:
commands:
- aws cloudformation package --template-file master.yaml --s3-bucket rtestbucket --output-template-file packaged.yaml
- aws s3 cp ./packaged.yaml s3://rtestbucket/packaged.yaml
- aws s3 cp s3://rtestbucket/packaged.yaml /codebuild/output
post_build:
commands:
- PARAMETERS_FILE="parameters.json" && PARAMS=($(jq -r '.Parameters[] | [.ParameterKey, .ParameterValue] | "\(.[0])=\(.[1])"' ${PARAMETERS_FILE}))
- ls
- aws cloudformation deploy --template-file /codebuild/output/packaged.yaml --region us-east-2 --stack-name InitialSetup --capabilities CAPABILITY_IAM --parameter-overrides ${PARAMS[#]}
artifacts:
type: zip
files:
- packaged.yaml
CodeBuild buildspec commands are not running in bash shell and I think the syntax:
${PARAMS[#]}
... is bash specific.
As per the answer here: https://stackoverflow.com/a/44811491/12072431
Try to wrap your commands in a script file with a shebang specifying the shell you'd like the commands to execute with.
The expression ${PARAMS[#]} is not returning any value, which causes the error aws: error: argument --parameter-overrides: expected at least one argument. Review the code and resolve, or remove that parameter.
I was able to resolve this issue with executing the all the required steps in shell script and providing access to script.

AWS SAM CLI ignoring my Python dependencies during build, package, and deploy

I'm trying to deploy an AWS Lambda function with the SAM CLI tool, from MacOS, not using Docker containers.
SAM CLI version 0.4.0
Python 3.8 runtime for Lambda function
Python 3.7 installed locally on MacOS
I have a requirements.txt file, in the same directory as my Lambda function file
Requirements.txt
boto3
botostubs
Deploy Script (PowerShell)
sam build --template-file $InputTemplate
sam package --region $AWSRegion --template-file $InputTemplate --profile $ProfileName --s3-bucket $BucketName --output-template-file $OutputTemplate
sam deploy --region $AWSRegion --profile $ProfileName --template-file $OutputTemplate --stack-name $StackName --capabilities CAPABILITY_NAMED_IAM
Actual Behavior
SAM CLI is ignoring my requirements.txt file, and only deploying my source code. This results in the following error when I test my function.
{
"errorMessage": "Unable to import module 'xxxxxxxxxxxxxx': No module named 'botostubs'",
"errorType": "Runtime.ImportModuleError"
}
Expected Behavior
SAM CLI packages up the declared Python dependencies, in requirements.txt, along with my source code.
Question: How can I ensure that the SAM CLI downloads and packages my Python dependencies, along with my source code? I followed the documentation, to the best of my knowledge.
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-build.html
Just figured it out, reading about the sam build command in a bit more depth. I didn't realize that it was creating a subfolder called .aws-sam/build/ and storing the modified template there.
I updated my commands and paths, and it is working just fine now.
$InputTemplate = "$PSScriptRoot/cloudformation.yml"
$BuiltTemplate = "$PSScriptRoot/.aws-sam/build/template.yaml"
$BucketName = 'xxxxxxx'
$AWSRegion = 'xxxxxx'
$StackName = 'xxxxxx'
# Package and deploy the application
sam build --template-file $InputTemplate
sam package --region $AWSRegion --template-file $BuiltTemplate --profile $ProfileName --s3-bucket $BucketName
sam deploy --region $AWSRegion --profile $ProfileName --template-file $BuiltTemplate --stack-name $StackName --capabilities CAPABILITY_NAMED_IAM --s3-bucket $BucketName
I had similar problem and root cause of my failure was that I was specifying --template-file template.yml. As per this issue https://github.com/awslabs/aws-sam-cli/issues/1252 SAM CLI looks for the code uri specified in my template.yml and uploads only the function code.
So my solution was:
specify --template-file in sam build
run sam deploy without --template-file option
Had a similar problem. Resolved it by changing directory into the build folder (doesn't use these directory shell variables)
sam build --use-container
cd .aws-sam/build/
sam package --template-file template.yaml --s3-bucket sdd-s3-basebucket --output-template-file packaged.yaml
sam deploy --template-file ./packaged.yaml --stack-name prod --capabilities CAPABILITY_IAM --region eu-central-1
Make sure your 'requirements.txt' file is right under the path specified in 'CodeUri' attribute of the Lambda in your template file.
Mmy solution was:
specify --template-file in sam build
run sam deploy without --template-file option
It works but everytime starts script, it ask about confirmation about deploying changset - it is not a problem when I use script but problem appears when it is executed by CI/CD.

CAPABILITY_NAMED_IAM using cloud9

I am trying to do all my dev work using cloud9 template for serverless apps
It complains that i don't have CAPABILITY_NAMED_IAM due to the fact that I am creating a role. How do I edit cloud9 deploy defaults to include CAPABILITY_NAMED_IAM?
If you started your Cloud9 with Code star, you can modify the pipeline to enable capabilities to CAPABILITY_NAMED_IAM in the AWS management console.
You need to edit the GenerateChangeSet section in the deploy step.
Otherwhise you should look into your create/update stack to add the --capabilities CAPABILITY_NAMED_IAM :
cloudformation create-stack --stack-name my-stack --template-url dummy-template.yaml --role-arn ... --tags ... --capabilities CAPABILITY_NAMED_IAM
https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-iam-template.html#using-iam-capabilities

Importing AWS information from CloudFormation to CodeBuild

I have a pipeline in AWS with Codestar, CodeBuild, CloudFormation, etc.
I am trying to figure out how to get information from the CloudFormation step returned to the CodeBuild step. Let me break it down:
I have a buildspec.yml for CodeBuild
# buildspec.yml
...
phases:
...
build:
commands:
- aws cloudformation package --region $REGION --template template.yml --s3-bucket $S3_BUCKET --output-template $OUTPUT_TEMPLATE
The above kicks off a CloudFormation build using our template.yml
# template.yml
...
S3BucketAssets:
Type: AWS::S3::Bucket
...
At this point, it creates a unique name for an S3 bucket. Awesome. Now, for step 2 in my buildspec.yml for CodeBuild, I want to push items to the S3 bucket just created in the CloudFormation template. BUT, I don't know how to get the dynamically created name of the S3 bucket from the CloudFormation template. I want something similar to:
# buildspec.yml
...
phases:
...
build:
commands:
# this is the same step as shown above
- aws cloudformation package --region $REGION --template template.yml --s3-bucket $S3_BUCKET --output-template $OUTPUT_TEMPLATE
# this is the new step
- aws s3 sync dist_files/ s3://{NAME_OF_THE_NEW_S3_BUCKET}
How can I accomplish getting the dynamically named S3 bucket so that I can push to it?
I am aware that within a CloudFormation template, you can reference the S3 bucket name with something like !GetAtt [ClientWebAssets, WebsiteURL]. But, I do not know how to get that information out of the cloudformation template and back into the codebuild template.
You could move to using CodePipeline. Stage one would be deploying the application via cloudformation with an output artifact being the stack creation output
http://docs.aws.amazon.com/codepipeline/latest/userguide/reference-pipeline-structure.html#action-requirements