テンプレートの更新
ここまでの手順でVPCの作成とEC2の起動まで完了しました。
ここで少しテンプレートをカスタマイズします。
EC2のIPアドレスを出力する
テンプレートのOutput
セクションを使うことで作成したリソースのIDや名称などの情報を出力することができます。
Outputs:
Logical ID:
Description: Information about the value
Value: Value to return
Export:
Name: Name of resource to export
作成したEC2インスタンスのインスタンスIDを出力したい場合はこのように指定します。
Outputs:
InstanceID:
Description: The Instance ID
Value: !Ref EC2Instance
EC2のパブリックIPアドレスを出力する場合はこのようになります。
Outputs:
PublicIp:
Description: EC2 Public IP
Value: !GetAtt EC2Instance.PublicIp
インスタンスIDとパブリックIPアドレスで値の取得方法が異なります。
各リソースの戻り値にはRef
とFn::GetAtt
の2種類あり、EC2インスタンスの場合はこのような定義です。
- Ref
- Fn::GetAtt
取得したい値がどちらで定義されているか確認し、使用する必要があります。
パラメーターを使用する
テンプレート内で使用する値をテンプレート実行時に外部からパラメーターとして渡すことができます。
パラメーターの指定はParameters
セクションを使用します。
Parameters:
ParameterLogicalID:
Type: DataType
ParameterProperty: value
ParameterPropertyとして様々な指定ができます。
- デフォルト値指定
- 入力フォーマット指定(入力桁、正規表現、数値場合の最小値・最大値)
- 入力フォーマットエラーに対するエラー時メッセージ
ユーザー名
user1
と固定していた文字列をパラメーター化してみましょう。
ユーザー名をパラメーターとする場合はこのようになります。
Parameters:
UserName:
Type: String
Description: User Name
Default: user1
パラメーターが含まれるテンプレートをデプロイする際に、パラメーターの入力が促されます。
パラメーターで指定した値は、Ref
組み込み関数で参照できます。
また、Fn::Join
組み込み関数やFn::Sub
組み込み関数と組み合わせて使用することも可能です。
!Join [ delimiter, [ comma-delimited list of values ] ]
Joinを使用してVPCのタグhandson-user1
を指定する方法はこのようになります。
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Join ['-', [handson, !Ref UserName]]
handson
と入力パラメーター
を-(区切り文字)
で連結する動作がJOINです。
!Sub
- String
- Var1Name: Var1Value
Var2Name: Var2Value
Stringパラメータにテンプレート・パラメータ、リソース論理ID、リソース属性のみを代入する場合は、変数マップを指定しないで利用が可能です。
!Sub String
VPCのタグhandson-user1
を指定する方法はこのようになります。
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub handson-${UserName}
インスタンスタイプ
同様に、EC2のインスタンスタイプを実行時に指定させる方法です。
Parametersセクションの定義でAllowedValues
を使用することで事前に用意した値から選択させることができます。
Parameters:
InstanceType:
Type: String
Description: Instance Type
AllowedValues:
- t2.micro
- t2.medium
Default: t2.micro
以下の内容で更新してください。
- EC2のインスタンスIDとパブリックIPアドレスを出力する
- ユーザー名を
UserName
としてパラメーター化し、VPCのタグFn::Join
組み込み関数で、EC2のタグをFn::Sub
組み込み関数で指定する
回答
AWSTemplateFormatVersion: "2010-09-09"
Description: Scalable website
Parameters:
UserName:
Type: String
Description: User Name
Default: user1
InstanceType:
Type: String
Description: Instance Type
AllowedValues:
- t2.micro
- t2.medium
Default: t2.micro
Mappings:
RegionMap:
us-east-1:
zone1: us-east-1a
zone2: us-east-1b
ap-northeast-1:
zone1: ap-northeast-1a
zone2: ap-northeast-1c
Resources:
###############
# VPC #
###############
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Join ['-', [handson, !Ref UserName]]
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.0.0/24
AvailabilityZone: !FindInMap [RegionMap, !Ref "AWS::Region", zone1]
Tags:
- Key: Name
Value: パブリックサブネット-1a
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !FindInMap [RegionMap, !Ref "AWS::Region", zone2]
Tags:
- Key: Name
Value: パブリックサブネット-1c
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.2.0/24
AvailabilityZone: !FindInMap [RegionMap, !Ref "AWS::Region", zone1]
Tags:
- Key: Name
Value: プライベートサブネット-1a
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.3.0/24
AvailabilityZone: !FindInMap [RegionMap, !Ref "AWS::Region", zone2]
Tags:
- Key: Name
Value: プライベートサブネット-1c
InternetGateway:
Type: AWS::EC2::InternetGateway
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
RouteTablePublic:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
RoutePublic1:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref RouteTablePublic
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
AssociateRouteTablePublic1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref RouteTablePublic
SubnetId: !Ref PublicSubnet1
AssociateRouteTablePublic2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref RouteTablePublic
SubnetId: !Ref PublicSubnet2
RouteTablePrivate1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
AssociateRouteTablePrivate1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref RouteTablePrivate1
SubnetId: !Ref PrivateSubnet1
RouteTablePrivate2:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
AssociateRouteTablePrivate2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref RouteTablePrivate2
SubnetId: !Ref PrivateSubnet2
###############
# EC2 #
###############
Ec2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: EC2 securitygroup
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: "ami-04beabd6a4fb6ab6f"
InstanceType: !Ref InstanceType
EbsOptimized: false
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
Encrypted: false
DeleteOnTermination: true
Iops: 3000
VolumeSize: 16
VolumeType: gp3
NetworkInterfaces:
- SubnetId: !Ref PublicSubnet1
AssociatePublicIpAddress: true
DeviceIndex: "0"
GroupSet:
- !Ref Ec2SecurityGroup
PrivateDnsNameOptions:
HostnameType: ip-name
EnableResourceNameDnsARecord: false
EnableResourceNameDnsAAAARecord: false
Tags:
- Key: Name
Value: !Sub webserver#1-${UserName}
UserData:
Fn::Base64: |
#!/bin/bash
dnf update -y
dnf install -y httpd wget php-fpm php-mysqli php-json php php-devel mariadb105
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/
chown apache:apache -R /var/www/html
systemctl enable httpd.service
systemctl start httpd.service
yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
systemctl restart amazon-ssm-agent
Outputs:
InstanceID:
Description: The Instance ID
Value: !Ref EC2Instance
PublicIp:
Description: EC2 Public IP
Value: !GetAtt EC2Instance.PublicIp