Streamlining AWS Infrastructure Setup with CloudFormation: A Step-by-Step Guide

Streamlining AWS Infrastructure Setup with CloudFormation: A Step-by-Step Guide

Are you tired of manually configuring your AWS infrastructure every time you start a new project? Discover how you can automate the setup process using CloudFormation templates. In this article, I'll walk you through creating a YAML template for setting up a Virtual Private Cloud (VPC), public subnets, and security groups. Streamline your AWS workflow and save time with this efficient approach.


Introduction:

Setting up AWS infrastructure can be time-consuming, especially when you have to repeat the process for multiple projects. Fortunately, AWS CloudFormation offers a solution to automate this process using infrastructure as code. In this article, I'll demonstrate how to create a CloudFormation YAML template for provisioning a VPC, public subnets, Internet Gateway, Route Table, NACLs, and security groups.


Here is the cloudformation template for creating a custom VPC, with two public subnets, an Internet Gateway, a public route table, an NACL, a security group for EC2, and a security group for the Application Load Balancer.

AWSTemplateFormatVersion: '2010-09-09'
Description: Create a VPC with two public subnets with an internet gateway, a public route table, and a security group

Parameters:
  DeploymentBucket:
    Description: Name of the deployment bucket
    Type: String
    Default: YOUR_BUCKET_NAME
  VpcCidr:
    Type: String
    Default: 10.0.0.0/16
    Description: CIDR block for VPC
  PublicSubnet1Cidr:
    Type: String
    Default: 10.0.0.0/24
    Description: CIDR block for public subnet 1
  PublicSubnet2Cidr:
    Type: String
    Default: 10.0.1.0/24
    Description: CIDR block for public subnet 2
  EnvironmentName:
    Description: Name of the environment
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - prod 
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      EnableDnsHostnames: 'true'
      EnableDnsSupport: 'true'
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-VPC
        - Key: Environment
          Value: !Ref EnvironmentName
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PublicSubnet1Cidr
      AvailabilityZone: !Select [ 0, !GetAZs ]
      MapPublicIpOnLaunch: 'true'
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-PublicSubnet1
        - Key: Environment
          Value: !Ref EnvironmentName
  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PublicSubnet2Cidr
      AvailabilityZone: !Select [ 1, !GetAZs ]
      MapPublicIpOnLaunch: 'true'
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-PublicSubnet2
        - Key: Environment
          Value: !Ref EnvironmentName
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-InternetGateway
        - Key: Environment
          Value: !Ref EnvironmentName
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-PublicRouteTable
        - Key: Environment
          Value: !Ref EnvironmentName
  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachGateway
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable
  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable
  PublicNetworkAcl:
    Type: AWS::EC2::NetworkAcl
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-PublicNetworkAcl
        - Key: Environment
          Value: !Ref EnvironmentName
  InboundHTTPPublicNetworkAclEntry:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref PublicNetworkAcl
      RuleNumber: '100'
      Protocol: '6'
      RuleAction: allow
      Egress: 'false'
      CidrBlock: '0.0.0.0/0'
      PortRange:
        From: '80'
        To: '80'
  InboundHTTPSPublicNetworkAclEntry:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref PublicNetworkAcl
      RuleNumber: '101'
      Protocol: '6'
      RuleAction: allow
      Egress: 'false'
      CidrBlock: '0.0.0.0/0'
      PortRange:
        From: '443'
        To: '443'
  InboundEmphemeralPublicNetworkAclEntry:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref PublicNetworkAcl
      RuleNumber: '102'
      Protocol: '6'
      RuleAction: allow
      Egress: 'false'
      CidrBlock: '0.0.0.0/0'
      PortRange:
        From: '1024'
        To: '65535'
  OutboundHTTPPublicNetworkAclEntry:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref PublicNetworkAcl
      RuleNumber: '100'
      Protocol: '6'
      RuleAction: allow
      Egress: 'true'
      CidrBlock: '0.0.0.0/0'
      PortRange:
        From: '80'
        To: '80'
  OutboundHTTPSPublicNetworkAclEntry:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref PublicNetworkAcl
      RuleNumber: '101'
      Protocol: '6'
      RuleAction: allow
      Egress: 'true'
      CidrBlock: '0.0.0.0/0'
      PortRange:
        From: '443'
        To: '443'
  OutboundEmphemeralPublicNetworkAclEntry:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref PublicNetworkAcl
      RuleNumber: '102'
      Protocol: '6'
      RuleAction: allow
      Egress: 'true'
      CidrBlock: '0.0.0.0/0'
      PortRange:
        From: '1024'
        To: '65535'
  PublicSubnet1NetworkAclAssociation:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      NetworkAclId: !Ref PublicNetworkAcl
  PublicSubnet2NetworkAclAssociation:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      NetworkAclId: !Ref PublicNetworkAcl
  ALBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub ${EnvironmentName}-ALBSecurityGroup
      GroupDescription: Allow HTTP inbound traffic from anywhere.
      VpcId: !Ref VPC
      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
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-ALBSecurityGroup
        - Key: Environment
          Value: !Ref EnvironmentName 
  EC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub ${EnvironmentName}-EC2SecurityGroup
      GroupDescription: Allow HTTP and HTTPS inbound and outbound traffic from anywhere.
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          SourceSecurityGroupId: !Ref ALBSecurityGroup
        - IpProtocol: tcp
          FromPort: '443'
          ToPort: '443'
          SourceSecurityGroupId: !Ref ALBSecurityGroup
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-EC2SecurityGroup
        - Key: Environment
          Value: !Ref EnvironmentName
  
Outputs:
  AccountId:
    Description: AWS Account ID
    Value: !Ref AWS::AccountId
  RegionName:
    Description: AWS Region Name
    Value: !Ref AWS::Region
  StackId:
    Description: Current Stack ID
    Value: !Ref AWS::StackId
  StackName:
    Description: Current Stack Name
    Value: !Ref AWS::StackName
  Environment:
    Description: Environment name
    Value: !Ref EnvironmentName
    Export:
      Name: !Sub ${EnvironmentName}-environment-name
  DeploymentBucket:
    Description: Deployment bucket
    Value: !Ref DeploymentBucket
    Export:
      Name: !Sub ${EnvironmentName}-deployment-bucket
  VpcId:
    Description: VPC ID
    Value: !Ref VPC
    Export:
      Name: !Sub ${EnvironmentName}-vpc-id
  PublicSubnet1Id:
    Description: Public subnet 1 ID
    Value: !Ref PublicSubnet1
    Export:
      Name: !Sub ${EnvironmentName}-public-subnet1-id
  PublicSubnet2Id:
    Description: Public subnet 2 ID
    Value: !Ref PublicSubnet2
    Export:
      Name: !Sub ${EnvironmentName}-public-subnet2-id
  EC2SecurityGroupId:
    Description: EC2 security group ID
    Value: !Ref EC2SecurityGroup
    Export:
      Name: !Sub ${EnvironmentName}-ec2-security-group-id
  ALBSecurityGroupId:
    Description: ALB security group ID
    Value: !Ref ALBSecurityGroup
    Export:
      Name: !Sub ${EnvironmentName}-alb-security-group-id        


Step 1: Create a private S3 bucket for the deployment

aws s3api create-bucket --bucket <YOUR_BUCKET_NAME> \
--region us-east-1        

Step 2: Upload the template file to the s3

aws s3 cp /path/to/template/file/vpc.yaml \ s3://YOUR_BUCKET_NAME/templates/vpc.yaml        

Step 3: Create a vpc stack

aws cloudformation create-stack --stack-name vpc --template-url https://YOUR_BUCKET_NAME.s3.amazonaws.com/templates/vpc.yaml \
--parameters \ ParameterKey=DeploymentBucket,ParameterValue=YOUR_BUCKET_NAME \
--region us-east-1        

Step 4: Check the status of the stack

aws cloudformation describe-stacks --stack-name vpc \
--query "Stacks[0].StackStatus" --output text --region us-east-1        

Step 4: Check all the outputs of the stack (When the stack is created successfully)

aws cloudformation describe-stacks --stack-name vpc \
--query "Stacks[0].Outputs" --output table --region us-east-1        


Sandeep Sasikumar

Senior DevOps Engineer at Zyxware Technologies

9 个月

Cloudformation templates is something powerful to automate the whole infrastructure kick start process

要查看或添加评论,请登录

社区洞察

其他会员也浏览了