How to pass parameter as a file in AWS CloudFormation deploy? - amazon-web-services

I was trying to update the existing CloudFormation stack with the below command.
aws cloudformation deploy
there is no option to pass parameter file with deploy option. we tried to pass parameter file with --parameter-overrides but it's giving the below error.
value passed to --parameter-overrides must be of format Key=Value
the command we try to execute is
aws cloudformation deploy --template-file sg.yml --stack-name Common-SG --parameter-overrides ip.json --no-execute-changeset
is there any way to pass the parameters in file with aws cloudformation deploy

Passing a parameters stored as JSON in a local file looks like:
aws cloudformation deploy \
--stack-name demo \
--template-file test.yml --parameter-overrides file://test.json \
and the test.json like this.
{
"Parameters": {
"BucketName": "myawesometestdemo"
}
}
test.yml
---
AWSTemplateFormatVersion: '2010-09-09'
Description: Simple S3 Bucket test
Parameters:
BucketName:
Type: String
Description: The name of the S3 Bucket to create
Metadata:
AWS::CloudFormation::Interface:
ParameterLabels:
BucketName:
default: S3 Bucket Name
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
aws cli version :
aws --version
aws-cli/2.2.35 Python/3. XXX

workaround for this issue is pass parameters with jq command.
yum install jq
Below is the syntax for the same.
aws cloudformation deploy --template-file sg.yml --stack-name Common-SG --parameter-overrides $(jq -r '.[] | [.ParameterKey, .ParameterValue] | "\(.[0])=\(.[1])"' ip.json) --no-execute-changeset

this might be too late already, but for the sake of future similar issue I found this answer on (https://github.com/aws/serverless-application-model/issues/111)
The command should look like:
aws cloudformation deploy --template-file sg.yml --stack-name Common-SG --parameter-overrides $(cat params.properties) --no-execute-changeset
Now this is not going to be a json file, since "parameter-overrieds" expects a Key=Value pairs!

You can actually pass a file path to Cloudformation deploy --parameter-overrides. The below syntax worked for me:
aws cloudformation deploy \
--template-file template.yml \
--stack-name my-stack \
--parameter-overrides file://path/to_parameter_file.json
where file://path/to_parameter_file.json represents the path to the parameter you want to pass.

I had the same issue with the files
Initially I had used
[
{
"ParameterKey": "EnvironmentStage",
"ParameterValue": "sandbox"
}
]
This did not work I got the error that the elements should be of Class 'Str' and not an ordered.Dict
2nd iteration I changed it to as mentioned in the earlier responses that did not work either
finally I have it as
[
"EnvironmentStage=sandbox"
]
and it works well

This worked for me in buildspec file:
Structure of parameters.json:
[
{
"ParameterKey": "Key1",
"ParameterValue": "Value1"
}
]
and then:
post_build:
commands:
- echo "Start build..."
- aws cloudformation deploy --template-file ./template.yaml --parameter-overrides $(jq -r '.[] | [.ParameterKey, .ParameterValue] | "\(.[0])=\(.[1])"' ./parameters/parameters.json) --stack-name ${stackName} --capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND

You can do like this based on aws doc:
https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy/index.html
aws cloudformation deploy --template-file /path_to_template/template.json --stack-name my-new-stack --parameter-overrides Key1=Value1 Key2=Value2

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

How to detect changes in ECR image when using sam deploy and CloudFormation

I have a CF template and ECR image referenced in this template
Image: !Sub <registry_id>.dkr.ecr.eu-central-1.amazonaws.com/<repo_name>:${AWS::StackName}
If I update an image and then run
sam deploy --template-file devops/templates/${CFFILENAME}.yml \
--capabilities CAPABILITY_NAMED_IAM --stack-name "${STACK_NAME}" \
--region ${AWS_DEFAULT_REGION} --no-fail-on-empty-changeset
It won't detect any changes and I have to run
aws ecs update-service --cluster Env-${STACK_NAME}-ClusterALB --service Env-Backend --force-new-deployment
To update ECS task later in the pipeline, but it is causing stack drift.
I would like to avoid it and do it all in one step in my CI pipeline and only using CF.
Is there any pretty way to do it?
After giving it a bit more thought - this is what I came up with.
I introduced new parameter in my cloudformation file such as:
Parameters:
ImageTag:
Description: "Image SHA"
Type: String
Then I referenced it in task definition
ContainerDefinitions:
- Name: admin
Essential: true
Image: !Sub <repo_id>.dkr.ecr.eu-central-1.amazonaws.com/<repo_name>:${AWS::StackName}-${ImageTag}
And passed in the parameter to SAM using --parameter-overrides as follows:
sam deploy --template-file devops/templates/${CFFILENAME}.yml \
--capabilities CAPABILITY_NAMED_IAM --stack-name "${STACK_NAME}" \
--region ${AWS_DEFAULT_REGION} --no-fail-on-empty-changeset \
--parameter-overrides ImageTag=${IMAGE_TAG}
And the image tag is generated during the pipeline in GitLab CI using commit SHA as follows:
- IMAGE_TAG="$(echo $CI_COMMIT_SHA | head -c 8)"

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

How to extract VPCID, PrivateSubnet1, PublicSubnet1, S3BucketName & DBSubnetGroup automatically after executing [aws cloudformation create-stack]

I ran this command:
aws cloudformation create-stack --stack-name my-stackname --template-body file://stack.yml --parameters file://stack-params.json
And got this result:
arams.json
{
"StackId": "arn:aws:cloudformation:us-east-1:343434345343:stack/some-stack-name/43434f-sed434-1147-867c-098sdfs09sdd"
}
However, I'm looking for a way to programmatically/automatically capture values for VPCID, PrivateSubnet1, PrivateSubnet2, PublicSubnet1, PublicSubnet2, S3BucketName & DBSubnetGroup based on the values in the output section of the base stack created above.
I don't want to login to my aws cloudformation service console to manually copy and paste these values.
Is there a way to automatically extract that data, maybe some script of some kind?
I could pipe the output of the above command to another program and parse the data if that data was in the output but all I get in the output is the stackid.
How do I get the VPCID, PrivateSubnet1, PrivateSubnet2, PublicSubnet1, PublicSubnet2, S3BucketName & DBSubnetGroup based on the values in the output section of the base stack created above?
You can use the aws cloudformation wait command to wait for your stack to finish before checking the output values. For example:
aws cloudformation create-stack \
--stack-name my-stackname \
--template-body file://stack.yml \
--parameters file://stack-params.json
aws cloudformation wait stack-create-complete \
--stack-name my-stackname
aws cloudformation describe-stacks \
--stack-name my-stackname \
--query "Stacks[0].Outputs"
If you want to get the stack outputs one by one, you can use a query such as:
aws cloudformation describe-stacks \
--stack-name my-stackname \
--query "Stacks[0].Outputs[?OutputKey=='VPCID'].OutputValue" \
--output text
Note that for wait, you need to use stack-update-complete if you are doing an update rather than a create.

get cloudformation parameters from .txt file/s3 bucket

I want to pass input parameter to cloudformation properties from text file or save the text file in s3 bucket and point the s3 URL in CF properties.
Please let me know if this is possible? If yes, how to do?
There isn't a way if you're using the AWS management console to create the CloudFormation stack, but you can if you use the AWS CLI. Save the parameters into a text file (e.g. parameters.txt) in one of the following formats:
Shorthand:
ParameterKey=string,ParameterValue=string,UsePreviousValue=boolean ...
JSON:
[
{
"ParameterKey": "string",
"ParameterValue": "string",
"UsePreviousValue": true|false
}
...
]
Then use the AWS CLI command cloudformation create-stack, e.g.:
aws cloudformation create-stack --stack-name <YourStackName> \
--template-body file://<YourTemplateFileName.ext> \
--parameters file://parameters.txt
Unfortunately it doesn't seem --parameters can reference an S3 bucket directly, only a local file or inline parameters.
See this blog parameter you pass using s3 url:
https://aws.amazon.com/blogs/devops/passing-parameters-to-cloudformation-stacks-with-the-aws-cli-and-powershell/
also try this:
aws cloudformation create-stack --stack-name <YourStackName> \
--template-body file://<YourTemplateFileName.ext> \
--parameters $(aws s3 cp S3:/yourbucketname\parameters.txt - )