メインコンテンツまでスキップ

テンプレートの更新

ここまでの手順でVPCの作成とEC2の起動まで完了しました。

image.png

ここで少しテンプレートをカスタマイズします。

EC2のIPアドレスを出力する

テンプレートのOutputセクションを使うことで作成したリソースのIDや名称などの情報を出力することができます。

Outputs

構文
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アドレスで値の取得方法が異なります。

各リソースの戻り値にはRefFn::GetAttの2種類あり、EC2インスタンスの場合はこのような定義です。

  • Ref

image

  • Fn::GetAtt

image

取得したい値がどちらで定義されているか確認し、使用する必要があります。

パラメーターを使用する

テンプレート内で使用する値をテンプレート実行時に外部からパラメーターとして渡すことができます。

パラメーターの指定はParametersセクションを使用します。

Parameters

構文
Parameters:
ParameterLogicalID:
Type: DataType
ParameterProperty: value

ParameterPropertyとして様々な指定ができます。

  • デフォルト値指定
  • 入力フォーマット指定(入力桁、正規表現、数値場合の最小値・最大値)
  • 入力フォーマットエラーに対するエラー時メッセージ

ユーザー名

user1と固定していた文字列をパラメーター化してみましょう。

ユーザー名をパラメーターとする場合はこのようになります。

Parameters:
UserName:
Type: String
Description: User Name
Default: user1

パラメーターが含まれるテンプレートをデプロイする際に、パラメーターの入力が促されます。

image.png

パラメーターで指定した値は、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
テンプレートファイル