This does not replace the running resources. Example, adding AccessControl(permissions) will simply change the permission settings on the same resource
Replacement updates, such as updating the name of the bucket.
NOTE: This will cause data loss.
- Tags // all the resources will share the stack's tags
- Permissions // provide role to the stack to create resources
- Notification Options // emails for general notifications
- Timeouts // fails after specific amount of time
- Rollback on Failure // rollback to previous state on failure
- Stack Policy // can be set to resources templates to avoid deletion
Parameters are a way to provide inputs to your AWS Cloudformation templates.
Parameters can be declared separately which helps the templates become more dynamic and reusable becuse they can be changed as per the requirements of the different applications
- Type: String/ Number/ CommaDelimitedList/ List/ AWS Parameter(AWS Custom Type)
- Description
- Contraints
- ContraintDescription
- Min/MaxLength
- Min/MaxValues
- Defaults
- AllowedValues(array)
- AllowedPattern(regex)
- NoEcho(Boolean) // if set true, the output will not be printed out (used for passwords)
Mappings is a section of cloudformation to help you organize parameters by named keys and its corresponding values for each group.
This is similar to parameters, but here the values are predefined and others who will be creating templates can use these predefined values. It'se similar to setting the environment variables to not hardcode the values everytime (to avoid errors).
In the below example, we are specifying valid ami's to be used by our team members depending on which region they're in:
Mappings:
# name of mapping
RegionMap:
us-east-1:
"32": "ami-6411e20d"
"64": "ami-7a11e213"
us-east-2:
"32": "ami-c9c7978c"
"64": "ami-cfc7978a"
These values can be reffered using !FindInMap function:
!FindInMap [ MapName, TopLevelKey, SecondLevelKey ]
Now the resources such as an EC2 instance can use one of those values:
# assuming instance needs to be in us-east1
# assuming instance needs to be of 64 bit
Resources:
MyEC2Instance:
Type: "AWS::EC2::Instance"
Properties:
ImageId: !FindInMap [ RegionMap, us-east1, 32 ]
Resources:
MyEC2Instance:
Type: "AWS::EC2::Instance"
Properties:
ImageId: !FindInMap [ RegionMap, !Ref "AWS::Region", 32 ]
This is what is called a Pseudo Parameter. These are provided by AWS an be dynamically used inside any of your template. Some of the common examples are:
- AWS::AccountId
- AWS::NoValue
- AWS::Region
- AWS::StackId
- AWS::StackName
The optional outputs
section declares output values that you can import into other stacks.
In simple words, suppose you want to use one stack's rendered output in some other stack. You can do it by using outputs.
Suppose you define a network Cloudformation and output the values such as VPC ID of the created network. You can use that network via this output in the other templates by using references.
Outputs:
Logical ID:
Description: Information about the value
Value: Value to return
Export:
Name: Value to export
# Logical ID : An identifier for the current output. Must be unique withtin template.
# Value :
## suppose a networking guy configures this
Resources:
MyCustomSSHSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: tcp
FromPort: 22
ToPort: 22
# export this for other stacks to be created
Outputs:
StackSSHSecurityGroup:
Value: !Ref MyCustomSSHSecurityGroup
Export:
# this can be reffered by other stacks
Name: SSHSecurityGroupOutput
Now this can be used by other stack using
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: us-east-2a
ImageId: ami-0a54aef4ef3b5f881
InstanceType: t2.micro
SecurityGroups:
# imported here
- !ImportValue SSHSecurityGroupOutput
As the name suggests conditions are used to control the creation of the resources based on some parameters.
The common use cases of using the conditions are:
- Environment(dev/test/prod)
- AWS Region
- Any parameter value
Conditions:
# name of your condition (can be any)
Logical ID:
Intrinsic function
- Fn::And
- Fn::Equals
- Fn::If
- Fn::Not
- Fn::Or
Suppose you want the resources(EC2) to be self configured so that they can perform the jobs they are supposed to perform. In simple words, you want them to be preconfigured. This can be achieved from Clouformation Init
This is a way to write a startup script or bootstrapping an instance with user custom scripts
. We can either pass in this script while manually provisioning this server or we can use this script inside our EC2 instance cloudformation template using the function:
Fn::Base64
We can use this function and write a script like:
Resources:
MyInstance:
Properties:
ImageId: ami-a4c7edb2
InstanceType: t2.micro
UserData:
Fn::Base64: |
#!/bin/bash
yum install something
echo "and so on..."
- What if we want to have a very large startup template?
- What if we wat to evolve the state of the EC2 instance without terminating it or creating a new one?
- How do we separate the user data from the cloudformation template?
- How do we check the logs to see if the script ran successfully or not?
All these can be solved using Cloudformation INIT instead of user-data
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html
It has following sections:
- You can install packages from the following repos:
rpm, yum/apt, rubygems, python, msi
. - Packages are are processed in the same order.
- You can specify any version [2.0] or the no version [] === latest.
packages:
rpm:
epel: "http://somelinktodownloadarepo.com"
yum:
httpd: []
docker: [3.1]
wordpress: []
python:
django: []
It is used by defining AWS::CloudFormation::Init
inside the resources template.
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
Metadata:
Comment: Install a simple php application
AWS::CloudFormation::Init:
config:
packages:
yum:
httpd: []
php: []
- If you want to have multiple users and groups in your EC2 instance.
groups:
# will have any gid
groupOne: {}
groupTwo:
gid: "45"
users:
myUser:
groups:
- groupOne
- groupTwo
uid: 50
homeDir: "/tmp"
- We can download whole compressed archives from the web and unpack them on the instance directly.
- It's very handy if you have a set of standardized scripts for your instances that you store in s3 for example.
- Or you could simply download the whole github project on your instance.
sources:
/etc/puppet: "https://github.com/user1/cfn-demo/tarball/master"
/etc/myapp: "https://s3.aws.com/bucket/myfile.tar.gz"
You can use files to create files in the ec2 instance, modify it's content and even change it's permissions.
files:
/tmp/setup.mysql:
content: !Sub |
CREATE DATABASE ${DBName};
CREATE USER '${DBUsername}'@'localhost' IDENTIFIED BY '${DBPassword}';
GRANT ALL ON ${DBName}.* TO '${DBUsername}'@'localhost';
FLUSH PRIVILEGES;
mode: "000644"
owner: "root"
group: "root"
You can use the commands key to execute commands on the EC2 instance. The commands are processed in alphabetical order by name.
commands:
test:
command: "echo \"$MAGIC\" > test.txt"
env:
MAGIC: "I come from the environment!"
cwd: "~"
test: "test ! -e ~/test.txt"
ignoreErrors: "false"
test2:
command: "echo \"$MAGIC2\" > test2.txt"
env:
MAGIC2: "I come from the environment!"
cwd: "~"
test: "test ! -e ~/test2.txt"
ignoreErrors: "false"
- You can use this to launch the services at launch.
- To define which services should be enabled or disabled when the instance is launched.
services:
sysvinit:
nginx:
enabled: "true"
ensureRunning: "true"
files:
- "/etc/nginx/nginx.conf"
sources:
- "/var/www/html"
php-fastcgi:
enabled: "true"
ensureRunning: "true"
packages:
yum:
- "php"
- "spawn-fcgi"
sendmail:
enabled: "false"
ensureRunning: "false"