0
0

「AWS Hands-on for Beginners AWS 環境のコード管理 AWS CloudFormationで Web システムを構築する」をAWS CLIでやってみる

Posted at

上記、「AWS Hands-on for Beginners AWS 環境のコード管理 AWS CloudFormationで Web システムを構築する」 をAWS CLIでやってみる

image.png
ハンズオンから引用

03 開発環境の構築 (CloudShellで実施)

ハンズオンではCloud9から実施するようになっているが、すべてCloudShellから実施することも可

変数

コマンド
# 名前
CLOUD9_ENVIRONMENT_NAME="handson" \
&& echo ${CLOUD9_ENVIRONMENT_NAME}

# 説明
CLOUD9_DSCTRIPTION="handson" \
&& echo ${CLOUD9_DSCTRIPTION}

# インスタンスタイプ
CLOUD9_INSTANCE_TYPE="t2.micro" \
&& echo ${CLOUD9_INSTANCE_TYPE}

# プラットフォーム
CLOUD9_IMAGE_ID="resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64" \
&& echo ${CLOUD9_IMAGE_ID}
出力
[cloudshell-user@ip-10-134-14-43 ~]$ # Cloud9
[cloudshell-user@ip-10-134-14-43 ~]$ # 名前
[cloudshell-user@ip-10-134-14-43 ~]$ CLOUD9_ENVIRONMENT_NAME="handson" \
> && echo ${CLOUD9_ENVIRONMENT_NAME}
handson
[cloudshell-user@ip-10-134-14-43 ~]$ 
[cloudshell-user@ip-10-134-14-43 ~]$ # 説明
[cloudshell-user@ip-10-134-14-43 ~]$ CLOUD9_DSCTRIPTION="handson" \
> && echo ${CLOUD9_DSCTRIPTION}
handson
[cloudshell-user@ip-10-134-14-43 ~]$ 
[cloudshell-user@ip-10-134-14-43 ~]$ # インスタンスタイプ
[cloudshell-user@ip-10-134-14-43 ~]$ CLOUD9_INSTANCE_TYPE="t2.micro" \
> && echo ${CLOUD9_INSTANCE_TYPE}
t2.micro
[cloudshell-user@ip-10-134-14-43 ~]$ 
[cloudshell-user@ip-10-134-14-43 ~]$ # プラットフォーム
[cloudshell-user@ip-10-134-14-43 ~]$ CLOUD9_IMAGE_ID="resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64" \
> && echo ${CLOUD9_IMAGE_ID}
resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64

環境作成

コマンド
# Cloud9環境作成
CLOUD9_ENVIRONMENT_ID=$(
    aws cloud9 create-environment-ec2 \
        --name ${CLOUD9_ENVIRONMENT_NAME} \
        --description ${CLOUD9_DSCTRIPTION} \
        --instance-type ${CLOUD9_INSTANCE_TYPE} \
        --image-id ${CLOUD9_IMAGE_ID} \
        --connection-type CONNECT_SSM \
        --automatic-stop-time-minutes 30 \
        --query environmentId \
        --output text
) \
&& echo ${CLOUD9_ENVIRONMENT_ID}
出力
[cloudshell-user@ip-10-134-14-43 ~]$ # Cloud9環境作成
[cloudshell-user@ip-10-134-14-43 ~]$ CLOUD9_ENVIRONMENT_ID=$(
>     aws cloud9 create-environment-ec2 \
>         --name ${CLOUD9_ENVIRONMENT_NAME} \
>         --description ${CLOUD9_DSCTRIPTION} \
>         --instance-type ${CLOUD9_INSTANCE_TYPE} \
>         --image-id ${CLOUD9_IMAGE_ID} \
>         --connection-type CONNECT_SSM \
>         --automatic-stop-time-minutes 30 \
>         --query environmentId \
>         --output text
> ) \
> && echo ${CLOUD9_ENVIRONMENT_ID}
9295554b15a245ac9bd32be3a214dc92

04 テンプレートの実行方法、VPCの作成 (Cloud9で実施)

作業用ディレクトリ作成

コマンド
mkdir cfn
出力
admin:~/environment $ mkdir cfn

変数

コマンド
# スタック名
STACK_NAME="handson-cfn" \
&& echo ${STACK_NAME}

# テンプレートファイル
CFN_TEMPLATE="01_vpc.yml" \
&& echo ${CFN_TEMPLATE}
出力
admin:~/environment $ # スタック名
admin:~/environment $ STACK_NAME="handson-cfn" \
> && echo ${STACK_NAME}
handson-cfn
admin:~/environment $ 
admin:~/environment $ # テンプレートファイル
admin:~/environment $ CFN_TEMPLATE="01_vpc.yml" \
> && echo ${CFN_TEMPLATE}
01_vpc.yml

YAMLファイル作成

コマンド
cat << "EOF" > cfn/${CFN_TEMPLATE}
AWSTemplateFormatVersion: 2010-09-09
Description: Hands-on template for VPC

Resources:
  CFnVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      InstanceTenancy: default
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: handson-cfn

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.0.0/24
      VpcId: !Ref CFnVPC
      AvailabilityZone: !Select [ 0, !GetAZs ]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet1

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.1.0/24
      VpcId: !Ref CFnVPC
      AvailabilityZone: !Select [ 1, !GetAZs ]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet2

  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.2.0/24
      VpcId: !Ref CFnVPC
      AvailabilityZone: !Select [ 0, !GetAZs ]
      Tags:
        - Key: Name
          Value: PrivateSubnet1

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.3.0/24
      VpcId: !Ref CFnVPC
      AvailabilityZone: !Select [ 1, !GetAZs ]
      Tags:
        - Key: Name
          Value: PrivateSubnet2

  CFnVPCIGW:
    Type: AWS::EC2::InternetGateway
    Properties: 
      Tags:
        - Key: Name
          Value: handson-cfn

  CFnVPCIGWAttach:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties: 
      InternetGatewayId: !Ref CFnVPCIGW
      VpcId: !Ref CFnVPC

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref CFnVPC
      Tags:
        - Key: Name
          Value: Public Route

  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: CFnVPCIGW
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref CFnVPCIGW

  PublicSubnet1Association:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  PublicSubnet2Association:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

Outputs:
  VPCID:
    Description: VPC ID
    Value: !Ref CFnVPC
    Export:
      Name: !Sub ${AWS::StackName}-VPCID

  PublicSubnet1:
    Description: PublicSubnet1
    Value: !Ref PublicSubnet1
    Export:
      Name: !Sub ${AWS::StackName}-PublicSubnet1

  PublicSubnet2:
    Description: PublicSubnet2
    Value: !Ref PublicSubnet2
    Export:
      Name: !Sub ${AWS::StackName}-PublicSubnet2

  PrivateSubnet1:
    Description: PrivateSubnet1
    Value: !Ref PrivateSubnet1
    Export:
      Name: !Sub ${AWS::StackName}-PrivateSubnet1

  PrivateSubnet2:
    Description: PrivateSubnet2
    Value: !Ref PrivateSubnet2
    Export:
      Name: !Sub ${AWS::StackName}-PrivateSubnet2
EOF
出力
admin:~/environment $ cat << "EOF" > cfn/${CFN_TEMPLATE}
> AWSTemplateFormatVersion: 2010-09-09
> Description: Hands-on template for VPC
> 
> Resources:
>   CFnVPC:
>     Type: AWS::EC2::VPC
>     Properties:
>       CidrBlock: 10.0.0.0/16
>       InstanceTenancy: default
>       EnableDnsSupport: true
>       EnableDnsHostnames: true
>       Tags:
>         - Key: Name
>           Value: handson-cfn
> 
>   PublicSubnet1:
>     Type: AWS::EC2::Subnet
>     Properties:
>       CidrBlock: 10.0.0.0/24
>       VpcId: !Ref CFnVPC
>       AvailabilityZone: !Select [ 0, !GetAZs ]
>       MapPublicIpOnLaunch: true
>       Tags:
>         - Key: Name
>           Value: PublicSubnet1
> 
>   PublicSubnet2:
>     Type: AWS::EC2::Subnet
>     Properties:
>       CidrBlock: 10.0.1.0/24
>       VpcId: !Ref CFnVPC
>       AvailabilityZone: !Select [ 1, !GetAZs ]
>       MapPublicIpOnLaunch: true
>       Tags:
>         - Key: Name
>           Value: PublicSubnet2
> 
>   PrivateSubnet1:
>     Type: AWS::EC2::Subnet
>     Properties:
>       CidrBlock: 10.0.2.0/24
>       VpcId: !Ref CFnVPC
>       AvailabilityZone: !Select [ 0, !GetAZs ]
>       Tags:
>         - Key: Name
>           Value: PrivateSubnet1
> 
>   PrivateSubnet2:
>     Type: AWS::EC2::Subnet
>     Properties:
>       CidrBlock: 10.0.3.0/24
>       VpcId: !Ref CFnVPC
>       AvailabilityZone: !Select [ 1, !GetAZs ]
>       Tags:
>         - Key: Name
>           Value: PrivateSubnet2
> 
>   CFnVPCIGW:
>     Type: AWS::EC2::InternetGateway
>     Properties: 
>       Tags:
>         - Key: Name
>           Value: handson-cfn
> 
>   CFnVPCIGWAttach:
>     Type: AWS::EC2::VPCGatewayAttachment
>     Properties: 
>       InternetGatewayId: !Ref CFnVPCIGW
>       VpcId: !Ref CFnVPC
> 
>   PublicRouteTable:
>     Type: AWS::EC2::RouteTable
>     Properties:
>       VpcId: !Ref CFnVPC
>       Tags:
>         - Key: Name
>           Value: Public Route
> 
>   PublicRoute:
>     Type: AWS::EC2::Route
>     DependsOn: CFnVPCIGW
>     Properties:
>       RouteTableId: !Ref PublicRouteTable
>       DestinationCidrBlock: 0.0.0.0/0
>       GatewayId: !Ref CFnVPCIGW
> 
>   PublicSubnet1Association:
>     Type: AWS::EC2::SubnetRouteTableAssociation
>     Properties:
>       SubnetId: !Ref PublicSubnet1
>       RouteTableId: !Ref PublicRouteTable
> 
>   PublicSubnet2Association:
>     Type: AWS::EC2::SubnetRouteTableAssociation
>     Properties:
>       SubnetId: !Ref PublicSubnet2
>       RouteTableId: !Ref PublicRouteTable
> 
> Outputs:
>   VPCID:
>     Description: VPC ID
>     Value: !Ref CFnVPC
>     Export:
>       Name: !Sub ${AWS::StackName}-VPCID
> 
>   PublicSubnet1:
>     Description: PublicSubnet1
>     Value: !Ref PublicSubnet1
>     Export:
>       Name: !Sub ${AWS::StackName}-PublicSubnet1
> 
>   PublicSubnet2:
>     Description: PublicSubnet2
>     Value: !Ref PublicSubnet2
>     Export:
>       Name: !Sub ${AWS::StackName}-PublicSubnet2
> 
>   PrivateSubnet1:
>     Description: PrivateSubnet1
>     Value: !Ref PrivateSubnet1
>     Export:
>       Name: !Sub ${AWS::StackName}-PrivateSubnet1
> 
>   PrivateSubnet2:
>     Description: PrivateSubnet2
>     Value: !Ref PrivateSubnet2
>     Export:
>       Name: !Sub ${AWS::StackName}-PrivateSubnet2
> EOF

スタック作成

コマンド
# create
aws cloudformation create-stack \
    --stack-name ${STACK_NAME} \
    --template-body file://cfn/${CFN_TEMPLATE}
出力
admin:~/environment $ # create
admin:~/environment $ aws cloudformation create-stack \
>     --stack-name ${STACK_NAME} \
>     --template-body file://cfn/${CFN_TEMPLATE}
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5"
}

リソース一覧確認

コマンド
aws cloudformation describe-stack-resources \
    --stack-name ${STACK_NAME} \
    --no-cli-pager
出力
admin:~/environment $ aws cloudformation describe-stack-resources \
>     --stack-name ${STACK_NAME} \
>     --no-cli-pager
{
    "StackResources": [
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "CFnVPC",
            "PhysicalResourceId": "vpc-00e1f8bcfca58ffdf",
            "ResourceType": "AWS::EC2::VPC",
            "Timestamp": "2024-08-10T12:17:54.152000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "CFnVPCIGW",
            "PhysicalResourceId": "igw-0cdd448e3deff017a",
            "ResourceType": "AWS::EC2::InternetGateway",
            "Timestamp": "2024-08-10T12:17:58.166000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "CFnVPCIGWAttach",
            "PhysicalResourceId": "IGW|vpc-00e1f8bcfca58ffdf",
            "ResourceType": "AWS::EC2::VPCGatewayAttachment",
            "Timestamp": "2024-08-10T12:17:57.375000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PrivateSubnet1",
            "PhysicalResourceId": "subnet-07d92abad18918935",
            "ResourceType": "AWS::EC2::Subnet",
            "Timestamp": "2024-08-10T12:17:59.251000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PrivateSubnet2",
            "PhysicalResourceId": "subnet-0b6ceb531c69a539c",
            "ResourceType": "AWS::EC2::Subnet",
            "Timestamp": "2024-08-10T12:17:59.224000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PublicRoute",
            "PhysicalResourceId": "rtb-09f7f89c25efc069b|0.0.0.0/0",
            "ResourceType": "AWS::EC2::Route",
            "Timestamp": "2024-08-10T12:18:08.486000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PublicRouteTable",
            "PhysicalResourceId": "rtb-09f7f89c25efc069b",
            "ResourceType": "AWS::EC2::RouteTable",
            "Timestamp": "2024-08-10T12:18:06.232000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PublicSubnet1",
            "PhysicalResourceId": "subnet-036055bb9649baeab",
            "ResourceType": "AWS::EC2::Subnet",
            "Timestamp": "2024-08-10T12:17:59.577000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PublicSubnet1Association",
            "PhysicalResourceId": "rtbassoc-069fad9a7cdfc8159",
            "ResourceType": "AWS::EC2::SubnetRouteTableAssociation",
            "Timestamp": "2024-08-10T12:18:01.753000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PublicSubnet2",
            "PhysicalResourceId": "subnet-02d1e69375b6cbbb3",
            "ResourceType": "AWS::EC2::Subnet",
            "Timestamp": "2024-08-10T12:17:59.574000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PublicSubnet2Association",
            "PhysicalResourceId": "rtbassoc-0590898ae9be96824",
            "ResourceType": "AWS::EC2::SubnetRouteTableAssociation",
            "Timestamp": "2024-08-10T12:18:01.759000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

YAMLファイルの更新 (PublicSubnet1名変更)

コマンド
cat << "EOF" > cfn/${CFN_TEMPLATE}
AWSTemplateFormatVersion: 2010-09-09
Description: Hands-on template for VPC

Resources:
  CFnVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      InstanceTenancy: default
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: handson-cfn

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.0.0/24
      VpcId: !Ref CFnVPC
      AvailabilityZone: !Select [ 0, !GetAZs ]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet1-update

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.1.0/24
      VpcId: !Ref CFnVPC
      AvailabilityZone: !Select [ 1, !GetAZs ]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet2

  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.2.0/24
      VpcId: !Ref CFnVPC
      AvailabilityZone: !Select [ 0, !GetAZs ]
      Tags:
        - Key: Name
          Value: PrivateSubnet1

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.3.0/24
      VpcId: !Ref CFnVPC
      AvailabilityZone: !Select [ 1, !GetAZs ]
      Tags:
        - Key: Name
          Value: PrivateSubnet2

  CFnVPCIGW:
    Type: AWS::EC2::InternetGateway
    Properties: 
      Tags:
        - Key: Name
          Value: handson-cfn

  CFnVPCIGWAttach:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties: 
      InternetGatewayId: !Ref CFnVPCIGW
      VpcId: !Ref CFnVPC

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref CFnVPC
      Tags:
        - Key: Name
          Value: Public Route

  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: CFnVPCIGW
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref CFnVPCIGW

  PublicSubnet1Association:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  PublicSubnet2Association:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

Outputs:
  VPCID:
    Description: VPC ID
    Value: !Ref CFnVPC
    Export:
      Name: !Sub ${AWS::StackName}-VPCID

  PublicSubnet1:
    Description: PublicSubnet1
    Value: !Ref PublicSubnet1
    Export:
      Name: !Sub ${AWS::StackName}-PublicSubnet1

  PublicSubnet2:
    Description: PublicSubnet2
    Value: !Ref PublicSubnet2
    Export:
      Name: !Sub ${AWS::StackName}-PublicSubnet2

  PrivateSubnet1:
    Description: PrivateSubnet1
    Value: !Ref PrivateSubnet1
    Export:
      Name: !Sub ${AWS::StackName}-PrivateSubnet1

  PrivateSubnet2:
    Description: PrivateSubnet2
    Value: !Ref PrivateSubnet2
    Export:
      Name: !Sub ${AWS::StackName}-PrivateSubnet2
EOF
出力
admin:~/environment $ cat << "EOF" > cfn/${CFN_TEMPLATE}
> AWSTemplateFormatVersion: 2010-09-09
> Description: Hands-on template for VPC
> 
> Resources:
>   CFnVPC:
>     Type: AWS::EC2::VPC
>     Properties:
>       CidrBlock: 10.0.0.0/16
>       InstanceTenancy: default
>       EnableDnsSupport: true
>       EnableDnsHostnames: true
>       Tags:
>         - Key: Name
>           Value: handson-cfn
> 
>   PublicSubnet1:
>     Type: AWS::EC2::Subnet
>     Properties:
>       CidrBlock: 10.0.0.0/24
>       VpcId: !Ref CFnVPC
>       AvailabilityZone: !Select [ 0, !GetAZs ]
>       MapPublicIpOnLaunch: true
>       Tags:
>         - Key: Name
>           Value: PublicSubnet1-update
> 
>   PublicSubnet2:
>     Type: AWS::EC2::Subnet
>     Properties:
>       CidrBlock: 10.0.1.0/24
>       VpcId: !Ref CFnVPC
>       AvailabilityZone: !Select [ 1, !GetAZs ]
>       MapPublicIpOnLaunch: true
>       Tags:
>         - Key: Name
>           Value: PublicSubnet2
> 
>   PrivateSubnet1:
>     Type: AWS::EC2::Subnet
>     Properties:
>       CidrBlock: 10.0.2.0/24
>       VpcId: !Ref CFnVPC
>       AvailabilityZone: !Select [ 0, !GetAZs ]
>       Tags:
>         - Key: Name
>           Value: PrivateSubnet1
> 
>   PrivateSubnet2:
>     Type: AWS::EC2::Subnet
>     Properties:
>       CidrBlock: 10.0.3.0/24
>       VpcId: !Ref CFnVPC
>       AvailabilityZone: !Select [ 1, !GetAZs ]
>       Tags:
>         - Key: Name
>           Value: PrivateSubnet2
> 
>   CFnVPCIGW:
>     Type: AWS::EC2::InternetGateway
>     Properties: 
>       Tags:
>         - Key: Name
>           Value: handson-cfn
> 
>   CFnVPCIGWAttach:
>     Type: AWS::EC2::VPCGatewayAttachment
>     Properties: 
>       InternetGatewayId: !Ref CFnVPCIGW
>       VpcId: !Ref CFnVPC
> 
>   PublicRouteTable:
>     Type: AWS::EC2::RouteTable
>     Properties:
>       VpcId: !Ref CFnVPC
>       Tags:
>         - Key: Name
>           Value: Public Route
> 
>   PublicRoute:
>     Type: AWS::EC2::Route
>     DependsOn: CFnVPCIGW
>     Properties:
>       RouteTableId: !Ref PublicRouteTable
>       DestinationCidrBlock: 0.0.0.0/0
>       GatewayId: !Ref CFnVPCIGW
> 
>   PublicSubnet1Association:
>     Type: AWS::EC2::SubnetRouteTableAssociation
>     Properties:
>       SubnetId: !Ref PublicSubnet1
>       RouteTableId: !Ref PublicRouteTable
> 
>   PublicSubnet2Association:
>     Type: AWS::EC2::SubnetRouteTableAssociation
>     Properties:
>       SubnetId: !Ref PublicSubnet2
>       RouteTableId: !Ref PublicRouteTable
> 
> Outputs:
>   VPCID:
>     Description: VPC ID
>     Value: !Ref CFnVPC
>     Export:
>       Name: !Sub ${AWS::StackName}-VPCID
> 
>   PublicSubnet1:
>     Description: PublicSubnet1
>     Value: !Ref PublicSubnet1
>     Export:
>       Name: !Sub ${AWS::StackName}-PublicSubnet1
> 
>   PublicSubnet2:
>     Description: PublicSubnet2
>     Value: !Ref PublicSubnet2
>     Export:
>       Name: !Sub ${AWS::StackName}-PublicSubnet2
> 
>   PrivateSubnet1:
>     Description: PrivateSubnet1
>     Value: !Ref PrivateSubnet1
>     Export:
>       Name: !Sub ${AWS::StackName}-PrivateSubnet1
> 
>   PrivateSubnet2:
>     Description: PrivateSubnet2
>     Value: !Ref PrivateSubnet2
>     Export:
>       Name: !Sub ${AWS::StackName}-PrivateSubnet2
> EOF

スタックファイルの更新

コマンド
# validate
aws cloudformation validate-template \
    --template-body file://cfn/${CFN_TEMPLATE}

# update
aws cloudformation update-stack \
    --stack-name ${STACK_NAME} \
    --template-body file://cfn/${CFN_TEMPLATE}
出力
admin:~/environment $ # validate
admin:~/environment $ aws cloudformation validate-template \
>     --template-body file://cfn/${CFN_TEMPLATE}
{
    "Parameters": [],
    "Description": "Hands-on template for VPC"
}
admin:~/environment $ 
admin:~/environment $ # update
admin:~/environment $ aws cloudformation update-stack \
>     --stack-name ${STACK_NAME} \
>     --template-body file://cfn/${CFN_TEMPLATE}
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5"
}

リソース一覧確認

コマンド
aws cloudformation describe-stack-resources \
    --stack-name ${STACK_NAME} \
    --no-cli-pager
出力
admin:~/environment $ aws cloudformation describe-stack-resources \
>     --stack-name ${STACK_NAME} \
>     --no-cli-pager
{
    "StackResources": [
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "CFnVPC",
            "PhysicalResourceId": "vpc-00e1f8bcfca58ffdf",
            "ResourceType": "AWS::EC2::VPC",
            "Timestamp": "2024-08-10T12:17:54.152000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "CFnVPCIGW",
            "PhysicalResourceId": "igw-0cdd448e3deff017a",
            "ResourceType": "AWS::EC2::InternetGateway",
            "Timestamp": "2024-08-10T12:17:58.166000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "CFnVPCIGWAttach",
            "PhysicalResourceId": "IGW|vpc-00e1f8bcfca58ffdf",
            "ResourceType": "AWS::EC2::VPCGatewayAttachment",
            "Timestamp": "2024-08-10T12:17:57.375000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PrivateSubnet1",
            "PhysicalResourceId": "subnet-07d92abad18918935",
            "ResourceType": "AWS::EC2::Subnet",
            "Timestamp": "2024-08-10T12:17:59.251000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PrivateSubnet2",
            "PhysicalResourceId": "subnet-0b6ceb531c69a539c",
            "ResourceType": "AWS::EC2::Subnet",
            "Timestamp": "2024-08-10T12:17:59.224000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PublicRoute",
            "PhysicalResourceId": "rtb-09f7f89c25efc069b|0.0.0.0/0",
            "ResourceType": "AWS::EC2::Route",
            "Timestamp": "2024-08-10T12:18:08.486000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PublicRouteTable",
            "PhysicalResourceId": "rtb-09f7f89c25efc069b",
            "ResourceType": "AWS::EC2::RouteTable",
            "Timestamp": "2024-08-10T12:18:06.232000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PublicSubnet1",
            "PhysicalResourceId": "subnet-036055bb9649baeab",
            "ResourceType": "AWS::EC2::Subnet",
            "Timestamp": "2024-08-10T12:24:55.276000+00:00",
            "ResourceStatus": "UPDATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PublicSubnet1Association",
            "PhysicalResourceId": "rtbassoc-069fad9a7cdfc8159",
            "ResourceType": "AWS::EC2::SubnetRouteTableAssociation",
            "Timestamp": "2024-08-10T12:18:01.753000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PublicSubnet2",
            "PhysicalResourceId": "subnet-02d1e69375b6cbbb3",
            "ResourceType": "AWS::EC2::Subnet",
            "Timestamp": "2024-08-10T12:17:59.574000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "PublicSubnet2Association",
            "PhysicalResourceId": "rtbassoc-0590898ae9be96824",
            "ResourceType": "AWS::EC2::SubnetRouteTableAssociation",
            "Timestamp": "2024-08-10T12:18:01.759000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

スタック詳細

コマンド
aws cloudformation describe-stacks \
    --stack-name ${STACK_NAME} \
    --no-cli-pager
出力
admin:~/environment $ aws cloudformation describe-stacks \
>     --stack-name ${STACK_NAME} \
>     --no-cli-pager
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn/88de90d0-5712-11ef-8a6e-065519c9cca5",
            "StackName": "handson-cfn",
            "Description": "Hands-on template for VPC",
            "CreationTime": "2024-08-10T12:17:38.970000+00:00",
            "LastUpdatedTime": "2024-08-10T12:24:41.046000+00:00",
            "RollbackConfiguration": {},
            "StackStatus": "UPDATE_COMPLETE",
            "DisableRollback": false,
            "NotificationARNs": [],
            "Outputs": [
                {
                    "OutputKey": "PrivateSubnet1",
                    "OutputValue": "subnet-07d92abad18918935",
                    "Description": "PrivateSubnet1",
                    "ExportName": "handson-cfn-PrivateSubnet1"
                },
                {
                    "OutputKey": "PrivateSubnet2",
                    "OutputValue": "subnet-0b6ceb531c69a539c",
                    "Description": "PrivateSubnet2",
                    "ExportName": "handson-cfn-PrivateSubnet2"
                },
                {
                    "OutputKey": "VPCID",
                    "OutputValue": "vpc-00e1f8bcfca58ffdf",
                    "Description": "VPC ID",
                    "ExportName": "handson-cfn-VPCID"
                },
                {
                    "OutputKey": "PublicSubnet2",
                    "OutputValue": "subnet-02d1e69375b6cbbb3",
                    "Description": "PublicSubnet2",
                    "ExportName": "handson-cfn-PublicSubnet2"
                },
                {
                    "OutputKey": "PublicSubnet1",
                    "OutputValue": "subnet-036055bb9649baeab",
                    "Description": "PublicSubnet1",
                    "ExportName": "handson-cfn-PublicSubnet1"
                }
            ],
            "Tags": [],
            "EnableTerminationProtection": false,
            "DriftInformation": {
                "StackDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

05 EC2の作成 その1 (Cloud9で実施)

変数

コマンド
# スタック名
STACK_NAME_EC2="handson-cfn-ec2" \
&& echo ${STACK_NAME_EC2}

# テンプレートファイル
CFN_TEMPLATE="02_ec2.yml" \
&& echo ${CFN_TEMPLATE}
出力
admin:~/environment $ # スタック名
admin:~/environment $ STACK_NAME_EC2="handson-cfn-ec2" \
> && echo ${STACK_NAME_EC2}
handson-cfn-ec2
admin:~/environment $ 
admin:~/environment $ # テンプレートファイル
admin:~/environment $ CFN_TEMPLATE="02_ec2.yml" \
> && echo ${CFN_TEMPLATE}
02_ec2.yml

YAMLファイル作成

コマンド
cat << "EOF" > cfn/${CFN_TEMPLATE}
AWSTemplateFormatVersion: 2010-09-09
Description: Hands-on template for EC2

Parameters:
  VPCStack:
    Type: String
    Default: handson-cfn
  EC2AMI:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

Resources:
  EC2WebServer01:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref EC2AMI
      InstanceType: t2.micro

Outputs:
  EC2WebServer01:
    Value: !Ref EC2WebServer01
    Export:
      Name: !Sub ${AWS::StackName}-EC2WebServer01
EOF
出力
admin:~/environment $ cat << "EOF" > cfn/${CFN_TEMPLATE}
> AWSTemplateFormatVersion: 2010-09-09
> Description: Hands-on template for EC2
> 
> Parameters:
>   VPCStack:
>     Type: String
>     Default: handson-cfn
>   EC2AMI:
>     Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
>     Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
> 
> Resources:
>   EC2WebServer01:
>     Type: AWS::EC2::Instance
>     Properties:
>       ImageId: !Ref EC2AMI
>       InstanceType: t2.micro
> 
> Outputs:
>   EC2WebServer01:
>     Value: !Ref EC2WebServer01
>     Export:
>       Name: !Sub ${AWS::StackName}-EC2WebServer01
> EOF

スタック作成

コマンド
# create
aws cloudformation create-stack \
    --stack-name ${STACK_NAME_EC2} \
    --template-body file://cfn/${CFN_TEMPLATE}
出力
admin:~/environment $ # create
admin:~/environment $ aws cloudformation create-stack \
>     --stack-name ${STACK_NAME_EC2} \
>     --template-body file://cfn/${CFN_TEMPLATE}
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-ec2/42600880-571e-11ef-8a6e-065519c9cca5"
}

リソース一覧確認

コマンド
aws cloudformation describe-stack-resources \
    --stack-name ${STACK_NAME_EC2} \
    --no-cli-pager
出力
admin:~/environment $ aws cloudformation describe-stack-resources \
>     --stack-name ${STACK_NAME_EC2} \
>     --no-cli-pager
{
    "StackResources": [
        {
            "StackName": "handson-cfn-ec2",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-ec2/42600880-571e-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "EC2WebServer01",
            "PhysicalResourceId": "i-09901dd8ead627178",
            "ResourceType": "AWS::EC2::Instance",
            "Timestamp": "2024-08-10T13:42:11.274000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

パラメータ一覧確認

コマンド
aws cloudformation describe-stacks \
    --stack-name ${STACK_NAME_EC2} \
    --query 'Stacks[0].Parameters'
出力
admin:~/environment $ aws cloudformation describe-stacks \
>     --stack-name ${STACK_NAME_EC2} \
>     --query 'Stacks[0].Parameters'
[
    {
        "ParameterKey": "VPCStack",
        "ParameterValue": "handson-cfn"
    },
    {
        "ParameterKey": "EC2AMI",
        "ParameterValue": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
        "ResolvedValue": "ami-092957e65e64cc357"
    }
]

YAMLファイルの更新 (SubnetId指定追加)

コマンド
cat << "EOF" > cfn/${CFN_TEMPLATE}
AWSTemplateFormatVersion: 2010-09-09
Description: Hands-on template for EC2

Parameters:
  VPCStack:
    Type: String
    Default: handson-cfn
  EC2AMI:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

Resources:
  EC2WebServer01:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref EC2AMI
      InstanceType: t2.micro
      SubnetId:
        Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet1

Outputs:
  EC2WebServer01:
    Value: !Ref EC2WebServer01
    Export:
      Name: !Sub ${AWS::StackName}-EC2WebServer01
EOF
出力
admin:~/environment $ cat << "EOF" > cfn/${CFN_TEMPLATE}
> AWSTemplateFormatVersion: 2010-09-09
> Description: Hands-on template for EC2
> 
> Parameters:
>   VPCStack:
>     Type: String
>     Default: handson-cfn
>   EC2AMI:
>     Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
>     Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
> 
> Resources:
>   EC2WebServer01:
>     Type: AWS::EC2::Instance
>     Properties:
>       ImageId: !Ref EC2AMI
>       InstanceType: t2.micro
>       SubnetId:
>         Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet1
> 
> Outputs:
>   EC2WebServer01:
>     Value: !Ref EC2WebServer01
>     Export:
>       Name: !Sub ${AWS::StackName}-EC2WebServer01
> EOF

YAMLファイルの検証

コマンド
# validate
aws cloudformation validate-template \
    --template-body file://cfn/${CFN_TEMPLATE}
出力
admin:~/environment $ # validate
admin:~/environment $ aws cloudformation validate-template \
>     --template-body file://cfn/${CFN_TEMPLATE}
{
    "Parameters": [
        {
            "ParameterKey": "VPCStack",
            "DefaultValue": "handson-cfn",
            "NoEcho": false
        },
        {
            "ParameterKey": "EC2AMI",
            "DefaultValue": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
            "NoEcho": false
        }
    ],
    "Description": "Hands-on template for EC2"
}

YAMLファイルの更新 (UserData追加)

コマンド
cat << "EOF" > cfn/02_ec2.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Hands-on template for EC2

Parameters:
  VPCStack:
    Type: String
    Default: handson-cfn
  EC2AMI:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

Resources:
  EC2WebServer01:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref EC2AMI
      InstanceType: t2.micro
      SubnetId:
        Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet1
      UserData: !Base64 |
        #! /bin/bash
        yum update -y
        amazon-linux-extras install php7.2 -y
        yum -y install mysql httpd php-mbstring php-xml
        
        wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
        tar zxvf /tmp/latest-ja.tar.gz -C /tmp
        cp -r /tmp/wordpress/* /var/www/html/
        touch /var/www/html/.check_alive
        chown apache:apache -R /var/www/html
        
        systemctl enable httpd.service
        systemctl start httpd.service

Outputs:
  EC2WebServer01:
    Value: !Ref EC2WebServer01
    Export:
      Name: !Sub ${AWS::StackName}-EC2WebServer01
EOF
出力
admin:~/environment $ cat << "EOF" > cfn/02_ec2.yml
> AWSTemplateFormatVersion: 2010-09-09
> Description: Hands-on template for EC2
> 
> Parameters:
>   VPCStack:
>     Type: String
>     Default: handson-cfn
>   EC2AMI:
>     Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
>     Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
> 
> Resources:
>   EC2WebServer01:
>     Type: AWS::EC2::Instance
>     Properties:
>       ImageId: !Ref EC2AMI
>       InstanceType: t2.micro
>       SubnetId:
>         Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet1
>       UserData: !Base64 |
>         #! /bin/bash
>         yum update -y
>         amazon-linux-extras install php7.2 -y
>         yum -y install mysql httpd php-mbstring php-xml
>         
>         wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
>         tar zxvf /tmp/latest-ja.tar.gz -C /tmp
>         cp -r /tmp/wordpress/* /var/www/html/
>         touch /var/www/html/.check_alive
>         chown apache:apache -R /var/www/html
>         
>         systemctl enable httpd.service
>         systemctl start httpd.service
> 
> Outputs:
>   EC2WebServer01:
>     Value: !Ref EC2WebServer01
>     Export:
>       Name: !Sub ${AWS::StackName}-EC2WebServer01
> EOF

スタックファイルの更新

コマンド
# validate
aws cloudformation validate-template \
    --template-body file://cfn/${CFN_TEMPLATE}

# update
aws cloudformation update-stack \
    --stack-name ${STACK_NAME_EC2}  \
    --template-body file://cfn/${CFN_TEMPLATE}
出力
admin:~/environment $ # validate
admin:~/environment $ aws cloudformation validate-template \
>     --template-body file://cfn/${CFN_TEMPLATE}
{
    "Parameters": [
        {
            "ParameterKey": "VPCStack",
            "DefaultValue": "handson-cfn",
            "NoEcho": false
        },
        {
            "ParameterKey": "EC2AMI",
            "DefaultValue": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
            "NoEcho": false
        }
    ],
    "Description": "Hands-on template for EC2"
}
admin:~/environment $ 
admin:~/environment $ # update
admin:~/environment $ aws cloudformation update-stack \
>     --stack-name ${STACK_NAME_EC2}  \
>     --template-body file://cfn/${CFN_TEMPLATE}
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-ec2/42600880-571e-11ef-8a6e-065519c9cca5"
}

リソース一覧確認

コマンド
aws cloudformation describe-stack-resources \
    --stack-name ${STACK_NAME_EC2} \
    --no-cli-pager
出力
admin:~/environment $ aws cloudformation describe-stack-resources \
>     --stack-name ${STACK_NAME_EC2} \
>     --no-cli-pager
{
    "StackResources": [
        {
            "StackName": "handson-cfn-ec2",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-ec2/42600880-571e-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "EC2WebServer01",
            "PhysicalResourceId": "i-0ef1d788ec0c18a5a",
            "ResourceType": "AWS::EC2::Instance",
            "Timestamp": "2024-08-10T13:50:43.161000+00:00",
            "ResourceStatus": "UPDATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

06 EC2の作成 その2 (Cloud9で実施)

YAMLファイルの更新 (セキュリティグループの作成)

コマンド
cat << "EOF" > cfn/02_ec2.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Hands-on template for EC2

Parameters:
  VPCStack:
    Type: String
    Default: handson-cfn
  EC2AMI:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

Resources:
  EC2WebServer01:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref EC2AMI
      InstanceType: t2.micro
      SubnetId:
        Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet1
      UserData: !Base64 |
        #! /bin/bash
        yum update -y
        amazon-linux-extras install php7.2 -y
        yum -y install mysql httpd php-mbstring php-xml
        
        wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
        tar zxvf /tmp/latest-ja.tar.gz -C /tmp
        cp -r /tmp/wordpress/* /var/www/html/
        touch /var/www/html/.check_alive
        chown apache:apache -R /var/www/html
        
        systemctl enable httpd.service
        systemctl start httpd.service
  EC2SG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: sg for web server
      VpcId:
        Fn::ImportValue: !Sub ${VPCStack}-VPCID
      SecurityGroupIngress: 
        - IpProtocol: tcp
          CidrIp: 10.0.0.0/16
          FromPort: 80
          ToPort: 80

Outputs:
  EC2WebServer01:
    Value: !Ref EC2WebServer01
    Export:
      Name: !Sub ${AWS::StackName}-EC2WebServer01
EOF
出力
admin:~/environment $ cat << "EOF" > cfn/02_ec2.yml
> AWSTemplateFormatVersion: 2010-09-09
> Description: Hands-on template for EC2
> 
> Parameters:
>   VPCStack:
>     Type: String
>     Default: handson-cfn
>   EC2AMI:
>     Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
>     Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
> 
> Resources:
>   EC2WebServer01:
>     Type: AWS::EC2::Instance
>     Properties:
>       ImageId: !Ref EC2AMI
>       InstanceType: t2.micro
>       SubnetId:
>         Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet1
>       UserData: !Base64 |
>         #! /bin/bash
>         yum update -y
>         amazon-linux-extras install php7.2 -y
>         yum -y install mysql httpd php-mbstring php-xml
>         
>         wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
>         tar zxvf /tmp/latest-ja.tar.gz -C /tmp
>         cp -r /tmp/wordpress/* /var/www/html/
>         touch /var/www/html/.check_alive
>         chown apache:apache -R /var/www/html
>         
>         systemctl enable httpd.service
>         systemctl start httpd.service
>   EC2SG:
>     Type: AWS::EC2::SecurityGroup
>     Properties:
>       GroupDescription: sg for web server
>       VpcId:
>         Fn::ImportValue: !Sub ${VPCStack}-VPCID
>       SecurityGroupIngress: 
>         - IpProtocol: tcp
>           CidrIp: 10.0.0.0/16
>           FromPort: 80
>           ToPort: 80
> 
> Outputs:
>   EC2WebServer01:
>     Value: !Ref EC2WebServer01
>     Export:
>       Name: !Sub ${AWS::StackName}-EC2WebServer01
> EOF

スタックファイルの更新

コマンド
# validate
aws cloudformation validate-template \
    --template-body file://cfn/${CFN_TEMPLATE}

# update
aws cloudformation update-stack \
    --stack-name ${STACK_NAME_EC2}  \
    --template-body file://cfn/${CFN_TEMPLATE}
出力
admin:~/environment $ # validate
admin:~/environment $ aws cloudformation validate-template \
>     --template-body file://cfn/${CFN_TEMPLATE}
{
    "Parameters": [
        {
            "ParameterKey": "VPCStack",
            "DefaultValue": "handson-cfn",
            "NoEcho": false
        },
        {
            "ParameterKey": "EC2AMI",
            "DefaultValue": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
            "NoEcho": false
        }
    ],
    "Description": "Hands-on template for EC2"
}
admin:~/environment $ 
admin:~/environment $ # update
admin:~/environment $ aws cloudformation update-stack \
>     --stack-name ${STACK_NAME_EC2}  \
>     --template-body file://cfn/${CFN_TEMPLATE}
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-ec2/42600880-571e-11ef-8a6e-065519c9cca5"
}

リソース一覧確認

コマンド
aws cloudformation describe-stack-resources \
    --stack-name ${STACK_NAME_EC2} \
    --no-cli-pager
出力
admin:~/environment $ aws cloudformation describe-stack-resources \
>     --stack-name ${STACK_NAME_EC2} \
>     --no-cli-pager
{
    "StackResources": [
        {
            "StackName": "handson-cfn-ec2",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-ec2/42600880-571e-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "EC2SG",
            "PhysicalResourceId": "sg-07fb844f584b369c2",
            "ResourceType": "AWS::EC2::SecurityGroup",
            "Timestamp": "2024-08-10T14:36:28.722000+00:00",
            "ResourceStatus": "UPDATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn-ec2",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-ec2/42600880-571e-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "EC2WebServer01",
            "PhysicalResourceId": "i-0ef1d788ec0c18a5a",
            "ResourceType": "AWS::EC2::Instance",
            "Timestamp": "2024-08-10T13:50:43.161000+00:00",
            "ResourceStatus": "UPDATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

YAMLファイルの更新 (EC2にセキュリティグループの適用)

コマンド
cat << "EOF" > cfn/02_ec2.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Hands-on template for EC2

Parameters:
  VPCStack:
    Type: String
    Default: handson-cfn
  EC2AMI:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

Resources:
  EC2WebServer01:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref EC2AMI
      InstanceType: t2.micro
      SubnetId:
        Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet1
      UserData: !Base64 |
        #! /bin/bash
        yum update -y
        amazon-linux-extras install php7.2 -y
        yum -y install mysql httpd php-mbstring php-xml
        
        wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
        tar zxvf /tmp/latest-ja.tar.gz -C /tmp
        cp -r /tmp/wordpress/* /var/www/html/
        touch /var/www/html/.check_alive
        chown apache:apache -R /var/www/html
        
        systemctl enable httpd.service
        systemctl start httpd.service
      SecurityGroupIds:
        - !Ref EC2SG
  EC2SG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: sg for web server
      VpcId:
        Fn::ImportValue: !Sub ${VPCStack}-VPCID
      SecurityGroupIngress: 
        - IpProtocol: tcp
          CidrIp: 10.0.0.0/16
          FromPort: 80
          ToPort: 80

Outputs:
  EC2WebServer01:
    Value: !Ref EC2WebServer01
    Export:
      Name: !Sub ${AWS::StackName}-EC2WebServer01
EOF
出力
admin:~/environment $ cat << "EOF" > cfn/02_ec2.yml
> AWSTemplateFormatVersion: 2010-09-09
> Description: Hands-on template for EC2
> 
> Parameters:
>   VPCStack:
>     Type: String
>     Default: handson-cfn
>   EC2AMI:
>     Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
>     Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
> 
> Resources:
>   EC2WebServer01:
>     Type: AWS::EC2::Instance
>     Properties:
>       ImageId: !Ref EC2AMI
>       InstanceType: t2.micro
>       SubnetId:
>         Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet1
>       UserData: !Base64 |
>         #! /bin/bash
>         yum update -y
>         amazon-linux-extras install php7.2 -y
>         yum -y install mysql httpd php-mbstring php-xml
>         
>         wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
>         tar zxvf /tmp/latest-ja.tar.gz -C /tmp
>         cp -r /tmp/wordpress/* /var/www/html/
>         touch /var/www/html/.check_alive
>         chown apache:apache -R /var/www/html
>         
>         systemctl enable httpd.service
>         systemctl start httpd.service
>       SecurityGroupIds:
>         - !Ref EC2SG
>   EC2SG:
>     Type: AWS::EC2::SecurityGroup
>     Properties:
>       GroupDescription: sg for web server
>       VpcId:
>         Fn::ImportValue: !Sub ${VPCStack}-VPCID
>       SecurityGroupIngress: 
>         - IpProtocol: tcp
>           CidrIp: 10.0.0.0/16
>           FromPort: 80
>           ToPort: 80
> 
> Outputs:
>   EC2WebServer01:
>     Value: !Ref EC2WebServer01
>     Export:
>       Name: !Sub ${AWS::StackName}-EC2WebServer01
> EOF

スタックファイルの更新

コマンド
# validate
aws cloudformation validate-template \
    --template-body file://cfn/${CFN_TEMPLATE}

# update
aws cloudformation update-stack \
    --stack-name ${STACK_NAME_EC2}  \
    --template-body file://cfn/${CFN_TEMPLATE}
出力
admin:~/environment $ # validate
admin:~/environment $ aws cloudformation validate-template \
>     --template-body file://cfn/${CFN_TEMPLATE}
{
    "Parameters": [
        {
            "ParameterKey": "VPCStack",
            "DefaultValue": "handson-cfn",
            "NoEcho": false
        },
        {
            "ParameterKey": "EC2AMI",
            "DefaultValue": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
            "NoEcho": false
        }
    ],
    "Description": "Hands-on template for EC2"
}
admin:~/environment $ 
admin:~/environment $ # update
admin:~/environment $ aws cloudformation update-stack \
>     --stack-name ${STACK_NAME_EC2}  \
>     --template-body file://cfn/${CFN_TEMPLATE}
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-ec2/42600880-571e-11ef-8a6e-065519c9cca5"
}

リソース一覧確認

コマンド
aws cloudformation describe-stack-resources \
    --stack-name ${STACK_NAME_EC2} \
    --no-cli-pager
出力
admin:~/environment $ aws cloudformation describe-stack-resources \
>     --stack-name ${STACK_NAME_EC2} \
>     --no-cli-pager
{
    "StackResources": [
        {
            "StackName": "handson-cfn-ec2",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-ec2/42600880-571e-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "EC2SG",
            "PhysicalResourceId": "sg-07fb844f584b369c2",
            "ResourceType": "AWS::EC2::SecurityGroup",
            "Timestamp": "2024-08-10T14:36:28.722000+00:00",
            "ResourceStatus": "UPDATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn-ec2",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-ec2/42600880-571e-11ef-8a6e-065519c9cca5",
            "LogicalResourceId": "EC2WebServer01",
            "PhysicalResourceId": "i-0ef1d788ec0c18a5a",
            "ResourceType": "AWS::EC2::Instance",
            "Timestamp": "2024-08-10T14:39:06.476000+00:00",
            "ResourceStatus": "UPDATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

スタック詳細

コマンド
aws cloudformation describe-stacks \
    --stack-name ${STACK_NAME_EC2} \
    --no-cli-pager
出力
admin:~/environment $ aws cloudformation describe-stacks \
>     --stack-name ${STACK_NAME_EC2} \
>     --no-cli-pager
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-ec2/42600880-571e-11ef-8a6e-065519c9cca5",
            "StackName": "handson-cfn-ec2",
            "Description": "Hands-on template for EC2",
            "Parameters": [
                {
                    "ParameterKey": "VPCStack",
                    "ParameterValue": "handson-cfn"
                },
                {
                    "ParameterKey": "EC2AMI",
                    "ParameterValue": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
                    "ResolvedValue": "ami-092957e65e64cc357"
                }
            ],
            "CreationTime": "2024-08-10T13:41:34.743000+00:00",
            "LastUpdatedTime": "2024-08-10T14:39:01.241000+00:00",
            "RollbackConfiguration": {},
            "StackStatus": "UPDATE_COMPLETE",
            "DisableRollback": false,
            "NotificationARNs": [],
            "Outputs": [
                {
                    "OutputKey": "EC2WebServer01",
                    "OutputValue": "i-0ef1d788ec0c18a5a",
                    "ExportName": "handson-cfn-ec2-EC2WebServer01"
                }
            ],
            "Tags": [],
            "EnableTerminationProtection": false,
            "DriftInformation": {
                "StackDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

07 RDS, ELBの作成、スタックのライフサイクル・分割

RDSの作成

コマンド
# スタック名
STACK_NAME_RDS="handson-cfn-rds" \
&& echo ${STACK_NAME_RDS}

# テンプレートファイル
CFN_TEMPLATE="03_rds.yml" \
&& echo ${CFN_TEMPLATE}
出力
admin:~/environment $ # スタック名
admin:~/environment $ STACK_NAME_RDS="handson-cfn-rds" \
> && echo ${STACK_NAME_RDS}
handson-cfn-rds
admin:~/environment $ 
admin:~/environment $ # テンプレートファイル
admin:~/environment $ CFN_TEMPLATE="03_rds.yml" \
> && echo ${CFN_TEMPLATE}
03_rds.yml

YAMLファイル作成

コマンド
cat << "EOF" > cfn/${CFN_TEMPLATE}
AWSTemplateFormatVersion: 2010-09-09
Description: Hands-on template for RDS

Parameters:
  VPCStack:
    Type: String
    Default: handson-cfn
  DBUser:
    Type: String
    Default: dbmaster
  DBPassword:
    Type: String
    Default: H&ppyHands0n
    NoEcho: true

  
Resources:
  DBInstance:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Delete
    Properties:
      DBInstanceClass: db.t3.micro
      AllocatedStorage: "10"
      StorageType: gp2
      Engine: MySQL
      MasterUsername: !Ref DBUser
      MasterUserPassword: !Ref DBPassword
      DBName: wordpress
      BackupRetentionPeriod: 0
      DBSubnetGroupName: !Ref DBSubnetGroup
      VPCSecurityGroups:
        - !Ref DBSecurityGroup

  DBSubnetGroup: 
    Type: AWS::RDS::DBSubnetGroup
    Properties: 
      DBSubnetGroupDescription: DB Subnet Group for Private Subnet
      SubnetIds: 
        - Fn::ImportValue: !Sub ${VPCStack}-PrivateSubnet1
        - Fn::ImportValue: !Sub ${VPCStack}-PrivateSubnet2

  DBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupDescription: !Sub ${AWS::StackName}-MySQL
      VpcId:
        Fn::ImportValue: !Sub ${VPCStack}-VPCID
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: 10.0.0.0/16


Outputs:
  DBEndpoint:
    Value: !GetAtt DBInstance.Endpoint.Address
    Export:
      Name: !Sub ${AWS::StackName}-DBEndpoint
EOF
出力
admin:~/environment $ cat << "EOF" > cfn/${CFN_TEMPLATE}
> AWSTemplateFormatVersion: 2010-09-09
> Description: Hands-on template for RDS
> 
> Parameters:
>   VPCStack:
>     Type: String
>     Default: handson-cfn
>   DBUser:
>     Type: String
>     Default: dbmaster
>   DBPassword:
>     Type: String
>     Default: H&ppyHands0n
>     NoEcho: true
> 
>   
> Resources:
>   DBInstance:
>     Type: AWS::RDS::DBInstance
>     DeletionPolicy: Delete
>     Properties:
>       DBInstanceClass: db.t3.micro
>       AllocatedStorage: "10"
>       StorageType: gp2
>       Engine: MySQL
>       MasterUsername: !Ref DBUser
>       MasterUserPassword: !Ref DBPassword
>       DBName: wordpress
>       BackupRetentionPeriod: 0
>       DBSubnetGroupName: !Ref DBSubnetGroup
>       VPCSecurityGroups:
>         - !Ref DBSecurityGroup
> 
>   DBSubnetGroup: 
>     Type: AWS::RDS::DBSubnetGroup
>     Properties: 
>       DBSubnetGroupDescription: DB Subnet Group for Private Subnet
>       SubnetIds: 
>         - Fn::ImportValue: !Sub ${VPCStack}-PrivateSubnet1
>         - Fn::ImportValue: !Sub ${VPCStack}-PrivateSubnet2
> 
>   DBSecurityGroup:
>     Type: AWS::EC2::SecurityGroup
>     Properties: 
>       GroupDescription: !Sub ${AWS::StackName}-MySQL
>       VpcId:
>         Fn::ImportValue: !Sub ${VPCStack}-VPCID
>       SecurityGroupIngress:
>         - IpProtocol: tcp
>           FromPort: 3306
>           ToPort: 3306
>           CidrIp: 10.0.0.0/16
> 
> 
> Outputs:
>   DBEndpoint:
>     Value: !GetAtt DBInstance.Endpoint.Address
>     Export:
>       Name: !Sub ${AWS::StackName}-DBEndpoint
> EOF

スタック作成

コマンド
# create
aws cloudformation create-stack \
    --stack-name ${STACK_NAME_RDS} \
    --template-body file://cfn/${CFN_TEMPLATE}
出力
admin:~/environment $ # create
admin:~/environment $ aws cloudformation create-stack \
>     --stack-name ${STACK_NAME_RDS} \
>     --template-body file://cfn/${CFN_TEMPLATE}
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-rds/024ef7a0-5729-11ef-bec7-0663b114b127"
}

リソース一覧確認

コマンド
aws cloudformation describe-stack-resources \
    --stack-name ${STACK_NAME_RDS} \
    --no-cli-pager
出力
admin:~/environment $ aws cloudformation describe-stack-resources \
>     --stack-name ${STACK_NAME_RDS} \
>     --no-cli-pager
{
    "StackResources": [
        {
            "StackName": "handson-cfn-rds",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-rds/024ef7a0-5729-11ef-bec7-0663b114b127",
            "LogicalResourceId": "DBInstance",
            "PhysicalResourceId": "handson-cfn-rds-dbinstance-gkxorqw5feoe",
            "ResourceType": "AWS::RDS::DBInstance",
            "Timestamp": "2024-08-10T15:01:43.837000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn-rds",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-rds/024ef7a0-5729-11ef-bec7-0663b114b127",
            "LogicalResourceId": "DBSecurityGroup",
            "PhysicalResourceId": "sg-0c44fd4ce31a23436",
            "ResourceType": "AWS::EC2::SecurityGroup",
            "Timestamp": "2024-08-10T14:58:37.822000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn-rds",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-rds/024ef7a0-5729-11ef-bec7-0663b114b127",
            "LogicalResourceId": "DBSubnetGroup",
            "PhysicalResourceId": "handson-cfn-rds-dbsubnetgroup-om1dh8gcn15d",
            "ResourceType": "AWS::RDS::DBSubnetGroup",
            "Timestamp": "2024-08-10T14:58:36.276000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

スタック詳細

コマンド
aws cloudformation describe-stacks \
    --stack-name ${STACK_NAME_RDS} \
    --no-cli-pager
出力
admin:~/environment $ aws cloudformation describe-stacks \
>     --stack-name ${STACK_NAME_RDS} \
>     --no-cli-pager
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-rds/024ef7a0-5729-11ef-bec7-0663b114b127",
            "StackName": "handson-cfn-rds",
            "Description": "Hands-on template for RDS",
            "Parameters": [
                {
                    "ParameterKey": "DBPassword",
                    "ParameterValue": "****"
                },
                {
                    "ParameterKey": "DBUser",
                    "ParameterValue": "dbmaster"
                },
                {
                    "ParameterKey": "VPCStack",
                    "ParameterValue": "handson-cfn"
                }
            ],
            "CreationTime": "2024-08-10T14:58:31.641000+00:00",
            "RollbackConfiguration": {},
            "StackStatus": "CREATE_COMPLETE",
            "DisableRollback": false,
            "NotificationARNs": [],
            "Outputs": [
                {
                    "OutputKey": "DBEndpoint",
                    "OutputValue": "handson-cfn-rds-dbinstance-gkxorqw5feoe.clacqicsiqrt.ap-northeast-1.rds.amazonaws.com",
                    "ExportName": "handson-cfn-rds-DBEndpoint"
                }
            ],
            "Tags": [],
            "EnableTerminationProtection": false,
            "DriftInformation": {
                "StackDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

ELBの作成

変数

コマンド
# スタック名
STACK_NAME_ELB="handson-cfn-elb" \
&& echo ${STACK_NAME_ELB}

# テンプレートファイル
CFN_TEMPLATE="04_elb.yml" \
&& echo ${CFN_TEMPLATE}
出力
admin:~/environment $ # スタック名
admin:~/environment $ STACK_NAME_ELB="handson-cfn-elb" \
> && echo ${STACK_NAME_ELB}
handson-cfn-elb
admin:~/environment $ 
admin:~/environment $ # テンプレートファイル
admin:~/environment $ CFN_TEMPLATE="04_elb.yml" \
> && echo ${CFN_TEMPLATE}
04_elb.yml

YAMLファイル作成

コマンド
cat << "EOF" > cfn/${CFN_TEMPLATE}
AWSTemplateFormatVersion: 2010-09-09
Description: Hands-on template for ALB

Parameters:
  VPCStack:
    Type: String
    Default: handson-cfn
  EC2Stack:
    Type: String
    Default: handson-cfn-ec2

Resources:
  FrontLB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Ref AWS::StackName
      Subnets:
        - Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet1
        - Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet2
      SecurityGroups: 
        - !Ref SecurityGroupLB

  FrontLBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      LoadBalancerArn: !Ref FrontLB
      Port: 80
      Protocol: HTTP 
      DefaultActions: 
        - Type: forward
          TargetGroupArn: !Ref FrontLBTargetGroup

  FrontLBTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${AWS::StackName}-tg
      VpcId:
        Fn::ImportValue: !Sub ${VPCStack}-VPCID
      Port: 80
      Protocol: HTTP
      HealthCheckPath: /.check_alive
      Targets:
        - Id:
            Fn::ImportValue: !Sub ${EC2Stack}-EC2WebServer01

  SecurityGroupLB:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupDescription: !Ref AWS::StackName
      VpcId:
        Fn::ImportValue: !Sub ${VPCStack}-VPCID
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

Outputs:
  FrontLBEndpoint:
    Value: !GetAtt FrontLB.DNSName
    Export:
      Name: !Sub ${AWS::StackName}-Endpoint
EOF
出力
admin:~/environment $ cat << "EOF" > cfn/${CFN_TEMPLATE}
> AWSTemplateFormatVersion: 2010-09-09
> Description: Hands-on template for ALB
> 
> Parameters:
>   VPCStack:
>     Type: String
>     Default: handson-cfn
>   EC2Stack:
>     Type: String
>     Default: handson-cfn-ec2
> 
> Resources:
>   FrontLB:
>     Type: AWS::ElasticLoadBalancingV2::LoadBalancer
>     Properties:
>       Name: !Ref AWS::StackName
>       Subnets:
>         - Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet1
>         - Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet2
>       SecurityGroups: 
>         - !Ref SecurityGroupLB
> 
>   FrontLBListener:
>     Type: AWS::ElasticLoadBalancingV2::Listener
>     Properties:
>       LoadBalancerArn: !Ref FrontLB
>       Port: 80
>       Protocol: HTTP 
>       DefaultActions: 
>         - Type: forward
>           TargetGroupArn: !Ref FrontLBTargetGroup
> 
>   FrontLBTargetGroup:
>     Type: AWS::ElasticLoadBalancingV2::TargetGroup
>     Properties:
>       Name: !Sub ${AWS::StackName}-tg
>       VpcId:
>         Fn::ImportValue: !Sub ${VPCStack}-VPCID
>       Port: 80
>       Protocol: HTTP
>       HealthCheckPath: /.check_alive
>       Targets:
>         - Id:
>             Fn::ImportValue: !Sub ${EC2Stack}-EC2WebServer01
> 
>   SecurityGroupLB:
>     Type: AWS::EC2::SecurityGroup
>     Properties: 
>       GroupDescription: !Ref AWS::StackName
>       VpcId:
>         Fn::ImportValue: !Sub ${VPCStack}-VPCID
>       SecurityGroupIngress:
>         - IpProtocol: tcp
>           FromPort: 80
>           ToPort: 80
>           CidrIp: 0.0.0.0/0
> 
> Outputs:
>   FrontLBEndpoint:
>     Value: !GetAtt FrontLB.DNSName
>     Export:
>       Name: !Sub ${AWS::StackName}-Endpoint
> EOF

スタック作成

コマンド
# create
aws cloudformation create-stack \
    --stack-name ${STACK_NAME_ELB} \
    --template-body file://cfn/${CFN_TEMPLATE}
出力
admin:~/environment $ # create
admin:~/environment $ aws cloudformation create-stack \
>     --stack-name ${STACK_NAME_ELB} \
>     --template-body file://cfn/${CFN_TEMPLATE}
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-elb/f06066e0-5729-11ef-a599-0e54d4b8961d"
}

リソース一覧確認

コマンド
aws cloudformation describe-stack-resources \
    --stack-name ${STACK_NAME_ELB} \
    --no-cli-pager
出力
admin:~/environment $ aws cloudformation describe-stack-resources \
>     --stack-name ${STACK_NAME_ELB} \
>     --no-cli-pager
{
    "StackResources": [
        {
            "StackName": "handson-cfn-elb",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-elb/f06066e0-5729-11ef-a599-0e54d4b8961d",
            "LogicalResourceId": "FrontLB",
            "PhysicalResourceId": "arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:loadbalancer/app/handson-cfn-elb/b5dbb13c88778e0c",
            "ResourceType": "AWS::ElasticLoadBalancingV2::LoadBalancer",
            "Timestamp": "2024-08-10T15:08:23.641000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn-elb",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-elb/f06066e0-5729-11ef-a599-0e54d4b8961d",
            "LogicalResourceId": "FrontLBListener",
            "PhysicalResourceId": "arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:listener/app/handson-cfn-elb/b5dbb13c88778e0c/67f0b6991e9025bb",
            "ResourceType": "AWS::ElasticLoadBalancingV2::Listener",
            "Timestamp": "2024-08-10T15:08:25.723000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn-elb",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-elb/f06066e0-5729-11ef-a599-0e54d4b8961d",
            "LogicalResourceId": "FrontLBTargetGroup",
            "PhysicalResourceId": "arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:targetgroup/handson-cfn-elb-tg/6a8a2524885a1675",
            "ResourceType": "AWS::ElasticLoadBalancingV2::TargetGroup",
            "Timestamp": "2024-08-10T15:05:30.528000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        },
        {
            "StackName": "handson-cfn-elb",
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-elb/f06066e0-5729-11ef-a599-0e54d4b8961d",
            "LogicalResourceId": "SecurityGroupLB",
            "PhysicalResourceId": "sg-0fa024cf6ba742651",
            "ResourceType": "AWS::EC2::SecurityGroup",
            "Timestamp": "2024-08-10T15:05:17.290000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

スタック詳細

コマンド
aws cloudformation describe-stacks \
    --stack-name ${STACK_NAME_ELB} \
    --no-cli-pager
出力
admin:~/environment $ aws cloudformation describe-stacks \
>     --stack-name ${STACK_NAME_ELB} \
>     --no-cli-pager
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:ap-northeast-1:999999999999:stack/handson-cfn-elb/f06066e0-5729-11ef-a599-0e54d4b8961d",
            "StackName": "handson-cfn-elb",
            "Description": "Hands-on template for ALB",
            "Parameters": [
                {
                    "ParameterKey": "EC2Stack",
                    "ParameterValue": "handson-cfn-ec2"
                },
                {
                    "ParameterKey": "VPCStack",
                    "ParameterValue": "handson-cfn"
                }
            ],
            "CreationTime": "2024-08-10T15:05:11.050000+00:00",
            "RollbackConfiguration": {},
            "StackStatus": "CREATE_COMPLETE",
            "DisableRollback": false,
            "NotificationARNs": [],
            "Outputs": [
                {
                    "OutputKey": "FrontLBEndpoint",
                    "OutputValue": "handson-cfn-elb-1292321126.ap-northeast-1.elb.amazonaws.com",
                    "ExportName": "handson-cfn-elb-Endpoint"
                }
            ],
            "Tags": [],
            "EnableTerminationProtection": false,
            "DriftInformation": {
                "StackDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

08 まとめ 、削除

CloudFormationスタック削除 (Cloud9で実施)

コマンド
# handson-cfn-elb
aws cloudformation delete-stack \
    --stack-name ${STACK_NAME_ELB}

# handson-cfn-rds
aws cloudformation delete-stack \
    --stack-name ${STACK_NAME_RDS}

# handson-cfn-ec2
aws cloudformation delete-stack \
    --stack-name ${STACK_NAME_EC2}

# handson-cfn
aws cloudformation delete-stack \
    --stack-name ${STACK_NAME}
出力
admin:~/environment $ # handson-cfn-elb
admin:~/environment $ aws cloudformation delete-stack \
>   --stack-name ${STACK_NAME_ELB}
admin:~/environment $ 
admin:~/environment $ # handson-cfn-rds
admin:~/environment $ aws cloudformation delete-stack \
>     --stack-name ${STACK_NAME_RDS}
admin:~/environment $ 
admin:~/environment $ # handson-cfn-ec2
admin:~/environment $ aws cloudformation delete-stack \
>     --stack-name ${STACK_NAME_EC2}
admin:~/environment $ 
admin:~/environment $ # handson-cfn
admin:~/environment $ aws cloudformation delete-stack \
>     --stack-name ${STACK_NAME}

Cloud9 環境削除 (CloudShellで実施)

コマンド
aws cloud9 delete-environment \
    --environment-id ${CLOUD9_ENVIRONMENT_ID}
出力
[cloudshell-user@ip-10-130-46-148 ~]$ aws cloud9 delete-environment \
>     --environment-id ${CLOUD9_ENVIRONMENT_ID}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0