DAY7 -IaC

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MyrinNew
    Senior Member
    • Feb 2024
    • 5175

    #1

    DAY7 -IaC

    Overview

    Today, I’ll build a basic VPC baseline, the same as Day1, using CloudFormation. CloudFormation makes it easier to create and update resources.

    I'll deploy two CloudFormation stacks to learn cross-stack references. The network stack contains network resources (VPC, subnets, IGW...) and the app stack contains app resources (EC2, SG...).





    Hands-on

    1. Create YAML templates

    Create two YAML files using the templates below.



    "day7-network.yaml"






    AWSTemplateFormatVersion: '2010-09-09'
    Description: Day7 Network Stack - VPC baseline with Exports (2AZ public/private, IGW, S3 Gateway Endpoint)

    # Create Variables
    Parameters:
    VpcCidr:
    Type: String
    Default: 10.0.0.0/16
    Az1:
    Type: AWS::EC2::AvailabilityZone::Name
    Az2:
    Type: AWS::EC2::AvailabilityZone::Name

    Resources:
    VPC:
    Type: AWS::EC2::VPC
    Properties:
    CidrBlock: !Ref VpcCidr
    EnableDnsSupport: true
    EnableDnsHostnames: true
    Tags:
    - Key: Name
    Value: hs-day7-vpc

    IGW:
    Type: AWS::EC2::InternetGateway
    Properties:
    Tags:
    - Key: Name
    Value: hs-day7-igw

    AttachIgw:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
    VpcId: !Ref VPC
    InternetGatewayId: !Ref IGW

    PublicSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
    VpcId: !Ref VPC
    AvailabilityZone: !Ref Az1
    CidrBlock: 10.0.0.0/24
    MapPublicIpOnLaunch: true
    Tags:
    - Key: Name
    Value: hs-day7-public-a

    PublicSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
    VpcId: !Ref VPC
    AvailabilityZone: !Ref Az2
    CidrBlock: 10.0.1.0/24
    MapPublicIpOnLaunch: true
    Tags:
    - Key: Name
    Value: hs-day7-public-b

    PublicRT:
    Type: AWS::EC2::RouteTable
    Properties:
    VpcId: !Ref VPC
    Tags:
    - Key: Name
    Value: hs-day7-rt-public

    PublicRouteDefault:
    Type: AWS::EC2::Route
    DependsOn: AttachIgw
    Properties:
    RouteTableId: !Ref PublicRT
    DestinationCidrBlock: 0.0.0.0/0
    GatewayId: !Ref IGW

    AssocPublicA:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
    SubnetId: !Ref PublicSubnetA
    RouteTableId: !Ref PublicRT

    AssocPublicB:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
    SubnetId: !Ref PublicSubnetB
    RouteTableId: !Ref PublicRT

    # Output resource information for reference from the stack
    Outputs:
    VpcId:
    Value: !Ref VPC
    Export:
    Name: !Sub "${AWS::StackName}-VpcId"

    PublicSubnetAId:
    Value: !Ref PublicSubnetA
    Export:
    Name: !Sub "${AWS::StackName}-PublicSubnetAId"

    PublicSubnetBId:
    Value: !Ref PublicSubnetB
    Export:
    Name: !Sub "${AWS::StackName}-PublicSubnetBId"

    PublicRouteTableId:
    Value: !Ref PublicRT
    Export:
    Name: !Sub "${AWS::StackName}-PublicRouteTableId"














    "day7-app.yaml"






    AWSTemplateFormatVersion: '2010-09-09'
    Description: Day7 App Stack - Create EC2 in imported VPC/Subnet (SSM enabled)

    Parameters:
    NetworkStackName:
    Type: String
    Description: Name of the Network stack that exports VPC/Subnets (e.g., hs-day7-network)
    InstanceType:
    Type: String
    Default: t3.micro

    Resources:
    Ec2Role:
    Type: AWS::IAM::Role
    Properties:
    RoleName: !Sub "hs-day7-ec2-ssm-role-${AWS::StackName}"
    AssumeRolePolicyDocument:
    Version: '2012-10-17'
    Statement:
    - Effect: Allow
    Principal:
    Service: ec2.amazonaws.com
    Action: sts:AssumeRole
    ManagedPolicyArns:
    - arn:aws:iam::awsolicy/AmazonSSMManagedInstanceCore

    Ec2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
    Roles:
    - !Ref Ec2Role

    # Create SG for EC2 instance using VPC ID imported by the network stack
    Ec2Sg:
    Type: AWS::EC2::SecurityGroup
    Properties:
    GroupDescription: hs-day7-ec2-sg (no inbound, all outbound)
    VpcId: !ImportValue
    Fn::Sub: "${NetworkStackName}-VpcId"
    SecurityGroupEgress:
    - IpProtocol: -1
    CidrIp: 0.0.0.0/0

    # Create an EC2 instance using subnet ID imported by the network stack
    Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
    ImageId: !Sub "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64}}"
    InstanceType: !Ref InstanceType
    IamInstanceProfile: !Ref Ec2InstanceProfile
    SubnetId: !ImportValue
    Fn::Sub: "${NetworkStackName}-PublicSubnetAId"
    SecurityGroupIds:
    - !Ref Ec2Sg
    Tags:
    - Key: Name
    Value: hs-day7-app-ec2

    # Output the instance id to review the instance.
    Outputs:
    InstanceId:
    Value: !Ref Ec2Instance












    2. Create CloudFormation stack

    1. Network stack

    CloudFormation → Create stack


    Upload "day7-network.yaml".





    Choose two Availability Zones (AZs).





    You can review the resources created by this stack in the "Resources" tab. (Network resources like VPC, subnets, IGW...)





    2. App stack

    CloudFormation → Create stack


    Upload "day7-app.yaml".

    NetworkStackName = the network stack name created in the previous step.








    You can review the resources created by this stack in the "Resources" tab. (App resources like EC2, SG, IAMrole...)





    3. Functionality Verification

    Systems Manager → Session Manager → Start session

    If you can start a Session Manager session to the EC2 instance, you’ve successfully created both stacks.





    Update "day7-app.yaml" to add a tag to the EC2 instance.

    ※"Environment : dev" tag!






    "day7-app.yaml"






    AWSTemplateFormatVersion: '2010-09-09'
    Description: Day7 App Stack - Create EC2 in imported VPC/Subnet (SSM enabled)

    Parameters:
    NetworkStackName:
    Type: String
    Description: Name of the Network stack that exports VPC/Subnets (e.g., hs-day7-network)
    InstanceType:
    Type: String
    Default: t3.micro

    Resources:
    Ec2Role:
    Type: AWS::IAM::Role
    Properties:
    RoleName: !Sub "hs-day7-ec2-ssm-role-${AWS::StackName}"
    AssumeRolePolicyDocument:
    Version: '2012-10-17'
    Statement:
    - Effect: Allow
    Principal:
    Service: ec2.amazonaws.com
    Action: sts:AssumeRole
    ManagedPolicyArns:
    - arn:aws:iam::awsolicy/AmazonSSMManagedInstanceCore

    Ec2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
    Roles:
    - !Ref Ec2Role

    # Create SG for EC2 instance using VPC ID imported by the network stack
    Ec2Sg:
    Type: AWS::EC2::SecurityGroup
    Properties:
    GroupDescription: hs-day7-ec2-sg (no inbound, all outbound)
    VpcId: !ImportValue
    Fn::Sub: "${NetworkStackName}-VpcId"
    SecurityGroupEgress:
    - IpProtocol: -1
    CidrIp: 0.0.0.0/0

    # Create an EC2 instance using subnet ID imported by the network stack
    Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
    ImageId: !Sub "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64}}"
    InstanceType: !Ref InstanceType
    IamInstanceProfile: !Ref Ec2InstanceProfile
    SubnetId: !ImportValue
    Fn::Sub: "${NetworkStackName}-PublicSubnetAId"
    SecurityGroupIds:
    - !Ref Ec2Sg
    Tags:
    - Key: Name
    Value: hs-day7-app-ec2
    - Key: Environment
    Value: dev

    # Output the instance id to review the instance.
    Outputs:
    InstanceId:
    Value: !Ref Ec2Instance












    CloudFormation → Stacks → the app stack → Create a change set → Update stack → Replace template → Create change set





    You can review the differences in the "Resource changes" tab.

    ※In this time, there are differences with tag settings.

    Execute change set.








    Execute change set, and the tag is added.





    Tidying up

    • Delete the app stack
    • Delete the network stack


    For test

    Key exam points related to today's services.


    CloudFormation

    • Cross-stack references: export values from one stack (Outputs/Export) and import them in another stack (ImportValue). Export names must be unique within the same account and region.
    • Change set is used when you change the template. Depending on the changes made, either in-place update or replacement are performed. (※In case of replacement, the resource is recreated. Some parameters like EC2 instance ID are changed.)


    It's a last hands-on lab, see you soon in the Day8!

    I'll summarize the key points of the services not covered in hands-on sessions.




    More...
Working...