2. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
“How do I plan my stacks?”
3. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Organize by layers & environments
Frontend
Services
• Consumer website, seller website,
mobile backend
Backend
Services
• Search, payments, reviews,
recommendations
Shared
Services
• CRM DBs, common monitoring
/alarms, subnets, security groups
Base
Network
• VPCs, Internet gateways, VPNs, NATs
Identity • IAM users, groups, roles
4. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Apply service-oriented architecture
Food catalog
website
Ordering website
Customer DB service
Inventory service
Recommendations
service
Analytics service
Fulfillment
service
Payment
service
5. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Apply service-oriented architecture
Food catalog
website
Customer DB service
“Outputs” : {
“CustDBEndPoint”:””
}
“Parameters” : {
“CustDBEndPoint”:””
}
7. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
“How do I ensure error-free
stack creation?”
8. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Validate your templates
ValidateTemplate API action validates:
• JSON syntax
• Absence of circular dependencies
• Template structure
9. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Use parameter types
"Parameters" : {
“aVpcId" : {
"Type" : "AWS::EC2::VPC::Id"
},
“bSubnetIds" : {
"Type" : "List<AWS::EC2::Subnet::Id>"
},
“cSecurityGroups" : {
"Type" : "List<AWS::EC2::SecurityGroup::Id>"
},
“dKeyPair" : {
"Type" : "AWS::EC2::KeyPair::KeyName"
}
10. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Use parameter constraints
"Parameters" : {
"SourceCIDRForSSH" : {
"Description" : "CIDR block to allow SSH from",
"Type" : "String",
"MinLength" : "9",
"MaxLength" : "18",
"AllowedPattern" : "^([0-9]+.){3}[0-9]+/[0-9]+$"
}
11. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
“How do I deploy and bootstrap
software and data?”
12. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Metadata
AWS::CloudFormation::Init
Use AWS::CloudFormation::Init
Declarative
Reusable
Grouping & ordering
Debug-able
Updatable
Highly secure
BIOT™ (Bring in other tools)
ow.ly/DiNCm
13. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Use AWS::CloudFormation::Init
"YourInstance": {
"Metadata": {
"AWS::CloudFormation::Authentication": {
"S3AccessCreds": {
"type": "S3",
"roleName": { "Ref" : "InstanceRole"},
"buckets" : ["your-bucket"]
}
},
"AWS::CloudFormation::Init": {} Securely download
Choose auth
type. IAM Role is
recommended
14. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Use AWS::CloudFormation::Init
"AWS::CloudFormation::Init": {
"webapp-config": {
"packages" : {}, "sources" : {}, "files" : {},
"groups" : {}, "users" : {},
"commands" : {}, "services" : {}
15. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Use AWS::CloudFormation::Init
"packages" : {},
"sources" : {},
"files" : {},
"groups" : {},
"users" : {},
"commands" : {},
"services" : {}
16. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Use AWS::CloudFormation::Init
"install_chef" : {},
"install_wordpress" : {
"commands" : {
"01_get_cookbook" : {}, ...,
"05_configure_node_run_list" : {
"command" : "knife node run_list add -z `knife
node list -z` recipe[wordpress]",
"cwd" : "/var/chef/chef-repo",
"env" : { "HOME" : "/var/chef" }
17. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Use AWS::CloudFormation::Init
"UserData": {
"# Get the latest CloudFormation helper scripts packagen",
"yum update -y aws-cfn-bootstrapn",
"# Trigger CloudFormation::Init configuration n",
"/opt/aws/bin/cfn-init --stack ", {"Ref": "AWS::StackId"},
" --resource WebServerInstance ",
" --region ", {"Ref": "AWS::Region"}, "n",
"# Signal completionn",
"/opt/aws/bin/cfn-signal –e $? --stack ", {"Ref": "AWS::StackId"},
" --resource WebServerInstance ",
" --region ", {"Ref": "AWS::Region"}, "n"
18. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Use CloudWatch Logs for debugging
"install_logs": {
"packages" : { ... "awslogs" ... },
"services" : { ... "awslogs" ... }
"files": {
"/tmp/cwlogs/cfn-logs.conf": {}
file = /var/log/cfn-init.log
log_stream_name = {instance_id}/cfn-init.log
file = /var/log/cfn-hup.log
log_stream_name = {instance_id}/cfn-hup.log
19. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Use CloudWatch Logs for debugging
20. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
CloudFormation Demo
21. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
CloudFormation Template: Web Application
Availability Zone - A
DMZ – 10.0.0.0/24
Web – 10.0.3.0/24
Database – 10.0.6.0/24
Availability Zone - B
DMZ – 10.0.1.0/24
Web – 10.0.4.0/24
Database – 10.0.7.0/24
Availability Zone - C
DMZ – 10.0.2.0/24
Web – 10.0.5.0/24
Database – 10.0.8.0/24
AWS
CloudFormation
22. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
CloudFormation Template – Production, Test, Dev
Production Test Development
23. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
CloudFormation Template – Multiple Regions
us-east-1 us-west-1 us-west-2
24. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
CloudFormation Template – Second Environment
Availability Zone - A
DMZ – 10.1.0.0/24
Web – 10.1.3.0/24
Database – 10.1.6.0/24
Availability Zone - B
DMZ – 10.1.1.0/24
Web – 10.1.4.0/24
Database – 10.1.7.0/24
Availability Zone - C
DMZ – 10.1.2.0/24
Web – 10.1.5.0/24
Database – 10.1.8.0/24
AWS
CloudFormation
25. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
CloudFormation Parameters
"Parameters": {
"Environment": {
"Default": "Development",
"Type": "String",
"AllowedValues": [ "Production", "Staging", "Development" ],
"Description": "Name of Environment",
"ConstraintDescription": "Production or Staging or Development"
}
}
30. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
When Should I Script?
• Whenever possible:
– If it can be scripted, script it!
– AWS services have API reference guides publicly available.
– Scripts and AWS CloudFormation templates can be used to quickly
launch, start, and stop dev and test environments.
AWS CLI
AWS CloudFormation
template stack
31. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Key Features of the AWS CLI
• It’s a unified tool to manage your AWS services
• It can be installed via MSI, a cross-platform bundle, or pip
• It’s a Python package
• Run aws configure to set access
keys and default region/output format
• All commands in the AWS CLI
have a structure similar to:
– $ aws <service> <operation>
– ex: $ aws ec2 describe-instances
Details for commands can be found online and using the help
subcommand.
AWS CLI
32. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
AWS CLI Configuration Values
• The aws configure <subcommand>
operation gives you programmatic access to
configuration variables
– list provides you with all of the current configuration data.
– get returns the value of a single configuration variable.
– set sets the value of a single configuration variable.
• Example: aws configure get region prints the currently
set region to standard output
33. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
EC2 Instance Profiles
• Assign an IAM role to an EC2 instance on launch
• EC2 securely delivers credentials to the instance
• EC2 rotates credentials
• AWS SDKs, AWS CLI, and Tools for PowerShell have
support for instance profiles
34. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Handy AWS CLI Command Options:
• --output is a useful way to make your returned information easier to read and
parse.
• There are three output formats:
JSON Text Table
{
“Places”: [
{
“City”: “Seattle”,
“State”: “WA”
},
{
“City”: “Las Vegas”,
“State”: “NV”
}
[
}
PLACES Seattle WA
PLACES Las Vegas NV
----------------------------
| SomeOperationName |
+--------------------------+
|| Places ||
|+------------+-----------+|
|| City | State ||
|+------------+-----------+|
|| Seattle | WA ||
|| Las Vegas | NV ||
|+------------+-----------+|
35. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Handy AWS CLI Command Options:
• In the AWS CLI, a profile is a group of
configuration values
• Since profiles store access key information, you can use them to
manage access to resources; i.e., you can have separate dev and test
profiles
• aws configure --profile <profile name> creates a new
profile with that name
• Can be combined with the list, get, and set subcommands
– To set the default region setting for the “dev2” profile to eu-west-1:
aws configure set region eu-west-1 --profile dev2
– Alternatively, that command can be constructed this way:
aws configure set profile.dev2.region eu-west-1
36. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Handy AWS CLI Command Options:
• --query uses JMESPath to filter response data down to include only
the things you want
– JMESPath is a query language for JSON
– jmespath.org has web-based tutorials to help learn the language
• If a command generates a response, the response body is parsed into
JSON
• If a --query option was used, this data is then filtered based on the
query and converted into the requested output format (JSON, text, or
table)
37. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Using
• --query '<keyname>[*].<key>' will return all values in keyname
with that key:
--query 'Capitals[*].City'
Input JSON Query Result
{
"Capitals": [
{
"Nation": "USA",
"City": "Washington"
},
{
"Nation": "Japan",
"City": "Tokyo"
},
{
"Nation": "Brazil",
"City": "Brasília"
}
],
}
[
"Washington",
"Tokyo",
"Brasília"
]
38. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Using Waiters: Polling Instance States
• What's the best way to make sure the AWS CLI waits for an EC2 instance to reach
the running state before performing any other operations?
Script it, right?
#!/bin/bash
instance_id=$(aws ec2 run-instances --image-id ami-12345
--query 'Reservations[].Instances[].InstanceID'
--output text)
instance_state=$(aws ec2 describe-instances –instance-ids $instance_id
--query 'Reservations[].Instances[].State.Name')
while [ "$instance_state" != "running" ]
do
sleep 1
instance_state=$(aws ec2 describe-instances --instance-ids $instance_id
--query 'Reservations[].Instances[].State.Name')
done
39. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Using Waiters: Polling Instance States
• What's the best way to make sure the AWS CLI waits for an EC2 instance
to reach the running state before performing any other operations?
Script it, right?
#!/bin/bash
instance_id=$(aws ec2 run-instances --image-id ami-12345
--query 'Reservations[].Instances[].InstanceID'
--output text)
instance_state=$(aws ec2 describe-instances –instance-ids $instance_id
--query 'Reservations[].Instances[].State.Name')
while [ "$instance_state" != "running" ]
do
sleep 1
instance_state=$(aws ec2 describe-instances --instance-ids $instance_id
--query 'Reservations[].Instances[].State.Name')
done
Problems with this?
40. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Using Waiters: Polling Instance States
• Let's rewrite this script using a waiter:
#!/bin/bash
instance_id=$(aws ec2 run-instances --image-id ami-12345
--query 'Reservations[].Instances[].InstanceID'
--output text)
aws ec2 wait instance-running --instance-ids $instance_id
42. AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Thank You.
This presentation will be loaded to SlideShare the week following the Symposium.
http://www.slideshare.net/AmazonWebServices
AWS Government, Education, and Nonprofit Symposium
Washington, DC I June 25-26, 2015
Notas del editor
When you are designing the architecture for your business, the first question you might have is how do you plan your stacks? Should you one stack for the whole account, 20 stacks, a thousand stacks, should you use nested stacks, etc. Here are some of patterns used successfully by our customers.
The lifecycles of your AWS resources are different. The lifecycle of the base network is very different than the lifecycle of a front end application. The expertise needed to manage CRM databases may be different than the expertise needed to build web applications. For these reasons, organize your resources into horizontal layers of stacks.
Each layer could be a single stack or multiple stacks depending on the complexity and the lifecycle within that layer. For example, in the shared services layer, if you have subnets used for two very different purposes, or by two separate teams, you may be better off having them in separate stacks.
Once you have a layered architecture, you would want to reuse those same templates to replicate it in multiple environments or regions.
One of the benefits of infrastructure-as-code is that you can easily model service-oriented architecture.
Service-oriented architecture is about organizing a big business problem into manageable parts. In this example, we are organizing a food ordering business.
Each service is a self-contained unit of functionality, loosely coupled with other services. The services have clearly defined defined contracts to interact with each other.
We see this working for our customers. When you are using CloudFormation, you map these services onto stacks, and you can create these well defined relationships across stacks.
For example, you might have a food catalog stack that depends on a customer db stack. You would use the stack outputs and parameters to create the relationship between the stacks.
Food catalog needs the customer db endpoint. So, you can publish it in the outputs of the customer DB stack and pass it on as an input parameter when you create a food catalog stack.
Moving on, you might be familiar with nested stacks. CloudFormation offers you the option you to create a tree to stacks. When you author a template, you can reference other templates inside it. When you create a stack from the top level template, a tree of nested stacks is automatically created based on the templates referenced underneath.
What is this good for?
A prime use case for nested stacks is reusability. When you want to maintain a common pattern in a single template and reuse it in many different stacks, you can use nested stacks.
For example, these websites use a common ELB and Auto Scaling pattern. So, you can capture the ELB and Auto Scaling configuration in a separate template and reuse the template for as many websites as you want. A nested stack is created for each website.
You still customize the ELB & Auto Scaling for each website by using parameters.
The other use of nested stacks is to support role-specialization. You can have people to author templates for their area of expertise and still create a combined stack by nesting the templates.
When you are using CloudFormation; like any other software development, you go through the process of coding, testing, hitting errors, debugging, and ultimately getting to a stack that works as expected. Are there any ways to minimize the errors that you encounter? Are there ways to make that process faster? Sure there are.
Make sure your validate your templates using the ValidateTemplate API. This will help you identify the JSON syntax errors, make sure the template sections like Parameters and Resources are structured properly and there are no circular dependencies. If you are using the console, this is done for you automatically.
We found that a large majority of stack creation failures are caused by bad input – invalid parameter values. We launched this new feature to address that challenge.
If you are hosting an application inside a VPC, you are likely passing in the VPC id, subnet ids, etc. as stack parameters. Even if you are not hosting an application in a VPC, you might still be passing in a KeyPair as a parameter so that later you can SSH into the application instances.
When you need to pass in those parameters, use the new parameter types. Logistically, you still pass these values in as simple strings. But, qualifying them with these new parameter types allows CloudFormation to make sure the values are valid.
Using these new parameter types in your templates has two benefits.
Number #1: It allows the CloudFormation console to show you a drop down list of a valid set of values in the console. – So, no more looking up the right VPC id and typing it in.
Even if you are not using the console, these parameter types allow CloudFormation to detect invalid parameters right at the start of the stack creation workflow.
Earlier, if you were passing in an invalid key pair, you might have had to wait a few minutes; until CloudFormation attempted to actually create the instance using that key pair; after creating all other resources that the instance depended on.
Now, if you are using these parameter types, CloudFormation can check whether the key pair is one of the valid key pairs in your account, for the region you are using; in just a few seconds; saving you a lot of time and money.
While we are on the topic of parameters, here is another way to help your template users to pass in valid parameters. CloudFormation parameters support adding constraints on parameters.
In this example, imagine you are provisioning a Windows server and you want to limit the IP address ranges from which a user can remote desktop into the server,
You can use the parameter constraints to make sure that the parameter is a valid CIDR block.
Ultimately, you are provisioning infrastructure to run applications. When you provision infrastructure using CloudFormation, you have several options to deploy and bootstrap those applications.
We recommend using the AWS::CloudFormation::Init and the cfn-bootstrap scripts. We recommend this because it has several benefits like being declarative and being updatable.
We will go over them very quickly. To find out more, note down that URL at the bottom or take a picture.
Through out the rest of this session you may find those links at the bottom. Note them down for more details.
When you are using CloudFormation::Init, use the authentication block to download application bits and data securely.
It supports multiple authentication options – IAM Roles, keys, username/password. Of course, use IAM roles when possible.
First of all, this way of installing and bootstrapping applications is declarative.
For example, just tell CloudFormation where to look for an application source and where to install it. CloudFormation figures out how to do it.
If you were doing this by writing scripts, you will have to figure out and code all of the granular steps in this.
The same applies for installing packages, creating users, and bootstrapping services.
If your configuration is highly customized and you must write a script, you always have the option of downloading that script using the files section here and execute the script using the command section.
CloudFormation::Init supports updates.
If you are bootstrapping an application right inside the EC2 UserData script, you cannot easily update it because the UserData script runs only when an instance is launched.
On the other hand, if you are using CloudFormation::Init, and lets say you want to install an updated package, you can update the template and call UpdateStack.
A CloudFormation daemon - cfn-hup, running on the instance will automatically detect the updated configuration and make changes.
You can still bring in other configuration tools of your choice – anything from a simple script to your chef recipes.
In this example, CloudFormation::Init first installs the chef client and the knife utility, and then lets Chef install WordPress.
To wrap up this topic, as a good practice, use CloudFormation::Init for configuring applications.
When you are using CloudFormation::Init, there should be only three things in your UserData scripts.
Get the latest CloudFormation scripts, Trigger the scripts to execute on CloudFormation::Init, and run cfn-signal to return the outcome back to the CloudFormation service.
Same for Windows and Linux, though the specific syntax for Windows may differ.
Back in the old days, when you hit an software configuration error, you had to SSH into instances to get the logs and debug. Not any more.
This year we launched CloudWatch Logs which allows you to stream any log file out from an EC2 instance and view the logs in the AWS console.
You can use this with CloudFormation::Init.
Just install and start the awslogs service on an instance when you do instance configuration, and have the cfn-init.log file streamed out.
You can store the logs along several dimensions. In this example, I will have the logs organized by instance id.
You can easily explore those logs in the CloudWatch Logs console.
When you are designing the architecture for your business, the first question you might have is how do you plan your stacks? Should you one stack for the whole account, 20 stacks, a thousand stacks, should you use nested stacks, etc. Here are some of patterns used successfully by our customers.
Ultimately, you are provisioning infrastructure to run applications. When you provision infrastructure using CloudFormation, you have several options to deploy and bootstrap those applications.
Notes:
Notes:
You can also find the information for a command by running:
aws <service> <operation> help
This will provide you with details on the commands including descriptions, arguments, sample syntaxes for some parameters, and examples of how to use the operation in different scenarios.
Notes:
Principles are either a user or a role, which is similar to a user but can be assumed by services, users and other roles.
The access key and secret key provide are credentials that identify a principle
The Access Control Policy is defined in JSON policy documents and define what actions a principle can and cannot perform on an AWS resource. Default deny,
Notes:
JSON is the default, however you can change the default output to any of the other two formats within the AWS CLI configuration settings.
JSON is useful if you’re using a JSON tool that can manipulate JSON.
Text output format is tab-separated, therefore it’s useful for commands like grep or set.
Table output format is the easiest to read, and it typically will be able to fit more information on one screen at a time than the other two outputs.
Notes:
Notes:
JSON is the default, however you can change the default output to any of the other two formats within the AWS CLI configuration settings.
JSON is useful if you’re using a JSON tool that can manipulate JSON.
Text output format is tab-separated, therefore it’s useful for commands like grep or set.
Table output format is the easiest to read, and it typically will be able to fit more information on one screen at a time than the other two outputs.
Notes:
JSON is the default, however you can change the default output to any of the other two formats within the AWS CLI configuration settings.
JSON is useful if you’re using a JSON tool that can manipulate JSON.
Text output format is tab-separated, therefore it’s useful for commands like grep or set.
Table output format is the easiest to read, and it typically will be able to fit more information on one screen at a time than the other two outputs.
Notes:
This pretty straight-forward script launches a new Amazon EC2 instance using ami-12345, then queries the instance's ID, which returns in pure text form. Then, it polls the state of that instance ID (using a sleep timer of 1) until the instance reaches a running state.
Notes:
This script is vulnerable to a lot of circumstances that could cause it to be caught in an infinite loop. If the instance fails to launch for some reason, the script will be stuck in an infinite loop, so the script needs to detect for a failure state. It's also possible that an instance gets stuck trying to launch, but this script doesn't have a timeout, either. And even more of an issue, this script is hand-written. The AWS CLI provides a much simpler and more robust solution than the above script.
Notes:
"aws ec2 wait instance-running" will poll every 15 seconds until a successful state has been reached for all of the elements described in the call. After 40 failed checks, it will exit with a return code of 255.
Each service has its own list of wait subcommands. You can find these in the output of an aws help request for that service as well as in our public documentation. For instance, the list of subcommands for aws ec2 wait can be found here:
http://docs.aws.amazon.com/cli/latest/reference/ec2/wait/index.html
The documentation also includes the list of options for each wait subcommand.
When you are designing the architecture for your business, the first question you might have is how do you plan your stacks? Should you one stack for the whole account, 20 stacks, a thousand stacks, should you use nested stacks, etc. Here are some of patterns used successfully by our customers.