CloudFormation is a service for managing AWS resources. You can create a Template that includes all the resources used (VPC, EC2, RDS, etc.). Template supports parameterization and can create resources based on conditions to adapt to different environments. Another important concept of CloudFormation is Stack. Each Stack contains a Template, which can set the parameter values defined in the Template, add Stack-level tags, set permissions, etc., and truly create resources through the Stack.
With CloudFormation, it is no longer necessary to create and configure AWS resources separately, relieve the tedious manual installation and configuration work, and manage the code version, which is conducive to future update and maintenance, and no need to write installation manuals.
Template
CloudFormation Template supports two formats: JSON and YAML, you can save template files with any extension, such as: .json, .yaml, .template, .txt. The YAML syntax is simpler and easier to read and supports comments, but CloudFormation Designer currently only supports JSON.
{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "A sample template", "Resources" : { "MyEC2Instance" : { "Type" : "AWS::EC2::Instance", "Properties" : { "ImageId" : "ami-2f726546", "InstanceType" : "t1.micro", "KeyName" : "testkey", "BlockDeviceMappings" : [ { "DeviceName" : "/dev/sdm", "Ebs" : { "VolumeType" : "io1", "Iops" : "200", "DeleteOnTermination" : "false", "VolumeSize" : "20" } } ] } } } }
AWSTemplateFormatVersion: "2010-09-09" Description: A sample template Resources: MyEC2Instance: Type: "AWS::EC2::Instance" Properties: ImageId: "ami-2f726546" InstanceType: t1.micro KeyName: testkey BlockDeviceMappings: - DeviceName: /dev/sdm Ebs: VolumeType: io1 Iops: 200 DeleteOnTermination: false VolumeSize: 20
For basic knowledge of templates, please refer to:
In addition to String, Number, List<Number>, CommaDelimitedList, the parameter types of Learn Template Basics Parameters also support specific types, such as AWS::EC2::KeyPair::KeyName, AWS::EC2::AvailabilityZone::Name, AWS: :EC2::SecurityGroup::GroupName, etc., the user must specify an existing AWS value in their account.
When creating a Stack through the CloudFormation Console, the parameters are sorted alphabetically by default. If there are too many parameters, it will look messy and difficult to find. This requires the help of Metadata. AWS::CloudFormation::Interface is used to define parameters in the CloudFormation console. grouping and sorting by:
"Metadata" : { "AWS::CloudFormation::Interface" : { "ParameterGroups" : [ { "Label" : { "default" : "Network Configuration" }, "Parameters" : [ "VPCID", "SubnetId", "SecurityGroupID" ] }, { "Label" : { "default":"Amazon EC2 Configuration" }, "Parameters" : [ "InstanceType", "KeyName" ] } ] } }The following code demonstrates the use of cfn-init and shell in CloudFormation. The AMI uses RHEL 7, which includes installing cfn-init, awscli, awslogs, configuring DNS, awscli, awslog, etc.
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "InstanceTest": { "Type": "AWS::EC2::Instance", "Metadata": { "AWS::CloudFormation::Init": { "configSets": { "Install": [ "Install" ] }, "Install": { "packages": { "yum": { "ntp": [], "nfs-utils": [], "rpcbind": [] } }, "files": { "/etc/sysconfig/network-scripts/ifcfg-eth0": { "content": { "Fn::Join": ["", [ "DEVICE=\"eth0\"\n", "BOOTPROTO=\"dhcp\"\n", "ONBOOT=\"yes\"\n", "TYPE=\"Ethernet\"\n", "USERCTL=\"yes\"\n", "PEERDNS=\"no\"\n", "IPV6INIT=\"no\"\n", "DNS1=\"10.184.13.14\"" ]]}, "owner": "root", "group": "root" }, "/root/.aws/config": { "content": { "Fn::Join": ["", [ "[default]\n", "output = json\n", "region = cn-north-1" ]]}, "mode": "000600", "owner": "root", "group": "root" }, "/root/.aws/credentials": { "content": { "Fn::Join": ["", [ "[default]\n", "aws_access_key_id = AKIAPM6UDU6DGZPYXXXX\n", "aws_secret_access_key = CrYrR/LeiDXJWbAX3KQwFnaScDU0zGE+XXXXXXXX" ]]}, "mode": "000600", "owner": "root", "group": "root" }, "/root/.aws/awslogs.conf": { "content": { "Fn::Join": ["", [ "[general]\n", "state_file = /var/awslogs/state/agent-state\n", "[/var/log/messages]\n", "datetime_format = %Y-%m-%d %H:%M:%S\n", "file = /var/log/messages\n", "buffer_duration = 5000\n", "log_stream_name = server-log\n", "initial_position = start_of_file\n", "log_group_name = /var/log/messages" ]]}, "mode": "000600", "owner": "root", "group": "root" } }, "commands": { "1-timezone": { "command": "timedatectl set-timezone UTC", "ignoreErrors": "true" }, "2-groups": { "command": "groupadd -g 1001 monet", "ignoreErrors": "true" }, "3-users": { "command": "useradd -d /monet -g monet -u 1001 monetmanager\nchmod 755 /monet ", "ignoreErrors": "true" } }, "services": { "sysvinit": { "ntpd": { "enabled" : "true", "ensureRunning" : "true" }, "rpcbind": { "enabled" : "true", "ensureRunning" : "true" }, "nfslock": { "enabled" : "true", "ensureRunning" : "true" } } } } } }, "Properties": { "AvailabilityZone": "cn-north-1a", "DisableApiTermination": "false", "EbsOptimized": "false", "ImageId": "ami-3ce23651", "InstanceInitiatedShutdownBehavior": "stop", "InstanceType": "t2.small", "KeyName": "Prod Key Pair", "Monitoring": "false", "PrivateIpAddress": "10.184.12.247", "SecurityGroupIds": [ { "Fn::ImportValue": "prod-network-sg-private-id" } ], "SubnetId": { "Fn::ImportValue": "prod-network-subnet-private-id" }, "BlockDeviceMappings": [ { "DeviceName": "/dev/sda1", "Ebs": { "VolumeSize": "30" } } ], "Tags": [ { "Key": "Name", "Value": "test-ec2" } ], "UserData": { "Fn::Base64": { "Fn::Join" : ["", [ "#!/bin/bash\n", "# Install cfn-init\n", "curl -O https://bootstrap.pypa.io/ez_setup.py\n", "python ez_setup.py\n", "easy_install --script-dir /opt/aws/bin https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n", "# Install the files and packages from the metadata\n", "/opt/aws/bin/cfn-init -v ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource InstanceTest ", " --configsets Install ", " --region ", { "Ref" : "AWS::Region" }, "\n", "# Install awscli\n", "curl -O https://bootstrap.pypa.io/get-pip.py\n", "python get-pip.py\n", "pip install awscli\n", "# Install awslogs\n", "curl -O https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py\n", "python ./awslogs-agent-setup.py --region cn-north-1 --non-interactive --configfile=/root/.aws/awslogs.conf\n", "# Delete installation files\n", "rm -f get-pip.py ez_setup.py setuptools*.zip awslogs-agent-setup.py\n" ] ] } } } } } }The following demonstrates installing DNS via powershell on Windows 2016:
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "InstanceDNS": { "Type": "AWS::EC2::Instance", "Properties": { "AvailabilityZone": "cn-north-1a", "DisableApiTermination": "false", "EbsOptimized": "false", "ImageId": "ami-2797404a", "InstanceInitiatedShutdownBehavior": "stop", "InstanceType": "t2.small", "KeyName": "Prod Key Pair", "Monitoring": "false", "PrivateIpAddress": "10.184.13.15", "SecurityGroupIds": [ "sg-b0525cd5" ], "SubnetId": "subnet-a65208c3", "BlockDeviceMappings": [ { "DeviceName": "/dev/sda1", "Ebs": { "VolumeSize": "30" } } ], "UserData": { "Fn::Base64" : { "Fn::Join" : ["", [ "<powershell>\n", "Install-WindowsFeature -Name DNS -IncludeManagementTools\n", "Add-DnsServerPrimaryZone -Name \"iata.org\" -ZoneFile \"iata.org.dns\"\n", "Add-DnsServerResourceRecordA -Name \"test\" -ZoneName \"iata.org\" -AllowUpdateAny -IPv4Address \"10.184.12.111\"\n", "</powershell>" ]]}}, "Tags": [ { "Key": "Name", "Value": "test-dns" } ] } } } }
CloudFormation Designer
AWS CloudFormation Console provides a graphical Template designer, supports drag-and-drop operations, integrates a JSON editor, and supports auto-completion.
Using the drag-and-drop function of CloudFormation Designer or using it to open an existing Template will add component location information, which is unnecessary in practical applications and increases the complexity of the Template, so I only use its auto-complete function. , when you want to edit an existing Template, use the Copy/Paste method.
hot key
【Ctrl+Shift+Space】 Display the prompt list
【Ctrl+F】 Search
【Ctrl+\】 Format Template (all blank lines will be deleted)
【Ctrl+Shift+\】 Delete all spaces
Sample Templates
CloudFormer
CloudFormer is a template creation tool that can create CloudFormation Templates from existing AWS resources, which can be used as initial Templates. It is a good tool for learning the syntax structure of Templates.
CloudFormer is very simple to use. It is a CloudFormation Stack that can be created from the CloudFormation Console and run on an EC2 instance without additional resources.
Create CloudFormer
Log in to CloudFormation Console > Create New Stack > Select a sample template > CloudFormer > Next > Enter Stack name, Username, Password > Follow the prompts to complete the next steps
Start CloudFormer
Click the link in the Outputs of the CloudFormer Stack tab, enter the username and password to start CloudFormer. Then Select the AWS Region > Create Template > Step by step to select the resource to create the template.
Note: If there is an error NoMethodError in TemplatesController, there may be a problem with resource configuration, try to reduce some resources.
Best Practices
- Organize stacks by life cycle and ownership, instead of putting all resources in one Stack, to avoid mutual influence when resources change. Additionally, resources can be partitioned according to hierarchy and service orientation (SOA).
- Use cross-stack references to export shared resources, and other stacks use the Fn::ImportValue function to call the exported resources. Reference resource output in another AWS CloudFormation stack
- Reuse templates to replicate stacks in multiple environments, to make templates reusable, use parameters, mappings, and conditional sections so that stacks can be customized when they are created.
- Use nested stacks to reuse common templates. To create nested stacks, use the AWS::CloudFormation::Stack resource in the template to reference other templates.
AWS CloudFormation CLI
Creating a Stack
You must provide the stack name, the location of a valid template, and any input parameters. If you specify a local template file, AWS CloudFormation uploads it to an Amazon S3 bucket in your AWS account.
$ aws cloudformation create-stack --stack-name myteststack --template-body file:///home/testuser/mytemplate.json --parameters ParameterKey=Parm1,ParameterValue=test1 ParameterKey=Parm2,ParameterValue=test2
Listing Your Stacks
Note The aws cloudformation list-stacks command returns information on deleted stacks for 90 days after they have been deleted.
$ aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE
Describing Your Stacks
$ aws cloudformation describe-stacks --stack-name myteststack
By default, aws cloudformation describe-stacks returns parameter values. To prevent sensitive parameter values such as passwords from being returned, include a NoEcho property set to TRUE in your AWS CloudFormation template.
Viewing Stack Event History
You can track the status of the resources AWS CloudFormation is creating and deleting with the aws cloudformation describe-stack-events command. The amount of time to create or delete a stack depends on the complexity of your stack.
$ aws cloudformation describe-stack-events --stack-name myteststack
Listing Stack Resources
$ aws cloudformation list-stack-resources --stack-name myteststack
Retrieving a Template
AWS CloudFormation stores the template you use to create your stack as part of the stack.
$ aws cloudformation get-template --stack-name myteststack
Validating a Template
You can validate templates locally by using the --template-body parameter, or remotely with the --template-url parameter.
$ aws cloudformation validate-template --template-url https://s3.amazonaws.com/cloudformation-templates-us-east-1/S3_Bucket.template
$ aws cloudformation validate-template --template-body file:///home/local/test/sampletemplate.json
Deleting a Stack
$ aws cloudformation delete-stack --stack-name myteststack
Getting Started with AWS CloudFormation
Learn Template BasicsUsing CloudFormer to Create AWS CloudFormation Templates from Existing AWS Resources
Using the AWS Command Line Interface
AWS CloudFormation Best Practices
Install roles, role services, and features by using Windows PowerShell cmdlets
Domain Name System (DNS) Server Cmdlets
CloudFormation provides a large number of sample templates for learning, among which there are few examples in the China Region, and the US West (Northern California) Region is recommended. For example, the following example in Services fully demonstrates from creating a VPC to EC2.