spinning up AWS cloudformation stack in multiple regions - amazon-web-services

I have a cloudformation stack that I have spun in us-east-1 region with auto scaling group and multiple AZ's .
I want to now replicate that same stack in another region to make it a multi region stack and therefore help in disaster recovery.
Can that be done via cloudformation ? Also to make AWS CLI call to do clouformation create stack do I need to be in the same region to effect the call?

CloudFormation is a region level service, so all resources created by a single stack exist in one region only. You can reuse the same template to create identical stacks in additional regions if you wish.
Using the AWS CLI, you can specify which region you want to interact with either in your ~/.aws/config file (e.g. type aws configure to setup this file), or in the environment variable AWS_DEFAULT_REGION, or by passing the --region option on the command line.
Exmaple:
aws cloudformation create-stack \
--region us-east-1 \
--stack-name MyStackName \
--template-body file://MyTemplate.yaml

Related

Difference between --parameter-overrides and --tags

I am having a hard time understanding the difference between --parameter-overrides and --tags when deploying an AWS stack using CloudFormation.
I tried to read through the documentation but I still do not understand, I seem to get exactly the same behaviour when I use the cli to deploy my stack with the usage of one or the other flag, such as
aws --profile $PROFILE cloudformation deploy
--stack-name ${STACK_NAME}
--template-file $TEMPLATE_FILE
--parameter-overrides
ApplicationName=$APP_NAME
--no-fail-on-empty-changeset
--tags
ApplicationName=$APP_NAME
When and why would I use the tags? Any help?
--tags set arbitrary Tags on the Stack. Tags are key-value metadata for labelling and categorizing AWS resources. Tags are optional. They do not affect how CloudFormation deploys the stack.
--parameter-overrides inject parameter values into the template. Optional if you are happy with the template's parameter defaults (for new deploys) or currently deployed values (for updates).

how to pass a service role to my stack when using CDK?

When using CloudFormation to deploy AWS resources you can assign a service role to the stack
aws cloudformation create-stack \
--stack-name ${STACK_NAME} \
--template-body file://stack.yaml \
--role-arn ${SERVICE_ROLE_ARN}
How can you do the same thing when using CDK? I see that the StackProps construct does not have a role-arn attribute.
-r, --role-arn ARN of Role to use when invoking CloudFormation
as found here: https://docs.aws.amazon.com/cdk/latest/guide/cli.html
however. Ermiya is correct in the comments to your answer, that anything beyond a deployment time role for deployment requires the language you are using - Its slightly, but importantly different in each one. Plus, there are many other factors in CDK deployment that are not part of the CloudFormation Create Stack options, such as AWS Environment (region and account number) and more.

cloudformation ecs force new deployement

What is the equivalent of --force-new-deployment flag in cloudformation ?
(aws ecs update-service --cluster --service --force-new-deployment)
In my cloudformation template, my docker image tag is latest. However I want to be able to force the redeployment if I replay the stack.
Thanks you
Think of CloudFormation as just a provisioning service or an orchestrator.
Specifying an Image as repository-url/image:tag will definitely fetch the specified image with specific tag from your repo but only upon a stack operation. Once a stack operation is finished, any changes to service will be depending on the next stack operation.
What you can do here is either having either
Cloudwatch Event based rule targeting a Lambda Function whenever there is an image upload to ECR.
Or in case of using some other repo than ECR, have a hook configured in a way that will invoke update-service --cluster --service --force-new-deployment ... command whenever there is a new image upload.
Considerations:
This can lead your stack being in DRIFTED status.
Just make sure to keep your stack's Image property's value in sync with the latest one running within service, whenever you plan to update the stack.
Here's something I came up with to force a deploy after a stack update if needed. The service name is the same as the stack name, so if yours is different you will need to adjust accordingly.
START_TIME=`date +%s`
aws cloudformation deploy --stack-name $STACK_NAME [other options]
LAST_DEPLOY=`aws ecs describe-services --services $STACK_NAME --query "services[0].deployments[?status=='PRIMARY'].createdAt" --output text`
if [ "$START_TIME" -gt "${LAST_DEPLOY%.*}" ]; then aws ecs update-service --service $STACK_NAME --force-new-deployment; fi
The best I have been able to come up with is to change my healthcheck from curl -f to curl --fail and back to force a new deployment. Not ideal but it works.
I'd be interested in a better way, ideally built in to CloudFormation too.

Cloudformation append to stack

I have an AWS stack with lambda and api gateway resources. There are about 250 resources and cloudformation only allows uploading 200 at a time so I split it into 2 templates. However when I run the deploy commands for each stack like so
aws cloudformation deploy --template-file template.yml --stack-name my-stack --region us-east-1 --capabilities CAPABILITY_IAM
aws cloudformation deploy --template-file template2.yml --stack-name my-stack --region us-east-1 --capabilities CAPABILITY_IAM
the second command deletes what the first command deployed to my-stack. I would like to append the resources in template2.yml to my-stack and keep what was deployed from template.yml. Is there a way to do that? I want the resources in both templates to use the same api gateway endpoint.
They are technically 2 stacks, but you only gave 1 stack name. So the later command will overwrite the deployed my-stack based on template.yml.
Change your 2nd command to use a different stack name like my-stack2
You could deploy this specifications into two different stacks (diferent stack names), besides you could reference the api gateway specification from the first stack into the second stack, this is one way to reference lambda functions in same api gateway.

CloudFormation LaunchConfiguration SSM Association

I see that it's now possible to create EC2 instances bootstrapped with SSM association(s):
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-document.html
But I don't see analogous properties exposed on Launch Configurations...
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-launchconfig.html
Is this just not possible yet or is there a way of getting SSM associations added automatically to EC2 instances launched via a Launch Configuration?
One solution would be to just call the CreateAssociation API directly when each instance is booted. You could use a Auto Scaling Event to invoke a Lambda function, or (probably easier) add a shell-script line into your Launch Configuration's UserData that invokes the API through the AWS CLI (aws ssm create-association), retrieving the currently-running instance ID through instance metadata:
aws ssm create-association \
--name mySSMDocumentName \
--instance-id $(curl http://169.254.169.254/latest/meta-data/instance-id)
You'll need to provide the Launch Configuration an IAM instance profile with "ssm:CreateAssociation" permissions and also provide the AWS CLI with the current region (either exported to the AWS_DEFAULT_REGION environment variable, or with an explicit --region parameter.)