Cloud Formation Template Examples

1. Simple Cloud Formation template to create EC2 instance.

---
AWSTemplateFormatVersion: "2010-09-09"
Description: "This template will create an EC2 instance with default tenancy, with specific AMI, Availability zone, Subnet, KeyPair and instance type "
 
Resources:
  DEVEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      AvailabilityZone: ap-south-1a
      ImageId: ami-0732b62d310b80e97
      InstanceType: t2.micro
      KeyName: MumbaiKP
      SubnetId: subnet-03a896945c3e5eb15
      Tags:
        Key: "Name"
          Value: "CFInstance"
      Tenancy: default

2. A Cloud Formation template to create EC2 instance with EIP.

---
AWSTemplateFormatVersion: "2010-09-09"
Description: "This template will create an EC2 instance with default tenancy, with specific AMI, Availability zone, Subnet, KeyPair and Instance type and EIP"
 
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0732b62d310b80e97
      InstanceType: t2.micro
      KeyName: MumbaiKP
      SecurityGroups:
        - default
      Tags:
        - Key: "Name"
          Value: "CFInstance"
      Tenancy: default
 
  MyElasticIP:                  
    Type: AWS::EC2::EIP
    Properties:
      InstanceId: !Ref MyEC2Instance

3. A Cloud Formation template to create EC2 instance with EIP and Security Group.

---
AWSTemplateFormatVersion: "2010-09-09"
Description: "This template will create an EC2 instance with default tenancy, with specific AMI, Availability zone, Subnet, KeyPair, and Instance type and EIP"
 
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0732b62d310b80e97
      InstanceType: t2.micro
      KeyName: MumbaiKP
      SecurityGroups:
        - !Ref SSHSecurityGroup
      Tags:
        - Key: "Name"
          Value: "CFInstance"
      Tenancy: default
     
  SSHSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: My SSH SG to allow 22 port
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 0.0.0.0/0
 
  MyElasticIP:                 
    Type: AWS::EC2::EIP
    Properties:
      InstanceId: !Ref MyEC2Instance

4. A Cloud Formation template to create EC2 instance with Security Group and allows you to select AZ, Instance Type, and Key Pair.

---
AWSTemplateFormatVersion: "2010-09-09"
 
Description: "This template allows you to select AvailabilityZone, InstanceType, and KeyPair to create EC2 instance with SecurityGroup allowing 22 port"
 
Parameters:
  MyKeyName:
    Description: Select the Kay Name from the List
    Type: AWS::EC2::KeyPair::KeyName
         
  MyAvailabilityZone:
    Description: Select the AZ from the List
    Type: String
    Default: ap-south-1a
    AllowedValues:
      - ap-south-1a
      - ap-south-1b
      - ap-south-1c
           
  MyInstanceType:
    Description: Select the AZ from the List
    Type: String
    Default: t2.micro
    AllowedValues:
      - "t2.nano"
      - "t2.micro"
      - "t2.small"
      - "t2.medium"
      - "t2.large"
 
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0732b62d310b80e97
      InstanceType: !Ref MyInstanceType
      KeyName: !Ref MyKeyName
      SecurityGroups:
        - !Ref SSHSecurityGroup
      Tags:
        - Key: "Name"
          Value: "CFInstance"
      Tenancy: default
      AvailabilityZone: !Ref MyAvailabilityZone
 
  SSHSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "My SSH SG to allow 22 port"
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 0.0.0.0/0

5. A Cloud Formation template to create EC2 instance with Dev, Test, Prod environment with respective instance type.

 ---
AWSTemplateFormatVersion: "2010-09-09"
Description: "This template allows you to select an environmnent like dev, test, prod based on which EC2 instance of respective instance type will be launched with AZ, KeyPair, existing SecurityGroup inside selected subnet."
 
Parameters:
  MyKeyName:
    Description: Select the key name from the list
    Type: AWS::EC2::KeyPair::KeyName
 
  MyEnvironment:
    Description: Select Your Environment
    Type: String
    Default: Dev
    AllowedValues:
      - Dev
      - Test
      - Prod
 
  MyAvailabilityZone:
    Description: Select the Availability Zone from the List
    Type: String
    Default: ap-south-1a
    AllowedValues:
      - ap-south-1a
      - ap-south-1b
      - ap-south-1c
 
  MySecurityGroups:
    Description: The list of SecurityGroupIds in your Virtual Private Cloud (VPC)
    Type: List<AWS::EC2::SecurityGroup::Id>      
 
  MySubnetId:
    Description: Select Subnet from the List.
    Type: AWS::EC2::Subnet::Id
 
Mappings:
  MyRegionMap:
    ap-south-1:
      AMI1: ami-0732b62d310b80e97   
 
  MyEnvironmentMap:
    Dev:
      instanceType: t2.micro
    Test:
      instanceType: t2.small       
    Prod:
      instanceType: t2.medium
 
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      AvailabilityZone: !Ref MyAvailabilityZone
      ImageId: !FindInMap
        - MyRegionMap
        - !Ref 'AWS::Region'
        - AMI1         
      InstanceType: !FindInMap
        - MyEnvironmentMap
        - !Ref MyEnvironment
        - instanceType                
      KeyName: !Ref MyKeyName
      SecurityGroupIds: !Ref MySecurityGroups
      SubnetId: !Ref MySubnetId
      Tags:
        - Key: "Name"
          Value: "CFInstance"
      Tenancy: default

6. A Cloud Formation template to create VPC with public and private subnets, Internet Gateway, Nat Gateway, Route Tables.

---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'This template will create VPC with two public and private subnets spread across two AZ, creates Internet gateway, Nat Gateway, Route Tables and also associate these subnets with respective route tables, Also adds route entries to route tables for traffic destined to the Internet.' 
Parameters:
  EnvironmentName:
    Description: An environment name that is prefixed to resource names
    Type: String
 
  VpcCIDR:
    Description: Please enter the IP range (CIDR notation) for this VPC
    Type: String
    Default: 10.192.0.0/16
   
  PublicSubnet1CIDR:
    Description: Please enter the IP range (CIDR notation) for Public Subnet 1
    Type: String
    Default: 10.192.1.0/24
 
  PublicSubnet2CIDR:
    Description: Please enter the IP range (CIDR notation) for Public Subnet 2
    Type: String
    Default: 10.192.2.0/24
 
  PrivateSubnet1CIDR:
    Description: Please enter the IP range (CIDR notation) for Private Subnet 1
    Type: String
    Default: 10.192.11.0/24
 
  PrivateSubnet2CIDR:
    Description: Please enter the IP range (CIDR notation) for Private Subnet 2
    Type: String
    Default: 10.192.12.0/24   
 
Resources:
##### Create VPC #####
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-VPC
 
##### Create Internet Gateway and Attach to VPC #####                
 
  MyInternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-IGW
 
  AttachMyInternetGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref MyVPC
      InternetGatewayId: !Ref MyInternetGateway
 
##### Create Nat Gateway in Public Subnet #####
##### Allocate Elastic IP to Nat Gateway #####
 
  NatEIP:
    DependsOn: AttachMyInternetGateway
    Type: AWS::EC2::EIP
    Properties:
       Domain: vpc
 
  MyNATGateway:
    Type: AWS::EC2::NatGateway
    DependsOn: AttachMyInternetGateway
    Properties:
       AllocationId: !GetAtt NatEIP.AllocationId
       SubnetId: !Ref PublicSubnet1
       Tags:
         - Key: Name
           Value: !Sub ${EnvironmentName}-NGW
 
##### Create Public and Private Subnets #####   
 
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select [ 0, !GetAZs ]
      CidrBlock: !Ref PublicSubnet1CIDR
      MapPublicIpOnLaunch: true
      Tags:
       - Key: Name
         Value: !Sub ${EnvironmentName}-Public-A
      VpcId: !Ref MyVPC
 
  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select [ 1, !GetAZs ]
      CidrBlock: !Ref PublicSubnet2CIDR
      MapPublicIpOnLaunch: true
      Tags:
       - Key: Name
         Value: !Sub ${EnvironmentName}-Public-B
      VpcId: !Ref MyVPC
 
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select [ 0, !GetAZs ]
      CidrBlock: !Ref PrivateSubnet1CIDR
      MapPublicIpOnLaunch: false
      Tags:
       - Key: Name
         Value: !Sub ${EnvironmentName}-Private-A
      VpcId: !Ref MyVPC
 
  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select [ 1, !GetAZs ]
      CidrBlock: !Ref PrivateSubnet2CIDR
      MapPublicIpOnLaunch: false
      Tags:
       - Key: Name
         Value: !Sub ${EnvironmentName}-Private-B
      VpcId: !Ref MyVPC
 
##### Create Public Route Table and add Route to InternetGateway #####
 
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC
      Tags:
      - Key: Name
        Value: !Sub ${EnvironmentName}-PublicRT
 
  MyPublicRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachMyInternetGateway
    Properties:
       RouteTableId: !Ref PublicRouteTable
       DestinationCidrBlock: 0.0.0.0/0
       GatewayId: !Ref MyInternetGateway
 
##### Create Private Route Table add Route to NATGateway #####
 
  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC
      Tags:
      - Key: Name
        Value: !Sub ${EnvironmentName}-PrivateRT
 
  MyPrivateRoute:
    Type: AWS::EC2::Route
    Properties:
       RouteTableId: !Ref PrivateRouteTable
       DestinationCidrBlock: 0.0.0.0/0
       NatGatewayId: !Ref MyNATGateway
 
##### Associate Public RT and Private RT with subnets #####
 
  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable
 
  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable
 
  PrivateSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable
 
  PrivateSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateRouteTable
 
Outputs:
  VPC:
    Description: A reference to the created VPC
    Value: !Ref MyVPC
 
  PublicSubnets:
    Description: A list of the public subnets
    Value: !Join [ ",", [ !Ref PublicSubnet1, !Ref PublicSubnet2 ]]
 
  PrivateSubnets:
    Description: A list of the private subnets
    Value: !Join [ ",", [ !Ref PrivateSubnet1, !Ref PrivateSubnet2 ]]
 
  PublicSubnet1:
    Description: A reference to the public subnet in the 1st Availability Zone
    Value: !Ref PublicSubnet1
 
  PublicSubnet2:
    Description: A reference to the public subnet in the 2nd Availability Zone
    Value: !Ref PublicSubnet2
 
  PrivateSubnet1:
    Description: A reference to the private subnet in the 1st Availability Zone
    Value: !Ref PrivateSubnet1
 
  PrivateSubnet2:
    Description: A reference to the private subnet in the 2nd Availability Zone
    Value: !Ref PrivateSubnet2

7. A Cloud Formation template to create EC2 Instance with Apache web server installed using CloudFormation bootstrap scripts.

--- 
AWSTemplateFormatVersion: 2010-09-09
Description: "AWS CloudFormation Sample Template for Apache Web Server This template demonstrates using the AWS CloudFormation bootstrap scripts to install the packages and files necessary to deploy the Apache web server at instance launch time."
Parameters:
  MyKeyName:
    Description: Select The Key Name From The List.
    Type: 'AWS::EC2::KeyPair::KeyName'
  MyInstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
      - t2.nano
      - t2.micro
      - t2.small
      - t2.medium
      - t2.large
  MyAvailabilityZone:
    Description: Select the Availability Zone from the List
    Type: String
    Default: ap-south-1a
    AllowedValues:
      - ap-south-1a
      - ap-south-1b
      - ap-south-1c
  MySecurityGroups:
    Description: The list of SecurityGroupIds in your Virtual Private Cloud (VPC)
    Type: 'List<AWS::EC2::SecurityGroup::Id>'
  MySubnetId:
    Description: Select Subnet From The List.
    Type: 'AWS::EC2::Subnet::Id'
Resources:
  MyEC2Instance:
    Type: 'AWS::EC2::Instance'
    Metadata:
      Comment: Install httpd package
      'AWS::CloudFormation::Init':
        config:
          packages:
            yum:
              httpd: []
          files:
            /var/www/html/index.html:
              content: |
                <html>
                  <body>
                    <h1>Goinit.Net</h1>
                    <h2>CloudFormation Web Server</h2>
                    <p>Welcome to My page.</p>
                  </body>
                </html>
              mode: '000644'
              owner: root
              group: root
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                stack=$(AWS::StackId}
                region=${AWS::Region}
                interval=7
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.MyEC2Instance.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource MyEC2Instance --region ${AWS::Region}
              mode: '000400'
              owner: root
              group: root
          services:
            sysvinit:
              httpd:
                enabled: 'true'
                ensureRunning: 'true'
              cfn-hup:
                enabled: 'true'
                ensureRunning: 'true'
                files:
                  - /etc/cfn/cfn-hup.conf
                  - /etc/cfn/hooks.d/cfn-auto-reloader.conf   
    Properties:
      AvailabilityZone: !Ref MyAvailabilityZone
      ImageId: ami-0732b62d310b80e97
      InstanceType: !Ref MyInstanceType
      KeyName: !Ref MyKeyName
      SecurityGroupIds: !Ref MySecurityGroups
      SubnetId: !Ref MySubnetId
      Tags:
        - Key: Name
          Value: CFInstance
      Tenancy: default
      UserData:
        Fn::Base64:
          !Sub |
            #!/bin/bash -xe
            #Get latest cfn package
            yum update -y aws-cfn-bootstrap
            #Start cfn-init to install all metadata content
            /opt/aws/bin/cfn-init --stack ${AWS::StackName} --resource MyEC2Instance --region ${AWS::Region} || error_exit 'Failed to run cfn-init'
            #Signal the status from cfn-init
            /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource MyEC2Instance --region ${AWS::Region}
Outputs:
  MyInstanceURL:
    Description: Apache web URL
    Value: !Sub 'http://${MyEC2Instance.PublicDnsName}'

8. A Cloud Formation template to create EC2 Instance with S3 Read Only Access by using EC2 IAM Role.
---
AWSTemplateFormatVersion: "2010-09-09"
Description: "AWS Cloud Formation template to create EC2 Instance with S3 Read Only Access(List* and Get*) by using EC2 IAM Role "
 
Parameters:
  InstanceName:
    Description: Give Tag to Instance
    Type: String
    Default: WebServer
 
  MyKeyName:
    Description: "Select The Key Name From The List."
    Type: AWS::EC2::KeyPair::KeyName
 
  MyInstanceType:
    Description: "WebServer EC2 instance type"
    Type: String
    Default: "t2.micro"
    AllowedValues:
      - "t2.nano"
      - "t2.micro"
      - "t2.small"
      - "t2.medium"
      - "t2.large"
 
  MyAvailabilityZone:
    Description: Select the Availability Zone from the List
    Type: String
    Default: ap-south-1a
    AllowedValues:
      - ap-south-1a
      - ap-south-1b
      - ap-south-1c
 
  MySecurityGroups:
    Description: The list of SecurityGroupIds in your Virtual Private Cloud (VPC)
    Type: List<AWS::EC2::SecurityGroup::Id>      
 
  MySubnetId:
    Description: Select Subnet From The List.
    Type: AWS::EC2::Subnet::Id
 
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      AvailabilityZone: !Ref MyAvailabilityZone
      ImageId: ami-0e306788ff2473ccb
      InstanceType: !Ref MyInstanceType
      KeyName: !Ref MyKeyName
      SecurityGroupIds: !Ref MySecurityGroups
      SubnetId: !Ref MySubnetId
      Tags:
        - Key: "Name"
          Value: !Ref InstanceName
      Tenancy: default
      IamInstanceProfile: !Ref MyInstanceS3AccessProfile
 
  MyEc2S3AccessProfileRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
              - ec2.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: MyEc2InstanceS3AccessPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 's3:Get*'
                  - 's3:List*'
                Resource: '*'
 
  MyInstanceS3AccessProfile:
    Type: 'AWS::IAM::InstanceProfile'
    Properties:
      Path: /
      Roles:
        - !Ref MyEc2S3AccessProfileRole  
 
Outputs:
  MyInstanceId:
    Description: Public IP Address
    Value: !GetAtt MyEC2Instance.PublicIp

How to create custom network with specific subnet and IP range

Task:

Create a custom network with default bridge driver named as my-custom-net with subnet 10.100.0.0/16 gateway 10.100.0.1 and IP range 10.100.2.0/24.
Create a container named as net-test with custom network i.e my-custom-net.
Inspect the container net-test and check the IP address assigned to it.

1. Create a custom network with custom IP settings.

#docker network create --subnet 10.100.0.0/16 --gateway 10.100.0.1 --ip-range 10.100.2.0/24 --driver bridge --label host2net my-custom-net                             

2. Inspect the custom network.

#docker network inspect my-custom-net                                                           

Check the Subnet, Gateway, IP Range and Label assigned to the network.


3. Launch the container with the custom network.  

#docker run -itd --name test1 --net my-custom-net centos:centos7 bash             

4. check container IP with docker inspect command.

#docker container inspect test1| grep -w "IPAddress"