AWS March 2016 Webinar Series - AWS IoT Real Time Stream Processing with AWS Lambda
AWS Infrastructure as Code - September 2016 Webinar Series
-
Upload
amazon-web-services -
Category
Technology
-
view
2.760 -
download
1
Transcript of AWS Infrastructure as Code - September 2016 Webinar Series
![Page 1: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/1.jpg)
© 2016, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Chris Munns
Business Development Manager – DevOps
Amazon Web Services
September 2016
Infrastructure as Code: Best
Practices with AWS CloudFormation
![Page 2: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/2.jpg)
![Page 3: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/3.jpg)
![Page 4: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/4.jpg)
CloudFormation concepts and technology
JSON/YAML formatted file
Parameter definition
Resource creation
Configuration actions
Framework
Stack creation
Stack updates
Error detection and rollback
Configured AWS resources
Comprehensive service support
Service event aware
Customizable
Template CloudFormation Stack
![Page 5: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/5.jpg)
Infrastructure as Code workflow
codeversion control
code review
integrate deploy
![Page 6: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/6.jpg)
Infrastructure as Code workflow
codeversion control
code review
integrate deploy
Text EditorGit/SVN/
Perforce
Review Tools
Syntax Validation
Tools
AWS Services
![Page 7: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/7.jpg)
Infrastructure as Code workflow
codeversion control
code review
integrate deploy
“It’s all software”
Text EditorGit/SVN/
Perforce
Review Tools
Syntax Validation
Tools
AWS Services
![Page 8: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/8.jpg)
In-place Blue-Green
Traffic
• Quicker and more cost efficient
• Updates or replaces resources
• Simpler state and data
migration
• Working stack stays intact for
easy roll backs
• Potentially need to sync data
• Shift traffic to new stack
Templates
Stacks
Update like software
Traffic
![Page 9: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/9.jpg)
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "AWS CloudFormation Sample Template EC2InstanceSample: **WARNING** This template an Amazon EC2 instances. You will be billed for the AWS resources used if
you create a stack from this template.",
"Parameters" : {
"KeyName" : {
"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instance",
"Type" : "String"
},
"Environment": {
"Type" : "String",
"Default" : ”Dev",
"AllowedValues" : [”Mgmt", "Dev", ”Staging", "Prod"],
"Description" : "Environment that the instances will run in.”
}
},
"Mappings" : {
"RegionMap" : {
"us-east-1" : { "AMI" : "ami-7f418316" },
"us-west-2" : { "AMI" : "ami-16fd7026" }
}
},
"Conditions" : {
”EnableEBSOptimized" : {"Fn::Equals" : [{"Ref" : " Environment "}, ”Prod"]},
},
"Resources" : {
"Ec2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"KeyName" : { "Ref" : "KeyName" },
"EbsOptimized " : {"Fn::If": [ " EnableEBSOptimized ", {“true”}, {“false”}]},
"ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "AMI" ]},
"UserData" : { "Fn::Base64" : "80" }
}
}
},
"Outputs" : {
"InstanceId" : {
"Description" : "InstanceId of the newly created EC2 instance",
"Value" : { "Ref" : "Ec2Instance" }
},
"PublicDNS" : {
"Description" : "Public DNSName of the newly created EC2 instance",
"Value" : { "Fn::GetAtt" : [ "Ec2Instance", "PublicDnsName" ] }
}
}
}
![Page 10: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/10.jpg)
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "AWS CloudFormation Sample Template EC2InstanceSample: **WARNING** This template an Amazon EC2 instances. You will be billed for the AWS resources used if
you create a stack from this template.",
"Parameters" : {
"KeyName" : {
"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instance",
"Type" : "String"
},
"Environment": {
"Type" : "String",
"Default" : ”Dev",
"AllowedValues" : [”Mgmt", "Dev", ”Staging", "Prod"],
"Description" : "Environment that the instances will run in.”
}
},
"Mappings" : {
"RegionMap" : {
"us-east-1" : { "AMI" : "ami-7f418316" },
"us-west-2" : { "AMI" : "ami-16fd7026" }
}
},
"Conditions" : {
”EnableEBSOptimized" : {"Fn::Equals" : [{"Ref" : " Environment "}, ”Prod"]},
},
"Resources" : {
"Ec2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"KeyName" : { "Ref" : "KeyName" },
"EbsOptimized " : {"Fn::If": [ " EnableEBSOptimized ", {“true”}, {“false”}]},
"ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "AMI" ]},
"UserData" : { "Fn::Base64" : "80" }
}
}
},
"Outputs" : {
"InstanceId" : {
"Description" : "InstanceId of the newly created EC2 instance",
"Value" : { "Ref" : "Ec2Instance" }
},
"PublicDNS" : {
"Description" : "Public DNSName of the newly created EC2 instance",
"Value" : { "Fn::GetAtt" : [ "Ec2Instance", "PublicDnsName" ] }
}
}
}
HEADERS
PARAMETERS
MAPPINGS
RESOURCES
OUTPUTS
CONDITIONALS
![Page 11: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/11.jpg)
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "AWS CloudFormation Sample Template EC2InstanceSample: **WARNING** This template an Amazon EC2 instances. You will be billed for the AWS resources used if
you create a stack from this template.",
"Parameters" : {
"KeyName" : {
"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instance",
"Type" : "String"
},
"Environment": {
"Type" : "String",
"Default" : ”Dev",
"AllowedValues" : [”Mgmt", "Dev", ”Staging", "Prod"],
"Description" : "Environment that the instances will run in.”
}
},
"Mappings" : {
"RegionMap" : {
"us-east-1" : { "AMI" : "ami-7f418316" },
"us-west-2" : { "AMI" : "ami-16fd7026" }
}
},
"Conditions" : {
”EnableEBSOptimized" : {"Fn::Equals" : [{"Ref" : " Environment "}, ”Prod"]},
},
"Resources" : {
"Ec2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"KeyName" : { "Ref" : "KeyName" },
"EbsOptimized " : {"Fn::If": [ " EnableEBSOptimized ", {“true”}, {“false”}]},
"ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "AMI" ]},
"UserData" : { "Fn::Base64" : "80" }
}
}
},
"Outputs" : {
"InstanceId" : {
"Description" : "InstanceId of the newly created EC2 instance",
"Value" : { "Ref" : "Ec2Instance" }
},
"PublicDNS" : {
"Description" : "Public DNSName of the newly created EC2 instance",
"Value" : { "Fn::GetAtt" : [ "Ec2Instance", "PublicDnsName" ] }
}
}
}
HEADERS
PARAMETERS
MAPPINGS
RESOURCES
OUTPUTS
CONDITIONALS
Description of what your stack does, contains, etc
Provision time values that add structured flexibility and
customization
Pre-defined conditional case statements
Conditional values set via evaluations of passed references
AWS resource definitions
Resulting attributes of stack resource creation
![Page 12: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/12.jpg)
{ "Description" : "Create an EC2 instance.”,"Parameters": {
"KeyName": { "Description" : "Name of an existing EC2 KeyPair to enable SSH
access into the WordPress web server", "Type": "AWS::EC2::KeyPair::KeyName"
},"EC2InstanceType" : {
"Description" : "EC2 instance type", "Type" : "String","Default" : "t2.micro", "AllowedValues" : [ "t2.micro", "t2.small", "t2.medium" ], "ConstraintDescription" : "Must be t2.micro, t2.small, t2.medium"
},},
Template Anatomy - Parameters
![Page 13: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/13.jpg)
{ "Description" : "Create an EC2 instance.”,"Resources" : {
"Ec2Instance" : { "Type" : "AWS::EC2::Instance", "Properties" : {
"KeyName" : “my-key-pair”, "ImageId" : "ami-6869aa05”,“InstanceType” : “m3.medium”
} }
}}
Template Anatomy - Resources
![Page 14: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/14.jpg)
"Outputs" : { "WebsiteURL" : {
"Description" : ”DNS name of the website", "Value" : {
"Fn::GetAtt" : [ “LoadBalancer”, “DNSName” ] }
} }
Template Anatomy - Outputs
![Page 15: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/15.jpg)
CloudFormation Best Practices
![Page 16: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/16.jpg)
Visualize template resources
Modify template with drag-drop gestures
Customize sample templates
CloudFormation Designer
![Page 17: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/17.jpg)
Avoid manual resource modifications
Avoid making quick-fixes out of band
Update your stacks with CloudFormation
Do not manually change resources
Consider using resource based permissions to
limit ability to make changes directly
![Page 18: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/18.jpg)
Preview updates with Change Sets
![Page 19: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/19.jpg)
Learn the intrinsic functions
![Page 20: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/20.jpg)
"Mappings" : {"RegionMap" : {
"us-east-1" : { "32" : "ami-6411e20d", "64" : "ami-7a11e213" },"us-west-1" : { "32" : "ami-c9c7978c", "64" : "ami-cfc7978a" },"eu-west-1" : { "32" : "ami-37c2f643", "64" : "ami-31c2f645" },"ap-southeast-1" : { "32" : "ami-66f28c34", "64" : "ami-60f28c32" },"ap-northeast-1" : { "32" : "ami-9c03a89d", "64" : "ami-a003a8a1" }
}},
Fn::FindInMap
![Page 21: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/21.jpg)
Fn::FindInMap
"Resources" : {"myEC2Instance" : {
"Type" : "AWS::EC2::Instance","Properties" : {
"ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "32"]},
"InstanceType" : "m1.small"}
}}
![Page 22: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/22.jpg)
"Resources" : {
"Ec2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"KeyName" : { "Ref" : "KeyName" },
"SecurityGroups" : [ { "Ref" : "InstanceSecurityGroup" } ],
"ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "AMI" ]},
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["",[
"#!/bin/bash -ex","\n",
"yum -y install gcc-c++ make","\n",
"yum -y install mysql-devel sqlite-devel","\n",
"yum -y install ruby-rdoc rubygems ruby-mysql ruby-devel","\n",
"gem install --no-ri --no-rdoc rails","\n",
"gem install --no-ri --no-rdoc mysql","\n",
"gem install --no-ri --no-rdoc sqlite3","\n",
"rails new myapp","\n",
"cd myapp","\n",
"rails server -d","\n"]]}}
}
}
Use EC2 UserData, which is available as a property of AWS::EC2::Instance resources
Bootstrap your applications using EC2 UserData
![Page 23: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/23.jpg)
AWS CloudFormation provides helper scripts
for deployment within your EC2 instances
Metadata Key —AWS::CloudFormation::Init
Cfn-init reads this metadata key and installs
the packages listed in this key (e.g., httpd,
mysql, and php). Cfn-init also retrieves and
expands files listed as sources.
Amazon EC2
AWS CloudFormation
cfn-init
cfn-hup
cfn-signal
cfn-get-
metadata
Bootstrap your applications using helper scripts
![Page 24: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/24.jpg)
"Metadata": {
"AWS::CloudFormation::Init" : {
"config" : {
"packages" : {
},
"sources" : {
},
"commands" : {
},
"files" : {
},
"services" : {
},
"users" : {
},
"groups" : {
}
}
}
“WebAppHost" : {
"Type" : "AWS::EC2::Instance",
"Metadata" : {
"AWS:CloudFormation::Init" : {
"config" : {
"packages" : {
"yum" : {
"gcc" : [],
"gcc-c++" : [],
"make" : [],
"automake" : [],
Use AWS::CloudFormation::Init with cfn-init to help bootstrap instances:
Bootstrapping example
![Page 25: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/25.jpg)
{
"Statement" : [
{
"Effect" : "Allow",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "*"
},
{
"Effect" : "Deny",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "LogicalResourceId/ProductionDatabase"
}
]
}
Prevent stack updates to protected resources using Stack policies
Protect your resources using Stack policies
![Page 26: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/26.jpg)
Ownership based template design
Limit one template to a single service
Aim for reusability across environments (development, testing, production)
Use nested stacks and cross-stack reference to break up large templates
Organize templates according to team structure/job function/line of business
![Page 27: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/27.jpg)
Ownership based template design
![Page 28: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/28.jpg)
Template File
Defining Stack
The entire infrastructure can be represented in an AWS
CloudFormation template.
Many Stacks & Environments from One Template
![Page 29: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/29.jpg)
Template File
Defining Stack
The entire infrastructure can be represented in an AWS
CloudFormation template.
Use the version control system of your choice to store and track changes to this template
Many Stacks & Environments from One Template
Git
Perforce
SVN
…
![Page 30: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/30.jpg)
Template File
Defining Stack
Git
Perforce
SVN
…
Dev
Test
Prod
The entire infrastructure can be represented in an AWS
CloudFormation template.
Use the version control system of your choice to store and track changes to this template
Build out multiple environments, such as for Development, Test, Production and even DR using the same template
Many Stacks & Environments from One Template
![Page 31: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/31.jpg)
Ownership based template design
![Page 32: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/32.jpg)
Ownership – nested stacks
![Page 33: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/33.jpg)
Web-SG
Ownership – cross-stack references
App-SG
App-SG
DB-SG
![Page 34: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/34.jpg)
Re-usable Templates – across AWS Regions
Consider environmental or regional differences
Amazon EC2 image Ids
VPC environment or “classic” environment
Available instance types
IAM policy principals
Endpoint names
Amazon Resource Names (arns)
![Page 35: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/35.jpg)
"LogsBucketPolicy": {"Type": "AWS::S3::BucketPolicy","Properties": {
"Bucket": {"Ref": "LogsBucket”},"PolicyDocument": {
"Version": "2008-10-17","Statement": [{"Sid": "ELBAccessLogs","Effect": "Allow","Resource": {
"Fn::Join": [ "", [ “arn:aws:s3:::", { "Ref": "LogsBucket" }, "/", "Logs",
"/AWSLogs/", { "Ref": "AWS::AccountId" }, "/*” ]]},"Principal": …,"Action": [ "s3:PutObject" ]
}]}
}},
Use “pseudo-parameters” to retrieve environmental data
Account Id
Region
Stack Name and Id
Re-usable Templates – “Pseudo-Parameters”
![Page 36: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/36.jpg)
Re-usable Templates - Using mappings
"LogsBucketPolicy": {"Type": "AWS::S3::BucketPolicy","Properties": {
"Bucket": {"Ref": "LogsBucket”},"PolicyDocument": {"Version": "2008-10-17","Statement": [{
"Sid": "ELBAccessLogs","Effect": "Allow","Resource": {"Fn::Join": [ "", [
{ "Fn::FindInMap" : ["RegionalConfig", {"Ref" : "AWS::Region"},"ArnPrefix”]},
"s3:::”, { "Ref": "LogsBucket" }, "/", "Logs", "/AWSLogs/”,{ "Ref": "AWS::AccountId" }, "/*" ] ]
},}
“Mappings” : {
“RegionalConfig” : {“us-east-1” : {
“AMI” : “ami-12345678”,
”ELBAccountId": "127311923021”,
“ArnPrefix” : “arn:aws:”
},“us-west-1” : {
“AMI” : “ami-98765432”
”ELBAccountId": “027434742980"
“ArnPrefix” :“arn:aws:”
},:
}}
Use mappings to define variables
Single place for configuration
Re-usable within the template
![Page 37: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/37.jpg)
Use conditionals to customize
resources and parameters
"DBEC2SG": {"Type": "AWS::EC2::SecurityGroup","Condition" : "Is-EC2-VPC","Properties" : {…}
},
"DBSG": {"Type": "AWS::RDS::DBSecurityGroup","Condition" : "Is-EC2-Classic","Properties": {…}
},
"MySQLDatabase": {"Type": "AWS::RDS::DBInstance","Properties": {
:
"VPCSecurityGroups": { "Fn::If" : [ "Is-EC2-VPC", [ { "Fn::GetAtt": [ "DBEC2SG", "GroupId" ] } ], { "Ref" : "AWS::NoValue"}]},
"DBSecurityGroups": { "Fn::If" : [ "Is-EC2-Classic", [ { "Ref": "DBSG" } ],{ "Ref" : "AWS::NoValue"}]}
}}
}
"Conditions" : {
"Is-EC2-VPC” : { "Fn::Or" : [ {"Fn::Equals" : [
{"Ref” : "AWS::Region"},"eu-central-1" ]},
{"Fn::Equals" : [{"Ref" : "AWS::Region"}, "cn-north-1" ]}]},
"Is-EC2-Classic" : { "Fn::Not" : [{ "Condition" : "Is-EC2-VPC"}]}
},
Re-usable Templates – Using conditionals
![Page 38: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/38.jpg)
Best Practices Summary
CloudFormation Designer
Avoid manual resource modifications
Preview updates with Change Sets
Learn the intrinsic functions
Bootstrap your applications using UserData and helper scripts
Protect critical resources using stack policies
Ownership based template design
Plan for environment and multi-region
Use Pseudo-Parameters
Use Mappings
Use Conditionals
![Page 39: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/39.jpg)
YAML formatted templates
Overview of template structure / basics
New function formatting (!Ref / !GetAZs / !FindInMap)
New Intrinsic Function ( Fn::Sub )
Cross Stack References
New function Fn::ImportValue
Allows use of outputs from unrelated stacks with custom resource
New
Key new features
New
![Page 40: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/40.jpg)
CloudFormation - YAML
Why YAML?
Better authoring and readability of templates
Native comment support
Simplification as templates get more and more complex
New
![Page 41: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/41.jpg)
Cloudformation - YAML
Resources:
VPC1:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: !Ref VPC1Cidr
Tags:
-
Key: "Name"
Value: "TroubleShooting"
Structure is shown through indentation (one or more spaces).
Sequence items are denoted by a dash
Key value pairs within a map are separated by a colon.
Tips: Use a monospace font, don’t use Tab, save using UTF-8
![Page 42: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/42.jpg)
All sections are the same as in a JSON template
---
AWSTemplateFormatVersion: "version date"
Description:
String
Metadata:
template metadata
Parameters:
set of parameters
Mappings:
set of mappings
Conditions:
set of conditions
Resources:
set of resources
Outputs:
set of outputs
CloudFormation – YAML Template Structure
![Page 43: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/43.jpg)
Two ways to declare Intrinsic functions: Long and Short
Short Form:
!FindInMap [ MapName, TopLevelKey, SecondLevelKey ]
Long Form:
"Fn::FindInMap" : [ "MapName", "TopLevelKey", "SecondLevelKey"]
Tag = ! (Its not Negation operator)
Few things to note with Tags
You cannot use one tag immediately after another
!Base64 !Sub…
Instead, you can do this
"Fn::Base64": !Sub...
!Select [ !Ref Value, [1,2,3]]
CloudFormation – YAML Function Declaration
![Page 44: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/44.jpg)
Fn::Base64 Fn::AndShort !Base64 valueToEncode Short !And [condition]
Long "Fn::Base64": valueToEncode Long "Fn::And": [condition]
Fn::Equals Fn::IfShort !Equals [value_1, value_2] Short !If [condition_name, value_if_true, value_if_false]
Long "Fn::Equals": [value_1, value_2] Long "Fn::If": [condition_name, value_if_true, value_if_false]
Fn::Not Fn::OrShort !Not [condition] Short !Or [condition, ...]
Long "Fn::Not": [condition] Long "Fn::Or": [condition, ...]
CloudFormation – Intrinsic Functions
![Page 45: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/45.jpg)
NewCloudFormation – Fn::Sub
Substitute variables in an input string with values
Function accepts a string or a map as a parameter.
Usage
VarName: ${MyVariableValue}
Literal: ${!LiteralValue}
Use | if you are spanning multiple lines
Available in JSON as well
![Page 46: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/46.jpg)
/tmp/create-wp-config:
content: !Sub |
#!/bin/bash -xe
cp /var/www/html/wordpress/wp-config-sample.php /var/www/html/wordpress/wp-config.php
sed -i "s/'database_name_here'/'${DBName}'/g" wp-config.php
sed -i "s/'username_here'/'${DBUser}'/g" wp-config.php
sed -i "s/'password_here'/'${DBPassword}'/g" wp-config.php
mode: '000500'
owner: root
group: root
configure_wordpress:
commands:
01_set_mysql_root_password:
command: !Sub |
mysqladmin -u root password '${DBRootPassword}'
test: !Sub |
$(mysql ${DBName} -u root --password='${DBRootPassword}' >/dev/null 2>&1 </dev/null); (( $? != 0 ))
02_create_database:
command: !Sub |
mysql -u root --password='${DBRootPassword}' < /tmp/setup.mysql
test: !Sub |
$(mysql ${DBName} -u root --password='${DBRootPassword}' >/dev/null 2>&1 </dev/null); (( $? !=0))
03_configure_wordpress:
command: /tmp/create-wp-config
cwd: /var/www/html/wordpress
CloudFormation – Fn::Sub Examples
![Page 47: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/47.jpg)
CloudFormation – Cross Stack References
Sharing resources made easy
IAM roles, VPC, Security groups
Add an explicit “Export” declaration to stack output
Use the resource in another stack using a new intrinsic function,
Fn::ImportValue`
Few guidelines:
Export names must be unique within an account and region
Cannot create references across regions
Cannot delete a stack that is referenced by another stack (Dependencies
are communicated in errors)
Outputs cannot be modified or removed as long as it is referenced by a
current stack
New
![Page 48: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/48.jpg)
The new intrinsic function for accessing exported outputs.
JSON{ "Fn::ImportValue" : sharedValueToImport }
YAML"Fn::ImportValue": sharedValueToImport
!ImportValue sharedValueToImport
CloudFormation – Fn::ImportValue
![Page 49: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/49.jpg)
Stack A
Stack B
"Outputs": {
"WebServerSecurityGroup": {
"Description": "TheIDofthesecuritygroup",
"Value": {"Fn: : GetAtt": ["WebServerSecurityGroup", "GroupId"]},
"Export": { "Name": "AccountSecGroup"}}
}
"Resources" : {
"WebServerInstance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"InstanceType" : "ts.micro",
"ImageId" : "ami-a1b23456",
"NetworkInterfaces" : [{
"GroupSet" : [{ "Fn::ImportValue" : "AccountSecGroup" ]} ]}
}
}
}
CloudFormation – Cross Stack Examples
![Page 50: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/50.jpg)
Questions?
![Page 51: AWS Infrastructure as Code - September 2016 Webinar Series](https://reader034.fdocuments.us/reader034/viewer/2022052116/58f2cda71a28ab142c8b456b/html5/thumbnails/51.jpg)
Thank you!