The Basics
DevOps@RajeshKumar.XYZ
“Amazon Web Servicesis a platform of web services offering solutions for computing, storing, and networking, at different layers of abstraction.”
Amazon Web Services in Action, Manning 2015
Let’s start!
What is the biggest advantage of Amazon Web Services?
Every part of AWS is controllable via an API
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": "ami-bff32ccc",
"InstanceType": "t2.nano”
}
Template
Written in JSON describing the target state of the infrastructure.
1 Template
=
Multiple Stacks
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "SSH Bastion Host",
"Resources": {
"EC2Instance": {...},
"ElasticIp": {...},
"SecurityGroup": {...}
}
}
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "SSH Bastion Host",
}
Template Format Version and Description
Version of the template anatomy: only valid value: 2010-09-09
A description helps you to organize and document your template
"Resources": {
"EC2Instance": {...},
"ElasticIp": {...},
"SecurityGroup": {...}
}
Resources Section
Includes the description of your infrastructure
The target state of all involved resources is described here
{
...
"Resources": {
"EC2Instance": {
"Type": "AWS::EC2::Instance",
"Properties": {...}
}
}
}
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": "ami-bff32ccc",
"InstanceType": "t2.nano"
}
EC2 Instance
Depending on the Resource Type, there are different properties available
It is possible to specify AMI and Instance Type for an EC2 instance
"EC2Instance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": "ami-bff32ccc",
"InstanceType": "t2.nano",
"NetworkInterfaces": [{"SubnetId": “..."}]
}
}
"Type": "AWS::EC2::EIP",
"Properties": {
"InstanceId": "i-d0f2e055",
"Domain": "vpc"
}}
Elastic IP
Properties of resource of type AWS::EC2::EIP
An Elastic IP address needs to be linked to an EC2 instance
Domain vpc as we are operating in a VPC
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "ssh-bastion-host",
"VpcId": "vpc-6b53320e",
"SecurityGroupIngress": [{...}]
}
Security Group
Resource describing a Security Group
Includes link to VPC and nested ingress rules
"SecurityGroupIngress": [{
"CidrIp": "0.0.0.0/0",
"FromPort": 22,
"IpProtocol": "tcp",
"ToPort": 22
}]
Security Group Ingress
Nested ingress rules of Security Group
Allowing incoming TCP traffic from everywhere on port 22
"EC2Instance": {
"Properties": {
"NetworkInterfaces": [{
"GroupSet": [{"Ref": "SecurityGroup"}]
}]
}
},
"SecurityGroup": {...}
"EC2Instance": {...},
"ElasticIP": {
"Type": "AWS::EC2::EIP",
"Properties": {
"InstanceId": {"Ref": "EC2Instance"},
"Domain": "vpc"
}
}
Install and Configure AWS Command Line Interface (CLI)
https://aws.amazon.com/cli/
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "SSH Bastion Host",
"Parameters": {...},
"Resources": {...}
}
"Parameters": {
"KeyPair": {
"Description": "A SSH key pair.",
"Type": "AWS::EC2::KeyPair::KeyName"
}
}
"InstanceType": {
"Description": “The instance type.",
"Type": "String"
}
Description
Describe your parameters to simplify filling them out later
"Parameters": {
"KeyPair": {
"Description": "A SSH key pair.",
"Type": "AWS::EC2::KeyPair::KeyName"
}
}
String: "string"
Number: 1
List<Number>: [1,2,3]
CommaDelimitedList: "1,2,3"
Parameter Type
General parameter types
AWS::EC2::Image::Id: "ami-b43503a4"
AWS::EC2::Instance::Id: "i-47cad982"
AWS::EC2::SecurityGroup::Id: "sg-6246b70c"
AWS::Route53::HostedZone::Id: "Z2VHZWU704GYI1"
Parameter Type
AWS parameter types
"Parameters": {
"KeyPair": {...}
},
"Resources": {
"EC2Instance": {
"Properties": {
"KeyName": {"Ref": "KeyPair"}
}
}}
AllowedValues: ["a", "b", "c"]
AllowedPattern: "[a-z0-9]*"
MaxLength/ MinLength: 1
MaxValue/ MinValue: 2
Input Validation
Software development 101 : validate your inputs
"InstanceType": {
"Description": "The instance type.",
"Type": "String",
"AllowedValues": ["t2.nano", "t2.micro", "t2.small"]
}
"InstanceType": {
"Description": "The instance type.",
"Type": "String",
"Default": "t2.nano"
}
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "SSH Bastion Host",
"Parameters": {...},
"Resources": {...},
"Outputs": {...}
}
"Outputs": {
"SSHBastionHostPublicIp": {
"Description": "Public IP address...",
"Value": {"Ref": "ElasticIP"}
}
}
"SSHBastionHostPublicIp": {
"Description": "Public IP address...",
"Value": {"Ref": "ElasticIP"}
}
Default Resource Return Value
Accessible via built -in Ref function
Return Value depends on the Resource Type
"SSHBastionHostPrivateIp": {
"Description": "Private IP address...",
"Value": {"Fn::GetAtt": ["EC2Instance", "PrivateIp"]}
}
Specific Resource Return Value
Accessible via built-in Fn::GetAtt function
Different return values depending on the Resource Type
"Resources": {
"ElasticIP": {...}
}
"Outputs": {
"SSHBastionHostPublicIp": {
"Description": "Public IP address...",
"Value": {"Ref": "ElasticIP"}
}
}
"Resources": {
“EC2": {...}
}
"Outputs": {
"SSHBastionHostPrivateIp": {
"Description": "Private IP address...",
"Value": {"Fn::GetAtt": ["EC2", "PrivateIp"]}
}
}
“A map is an object that maps keys to values.”
What is a map?
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "SSH Bastion Host",
“Mappings": {...},
"Resources": {...}
}
"Mappings" : {
"Mapping" : {
"Key" : {
"Name" : "Value"
}
}
}
"Mapping" : {
"KeyA" : {},
"KeyB" : {}
}
Unique Key
A key has to be unique within a mapping
"Key" : {
"NameA" : "ValueA",
"NameB" : "ValueB",
}
Named Values
A key can contain multiple named values
A name has to be unique within a key
"RegionAMI": {
"us-east-1": {
"AmazonLinux": "ami-8fcee4e5",
"Ubuntu": "ami-fce3c696"
},
"eu-west-1": {
"AmazonLinux": "ami-e1398992",
"Ubuntu": "ami-f95ef58a"
}}
"Fn::FindInMap": ["RegionAMI", "eu-west-1", "AmazonLinux"]
Fn:: FindInMap
Allows to access values from a Mapping
Accepts Mapping name, Key, and Name as parameters
"Subnet": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": "???",
"CidrBlock": "10.0.0.0/24",
"VpcId": {"Ref": "VPC"},
"MapPublicIpOnLaunch": "true"
}}
AWS::AccountId
AWS::NotificationARNs
AWS::NoValue
AWS::Region
AWS::StackId
AWS::StackName
{"Ref": "AWS::Region"}
Accessing a Pseudo Parameter
Use built in Ref function to access pseudo parameters
{"Fn::GetAZs": {"Ref": "AWS::Region"}}
Fn::GetAZs
Returns all Availability Zones for a region
Uses current region of stack in this example
{"Fn::Select": ["0", ["a", "b", "c"]}
Fn::Select
Selects a value from a list
Selects first value of list in this example
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": {
"Fn::Select": [
"0",
{"Fn::GetAZs": {"Ref": "AWS::Region"}}
]
}, ...
}
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-reference.html
"Type": "AWS::EC2::Instance",
"Properties": {
"UserData": "..."
}
User Data Property
User Data can be described as property of an EC2 Instance
But User Data needs to be encoded in base64
{"Fn::Base64": "A String"}
Fn::Base64
There’s a built in function for that
Encodes a String in base64
{"Fn::Join": [";", ["a", "b", "c"]]}
Fn::Join
Allows you to concatenate Strings
Accepts a delimiter and a list of Strings as input
"UserData": {"Fn::Base64": {"Fn::Join": ["\n", [
"#!/bin/bash-ex",
"yum install-y httpd",
"cd /var/www/html",
"echo '<html><body>...</body></html>' > index.html",
"service httpd start"
]]}}