Note: This blog assumes that you already know how to create a VPC using AWS web console and have a clear understand of it’s architecture and requirements, if you are new to Cloud Formation please refer this blog for basic understand of what it is.
What are Parameters, Resources, Outputs in an AWS Cloud Formation template?
Parameters
when you want to allow any user input while creating a stack like name of a s3 bucket or if you want to reuse the same template it’s not recommended to hardcode all the details of your resources rather you can give these details using parameters, let’s see this while creating the stack in aws console, and it’s completely optional to define parameters in a template , below is an example parameter which is intended to be used for a VPC CIDR.
Parameters: VpcCIDR: Default: 10.0.0.0/16 Description: Please enter the CIDR (IP range) for this VPC Type: String
all the parameters that you declare in a template should be under Parameters: tag only and VpcCIDR: is the logical names it can be any alpha alphanumeric value and it should be unique from all the logical names that were defined with in a template as one can refer to this parameter with this logical name only, different parameter types allowed string , number, list of numbers, comma-delimited list , the type of value allowed for a particular parameter is declared under Type:, and the value given for Default: key word will be used by cloud formation for creating the stack/infrastructure if no other value is given by the user while creating the stack.
Resources
there more than 200 plus resources available in aws , the infrastructure that you want to deploy should be declared under Resources tag in configuration file , and every resource will have its own properties and there will be some required properties for each resource that need to be declared to deploy a resource, below is the basic syntax to declare a resource
Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCIDR EnableDnsHostnames: true EnableDnsSupport: true InstanceTenancy: default Tags: - Key: Name Value: Test VPC
Here Resources: is tag under which you need to declare resources that you want deploy and Type:AWS::EC2::VPC is the resource key word for VPC . CidrBlock, EnableDnsHostnames, InstanceTenancy are the basic properties that are needed to create a vpc, and as you can see Intrinsic function !Ref is used to get the value for CidrBlock property by referring to VpcCIDR which is declared in Parameters part.
Intrinsic functions are basically built-in functions that comes within the AWS cloud formation, The intrinsic function Ref returns the value of the given parameter or resource, when you specify a parameter’s logical name, it returns the value of the parameter and if you specify a resource’s logical name, it returns a value that you can use to refer to that resource.
Outputs
once the stack is created or the infrastructure is deployed to get the details of resources , for example you have deployed a ec2 instance and you want Id of that instance you have to go all the way to ec2 dashboard in AWS web console for this , to make it easier we can declare outputs with in the same template you are using to create your infrastructure , this will give you specific details in the output section of cloud formation, lets see this while creating the stack in CF.
below is the basic syntax to declare a output ,
Outputs: Logical ID: Description: Information about the value Value: Value to return Export: Name: Name of resource to export
Intrinsic Function in AWS Cloud Formation
Before going on to create whole template to create a VPC Let’s look in to two more intrinsic functions.
!Sub
The intrinsic function Fn: :Sub called as substitute function substitutes variables in an input string with values that you specify, you can use this function to construct commands or outputs in your template, go through the below given yaml configuration and explanation below it.
Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCIDR EnableDnsHostnames: true EnableDnsSupport: true InstanceTenancy: default Tags: - Key: Name Value: Test VPC Outputs: VPC: Description: VPC ID Export: Name: !Sub ${AWS::StackName}-VPC Value: !Ref VPC
In the above cloud formation template, Fn:: Sub is used in the output to give a export name, ${Variable name } this is the syntax to describe a variable using substitute function, !Sub ${AWS::StackName} is used it to get the stack name and giving it as a Export name.
GetAZs
The intrinsic function Fn::GetAZs returns an array that lists Availability Zones in a region in alphabetical order, so that way you don’t have to hard-code a full list of Availability Zones for a specified region.
Select intrinsic function select returns a single object from a list of objects based on given index.
Cloud Formation Template to Create VPC
Below is the complete configuration in yaml for creating a VPC(CIDR: 10.0.0.0/16 ) with one public (CIDR: 10.0.0.0/24) and one private subnet(CIDR: 10.0.1.0/24), go through each block and save in a yaml file.
AWSTemplateFormatVersion: 2010-09-09 Description: This template creates vpc with public and private subnets # Parameters are used to to build flexible/reusable CloudFormation templates Parameters: VpcCIDR: Default: 10.0.0.0/16 Description: Please enter the IP range (CIDR notation) for this VPC Type: String PublicSubnet1CIDR: Default: 10.0.0.0/24 Description: Please enter the IP range (CIDR notation) for the public subnet 1 Type: String PrivateSubnet1CIDR: Default: 10.0.2.0/24 Description: Please enter the IP range (CIDR notation) for the private subnet 1 Type: String SSHLocation: Default: 0.0.0.0/0 Description: The IP address range that can be used to access the web server using SSH. MaxLength: '18' MinLength: '9' Type: String Resources: # Create VPC VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCIDR EnableDnsHostnames: true EnableDnsSupport: true InstanceTenancy: default Tags: - Key: Name Value: Test VPC # Create Internet Gateway InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: Test IGW # Attach Internet Gateway to VPC InternetGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VPC # Create Public Subnet1 PublicSubnet1: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 0, !GetAZs '' ] CidrBlock: !Ref PublicSubnet1CIDR MapPublicIpOnLaunch: true Tags: - Key: Name Value: Public Subnet 1 VpcId: !Ref VPC # Create Route Table PublicRouteTable: Type: AWS::EC2::RouteTable Properties: Tags: - Key: Name Value: Public Route Table VpcId: !Ref VPC # Add a Public Route to the Route Table PublicRoute: Type: AWS::EC2::Route Properties: DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway RouteTableId: !Ref PublicRouteTable # Associate Public Subnet1 with Public Route Table PublicSubnet1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PublicRouteTable SubnetId: !Ref PublicSubnet1 # Create Private Subnet1 PrivateSubnet1: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 0, !GetAZs '' ] CidrBlock: !Ref PrivateSubnet1CIDR MapPublicIpOnLaunch: false Tags: - Key: Name Value: Private Subnet 1 | App Tier VpcId: !Ref VPC # Create Security Group for the Web Server WebServerSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Enable traffic on ports 80/http, 443/https, 22/SSH SecurityGroupIngress: - IpProtocol: tcp FromPort: '80' ToPort: '80' CidrIp: "0.0.0.0/0" - IpProtocol: tcp FromPort: '443' ToPort: '443' CidrIp: "0.0.0.0/0" - IpProtocol: tcp FromPort: '22' ToPort: '22' CidrIp: "0.0.0.0/0" Tags: - Key: Name Value: WebServer Security Group VpcId: !Ref VPC #Create an EC2 instance in public subnet. EC2Instance: Type: AWS::EC2::Instance Properties: InstanceType: t2.micro ImageId: "ami-051dfed8f67f095f5" KeyName: key9 NetworkInterfaces: - DeviceIndex: 0 AssociatePublicIpAddress: true DeleteOnTermination: true SubnetId: !Ref PublicSubnet1 GroupSet: - !Ref WebServerSecurityGroup Outputs: # Export VPC ID VPC: Description: VPC ID Export: Name: !Sub ${AWS::StackName}-VPC Value: !Ref VPC # Export Public Subnet 1 PublicSubnet1: Description: Public Subnet 1 ID Export: Name: !Sub ${AWS::StackName}-PublicSubnet1 Value: !Ref PublicSubnet1 # Export Private Subnet 1 PrivateSubnet1: Description: Private Subnet 1 ID Export: Name: !Sub ${AWS::StackName}-PrivateSubnet1 Value: !Ref PrivateSubnet1 # Export WebServer Security Group ID WebServerSecurityGroup: Description: Webserver Security Group ID Export: Name: !Sub ${AWS::StackName}-WebServerSecurityGroup Value: !Ref WebServerSecurityGroup # Export DataBase Security Group ID EC2Instance: Description: EC2 Instance ID Export: Name: !Sub ${AWS::StackName}-EC2Instance Value: !Ref EC2Instance
Steps to Create Infrastructure using Cloud Formation and Configuration Template
On your AWS web console search for Cloud Formation then click on create stack.
Stack: To create resources defined in template you need to create a stack in cloud formation which allows you to manage your resources like delete update or create.
Then in step-2 give a name to your stack and also you change the default values of the parameters that you declared in the configuration template.
In step-3 you can give tags and the IAM role that should be used by CF to create your stack and in Step-4 Review all the details and click on Create Stack , this will redirect you to events page where you can see the progress of the deployment.
Now go to Outputs to see the values that you have exported in the configuration file.
Please contact our cloud consultants if you have any cloud infrastructure related issues to be discussed.