AWS Cloudformation Series – 27/Sep/2019

What is happening when we try to create stack from template

  • Creating Template locally
  • Create a stack & we are uploading template
    • Templates are stored in S3 Buckets
  • The AWS Reads the template and performs IAC
  • Refer Here for cloudformation introduction

Start Building From where we left

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "This is my first cf template",
    "Parameters": {
        "subnet1az": {
            "Description": "Enter subnet1 az",
            "Type": "String",
            "Default": "us-west-2a"
        },
        "subnet2az": {
            "Description": "Enter subnet1 az",
            "Type": "String",
            "Default": "us-west-2b"
        },
        "subnet3az": {
            "Description": "Enter subnet1 az",
            "Type": "String",
            "Default": "us-west-2c"
        }
    },
    "Resources": {
        "myvpc": {
            "Type": "AWS::EC2::VPC",
            "Properties": {
                "CidrBlock": "10.1.0.0/16",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet1": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet1az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.0.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet2": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet2az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.1.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet3": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet3az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.2.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        }
    }
}
  • The limitation as of now in the above template is "we allow user to enter free hand text"
  • Lets add a paramater with allowed values
"subnet1az": {
            "Description": "Enter subnet1 az",
            "Type": "String",
            "Default": "us-west-2a",
            "AllowedValues": ["us-west-2a", "us-west-2b", "us-west-2c"]
        }
  • The whole template is as follows
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "This is my first cf template",
    "Parameters": {
        "subnet1az": {
            "Description": "Enter subnet1 az",
            "Type": "String",
            "Default": "us-west-2a",
            "AllowedValues": ["us-west-2a", "us-west-2b", "us-west-2c"]
        },
        "subnet2az": {
            "Description": "Enter subnet1 az",
            "Type": "String",
            "Default": "us-west-2b",
            "AllowedValues": ["us-west-2a", "us-west-2b", "us-west-2c"]
        },
        "subnet3az": {
            "Description": "Enter subnet1 az",
            "Type": "String",
            "Default": "us-west-2c",
            "AllowedValues": ["us-west-2a", "us-west-2b", "us-west-2c"]
        }
    },
    "Resources": {
        "myvpc": {
            "Type": "AWS::EC2::VPC",
            "Properties": {
                "CidrBlock": "10.1.0.0/16",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet1": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet1az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.0.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet2": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet2az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.1.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet3": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet3az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.2.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        }
    }
}
  • While executing template to create stack now user will have a drop down list not a free hand text.

  • Problem is cannot work with other regions apart from oregon

  • What is the solution ?

    • One solution is to use interpolation
    • Refer Supported AWS-Specific Parameter Types in here
    • Lets use the type defined for Availability Zone and relook at our script
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "This is my first cf template",
    "Parameters": {
        "subnet1az": {
            "Description": "Enter subnet1 az",
            "Type": "AWS::EC2::AvailabilityZone::Name"
        },
        "subnet2az": {
            "Description": "Enter subnet1 az",
            "Type": "AWS::EC2::AvailabilityZone::Name"
        },
        "subnet3az": {
            "Description": "Enter subnet1 az",
            "Type": "AWS::EC2::AvailabilityZone::Name"
        }
    },
    "Resources": {
        "myvpc": {
            "Type": "AWS::EC2::VPC",
            "Properties": {
                "CidrBlock": "10.1.0.0/16",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet1": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet1az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.0.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet2": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet2az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.1.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet3": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet3az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.2.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        }
    }
}
  • Lets add internet gateway, route table & route to internet gateway
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "This is my first cf template",
    "Parameters": {
        "subnet1az": {
            "Description": "Enter subnet1 az",
            "Type": "AWS::EC2::AvailabilityZone::Name"
        },
        "subnet2az": {
            "Description": "Enter subnet1 az",
            "Type": "AWS::EC2::AvailabilityZone::Name"
        },
        "subnet3az": {
            "Description": "Enter subnet1 az",
            "Type": "AWS::EC2::AvailabilityZone::Name"
        }
    },
    "Resources": {
        "myvpc": {
            "Type": "AWS::EC2::VPC",
            "Properties": {
                "CidrBlock": "10.1.0.0/16",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet1": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet1az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.0.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet2": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet2az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.1.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet3": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet3az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.2.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "myigw": {
            "Type": "AWS::EC2::InternetGateway",
            "Properties": {
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "AttachGateway": {
            "Type": "AWS::EC2::VPCGatewayAttachment",
            "Properties": {
                "VpcId": {
                    "Ref": "myvpc"
                },
                "InternetGatewayId": {
                    "Ref": "myigw"
                }
            }
        },
        "myrt": {
            "Type": "AWS::EC2::RouteTable",
            "Properties": {
                "VpcId": {
                    "Ref": "myvpc"
                },
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "igwroute": {
            "Type": "AWS::EC2::Route",
            "Properties": {
                "RouteTableId": {
                    "Ref": "myrt"
                },
                "DestinationCidrBlock": "0.0.0.0/0",
                "GatewayId": {
                    "Ref": "myigw"
                }
            }
        }
    }
}

Preview

  • Lets add route table associations with subnets as mentioned above
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "This is my first cf template",
    "Parameters": {
        "subnet1az": {
            "Description": "Enter subnet1 az",
            "Type": "AWS::EC2::AvailabilityZone::Name"
        },
        "subnet2az": {
            "Description": "Enter subnet1 az",
            "Type": "AWS::EC2::AvailabilityZone::Name"
        },
        "subnet3az": {
            "Description": "Enter subnet1 az",
            "Type": "AWS::EC2::AvailabilityZone::Name"
        }
    },
    "Resources": {
        "myvpc": {
            "Type": "AWS::EC2::VPC",
            "Properties": {
                "CidrBlock": "10.1.0.0/16",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet1": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet1az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.0.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet2": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet2az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.1.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "mysubnet3": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Ref": "subnet3az"
                },
                "VpcId": {
                    "Ref": "myvpc"
                },
                "CidrBlock": "10.1.2.0/24",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "myigw": {
            "Type": "AWS::EC2::InternetGateway",
            "Properties": {
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "AttachGateway": {
            "Type": "AWS::EC2::VPCGatewayAttachment",
            "Properties": {
                "VpcId": {
                    "Ref": "myvpc"
                },
                "InternetGatewayId": {
                    "Ref": "myigw"
                }
            }
        },
        "myrt": {
            "Type": "AWS::EC2::RouteTable",
            "Properties": {
                "VpcId": {
                    "Ref": "myvpc"
                },
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "From VsCode"
                    }
                ]
            }
        },
        "igwroute": {
            "Type": "AWS::EC2::Route",
            "Properties": {
                "RouteTableId": {
                    "Ref": "myrt"
                },
                "DestinationCidrBlock": "0.0.0.0/0",
                "GatewayId": {
                    "Ref": "myigw"
                }
            }
        },
        "subnet1rt": {
            "Type": "AWS::EC2::SubnetRouteTableAssociation",
            "Properties": {
                "SubnetId": {
                    "Ref": "mysubnet1"
                },
                "RouteTableId": {
                    "Ref": "myrt"
                }
            }
        },
        "subnet2rt": {
            "Type": "AWS::EC2::SubnetRouteTableAssociation",
            "Properties": {
                "SubnetId": {
                    "Ref": "mysubnet2"
                },
                "RouteTableId": {
                    "Ref": "myrt"
                }
            }
        },
        "mysubnet3rt": {
            "Type": "AWS::EC2::SubnetRouteTableAssociation",
            "Properties": {
                "SubnetId": {
                    "Ref": "mysubnet3"
                },
                "RouteTableId": {
                    "Ref": "myrt"
                }
            }
        }
    }
}

By continuous learner

devops & cloud enthusiastic learner

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Please turn AdBlock off
Customized Social Media Icons from Acurax Digital Marketing Agency

Discover more from Direct DevOps from Quality Thought

Subscribe now to keep reading and get access to the full archive.

Continue reading

Visit Us On FacebookVisit Us On LinkedinVisit Us On Youtube