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