EC2 CloudFormationの例
この記事では、CloudFormationを使用してEC2の構築するときの実際的な例をいくつか紹介したいと思います。CloudFormation、EC2、EIP、VPC、およびVPCについてある程度の知識が必要です。この記事ではYAMLも使用していますので、その構文に精通している必要があります。以下の項目についてYAMLファイルを書いて説明します。
- 既存のVPCを利用してInstance作成
- セキュリティグループを作成
- Elastic IPを作成してEC2インスタンスに接続する
- CloudFormationのEC2インスタンス
- VPC作成(public及びprivateサブネット)
EC2 Instances in CloudFormation
AWS::EC2::Instance
リソースは EC2 インスタンスを作成する際に利用します。
ドキュメントを参照すると、ImageIdは必須パラメータがであることがわかります。
ImageId
プロパティは、インスタンスのために使用されるAMIを指します。
例えば ami-0c3fd0f5d33134a76
では、HVM仮想化を使用するAmazon Linux 2 AMI (HVM)イメージであるAMIとインスタンスストア用のEBSバックアップSSDドライブ hvm:ebs-ssd
を使用するために指定できるパラメタです。
既存のVPCを利用してInstance作成
この例では、既存のVPCを利用してInstance作ることを説明します。SecurityGroupIdsそしてSubnetIdのプロパティを含める必要があります。
- SecurityGroupIdsはインスタンスが属するVPCセキュリティグループのリストです。
- SubnetId インスタンスをVPC内の特定のサブネットと対応するAvailabilityZoneに配置します。
すでに作成されているKeyName(キー)を再利用できるように、インスタンスにも設定したいと思います。
InstanceTypeプロパティも設定することができます。利用可能なインスタンスタイプ を参照はこちらにしてください。インスタンスタイプはEC2のためのt2.nano、t2.microおよびt2.smallみたいな感じで選べることができます。
既存のVPCを利用してInstanceを作るテンプレート例
AWSTemplateFormatVersion: "2010-09-09"
Resources:
WebInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-0c3fd0f5d33134a76
KeyName: my-key
SecurityGroupIds:
- sg-sctv01234
SubnetId: subnet-sctv01234
インスタンスにタグつける
インスタンス名を設定するために Tag
属性を使ってKey
と value
にpropertyを入れる。これでTagつけることができます。
##### Tagの例:
AWSTemplateFormatVersion: "2010-09-09"
Resources:
WebInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-0c3fd0f5d33134a76
KeyName: my-key
SecurityGroupIds:
- sg-sctv01234
SubnetId: subnet-sctv01234
Tags:
-
Key: Name
Value: sctvーwebserver
##### 拡張モニタリングを有効にする方法
もう1つやりたいのは、拡張モニタリングを有効にすることです。Monitoringのプロパティがtrue
に設定することによって拡張モニタリングすることができます。
AWSTemplateFormatVersion: "2010-09-09"
Resources:
WebInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-0c3fd0f5d33134a76
KeyName: my-key
Monitoring: true
SecurityGroupIds:
- sg-sctv01234
SubnetId: subnet-sctv01234
Tags:
-
Key: Name
Value: sctvーwebserver
#### 削除保護の設定する方法
もう一つのベストプラクティスとして、リソースの誤った除去を防ぐために削除保護を有効にすることです。これはCloudFormationテンプレートにも同様に当てはまり、誤って本番用サーバーのスタック全体を一掃する可能性があります。
DisableApiTermination
のプロパティがtrue
に設定することによって、削除保護を有効にすることができる。
AWSTemplateFormatVersion: "2010-09-09"
Resources:
WebInstance:
Type: AWS::EC2::Instance
Properties:
DisableApiTermination: true
InstanceType: t2.micro
ImageId: ami-0c3fd0f5d33134a76
KeyName: my-key
Monitoring: true
SecurityGroupIds:
- sg-sctv01234
SubnetId: subnet-sctv01234
Tags:
-
Key: Name
Value: sctvーwebserver
DisableApiTerminationをtrueにすると、ロールバック操作中にインスタンスが削除またはクリーンアップすることができなくなります。何らかの理由でスタックを削除しようとするときは、スタックを削除する前に手動で削除保護を無効にする必要になります。
CloudFormationのセキュリティグループ
セキュリティグループを作成するには、AWS::EC2::SecurityGroup
リソースを使用します。
- VpcId:VPCのIDを指定。
- SecurityGroupIngress
- Amazon EC2 セキュリティグループの Ingress ルールのリスト。
すべてのIPv4アドレスに対してポート80と443ポートを開けるためのテンプレートです。
AWSTemplateFormatVersion: "2010-09-09"
Resources:
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: sctv Webserver
GroupName: web
VpcId: vpc-sctv01234
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
-
IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
CidrIP
代わりにSourceSecurityGroupId
が指定することができます。これにより、指定したセキュリティグループに属するリソースからの接続が許可されます。
例えば、WebSecurityGroupからDatabaseSecurityGroupの3306ポートへのtcpアクセス許可するような設定を行うことができます。
AWSTemplateFormatVersion: "2010-09-09"
Resources:
DatabaseSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: SCTV Database server
GroupName: database
VpcId: vpc-sctv01234
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: sg-sctv01234
WebSecurityGroupとDatabaseSecurityGroupて同じテンプレートにしている場合Ref
を使用してWebSecurityGroupのリソースを参照できるように設定する方法もできます。
AWSTemplateFormatVersion: "2010-09-09"
Resources:
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Web server
GroupName: web
VpcId: vpc-sctv01234
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
DatabaseSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: SCTV Database server
GroupName: database
VpcId: vpc-sctv01234
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !Ref WebSecurityGroup
Refの使用すると別のリソースや指定したパラメータの値を参照することができます。
##セキュリティグループとEC2の連携
セキュリティグループ付きのEC2インスタンスをcloudformationで作成する例を見ましょう。この例では新規security groupを作成して、Instance作成するときにRefを使用してセキュリティグループの参照するようにYaml書くことができます。
AWSTemplateFormatVersion: "2010-09-09"
Resources:
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Web server
GroupName: web
VpcId: vpc-abc01234
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
WebInstance:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: ap-northeast-1
InstanceType: t2.micro
ImageId: ami-0c3fd0f5d33134a76
KeyName: my-key
SecurityGroupIds:
- !Ref WebSecurityGroup
SubnetId: subnet-sctv01234
今回の例では、SecurityGroupをWebInstanceに付属させることができました。
##EIP
ElasticIPをEC2インスタンスにアタッチすることで固定なIPアドレスを作成することができる。
EIPをcloudformationで書くときはAWS::EC2::EIP
リソースを使用して、2つのプロパティを定義します。
- InstanceId: EIPを割り当てるインスタンスへの参照
- Domain: vpcに設定する。
それでおしまい。これは次のようなものです。
AWSTemplateFormatVersion: "2010-09-09"
Resources:
WebInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.nano
ImageId: ami-0c3fd0f5d33134a76
KeyName: my-key
SecurityGroupIds:
- sg-sctv01234
SubnetId: subnet-sctv01234
ElasticIp:
Type: AWS::EC2::EIP
Properties:
InstanceId: !Ref WebInstance
Domain: vpc
SecurityGroupとEC2インスタンスとEIPの連携。
最後の例になりますが上で説明してた全てのリソースを作成できるように同じテンプレート書いて見ましょう。
- セキュリティグループを作成する
- EC2インスタンスを作成する
- インスタンスにElastic IPをアタッチする
AWSTemplateFormatVersion: "2010-09-09"
Resources:
## 全てのIPアドレスから80ポートへアクセス許可する
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Sctv Web server
GroupName: web
VpcId: vpc-sctv01234
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
WebInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-0c3fd0f5d33134a76
KeyName: my-key
## keyNameは既存で発行済みにキーを使う時利用する
Monitoring: true
SecurityGroupIds:
- !Ref WebSecurityGroup
SubnetId: subnet-sctv01234
Tags:
-
Key: Name
Value: sctvーwebserver
## インスタンスにElastic IPをアタッチする
WebElasticIp:
Type: AWS::EC2::EIP
Properties:
InstanceId: !Ref WebInstance
Domain: vpc
##VPC作成(public及びprivateサブネット)
最後には少し細かい部分になりますが、VPC内にpublicとprivateサブネット類を作成しをしてt2.microでEC2インスタンスを作成するCloudFormationのサンプルです。
AWSTemplateFormatVersion: 2010-09-09
Description: Create AWS CloudFormation Customize Virtual Private Cloud
Resources:
## VPCの作成をする
VPC:
Type: 'AWS::EC2::VPC'
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: 'true'
EnableDnsHostnames: 'true'
Tags:
- Key: Name
Value: example-vpc
## MultiAZに配置するための複数のPublicサブネット(SubnetPublic1aとSubnetPublic1d)の作成
SubnetPublic1a:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref VPC
AvailabilityZone: ap-northeast-1a
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true
SubnetPublic1d:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref VPC
AvailabilityZone: ap-northeast-1d
CidrBlock: 10.0.2.0/24
MapPublicIpOnLaunch: true
## MultiAZに配置するための複数のPrivateサブネット(SubnetPrivate1aとSubnetPrivate1d)の作成
SubnetPrivate1a:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref VPC
AvailabilityZone: ap-northeast-1a
CidrBlock: 10.0.3.0/24
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: example-vpc-private-subnet-1a
SubnetPrivate1d:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref VPC
AvailabilityZone: ap-northeast-1d
CidrBlock: 10.0.4.0/24
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: example-vpc-private-subnet-1d
## InternetGatewayの作成
InternetGateway:
Type: 'AWS::EC2::InternetGateway'
Properties:
Tags:
- Key: Name
Value: example-vpc-igwg
## VPC にゲートウェイをアタッチします。
GatewayToInternet:
Type: 'AWS::EC2::VPCGatewayAttachment'
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
## VPC内に新しいルートテーブルの作成
PublicRouteTable:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Ref VPC
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
- Key: Network
Value: Public
PublicRoute:
Type: 'AWS::EC2::Route'
DependsOn: GatewayToInternet
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
## サブネットをルートテーブルに関連付ける
PublicSubnetRouteTableAssociatio1a:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref SubnetPublic1a
RouteTableId: !Ref PublicRouteTable
PublicSubnetRouteTableAssociation1c:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref SubnetPublic1c
RouteTableId: !Ref PublicRouteTable
## Vpcに新しいネットワークACLの作成
PublicNetworkAcl:
Type: 'AWS::EC2::NetworkAcl'
Properties:
VpcId: !Ref VPC
PublicNetworkAclEntry:
Type: 'AWS::EC2::NetworkAclEntry'
Properties:
CidrBlock: 10.0.0.0/16
Egress: 'true'
NetworkAclId: !Ref PublicNetworkAcl
Protocol: '-1'
RuleAction: allow
RuleNumber: '100'
PublicSubnetNetworkAclAssociatio1a:
Type: 'AWS::EC2::SubnetNetworkAclAssociation'
Properties:
SubnetId: !Ref SubnetPublic1a
NetworkAclId: !Ref PublicNetworkAcl
PublicSubnetNetworkAclAssociatio1c:
Type: 'AWS::EC2::SubnetNetworkAclAssociation'
Properties:
SubnetId: !Ref SubnetPublic1c
NetworkAclId: !Ref PublicNetworkAcl
## SecurityGroupの作成
InstanceSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
VpcId: !Ref VPC
GroupDescription: Enable SSH access via port 22
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 10.0.0.0/16
## EC2インスタンスの作成
EC2Instance:
Type: 'AWS::EC2::Instance'
Properties:
ImageId: ami-0c3fd0f5d33134a76
SecurityGroupIds:
- !Ref InstanceSecurityGroup
SubnetId: !Ref SubnetPrivate1a
InstanceType: !Ref InstanceType
KeyName: !Ref KeyName
Tags:
- Key: Application
Value: string
- Key: Name
Value: !Ref NameTags
参考サイト
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_Subnets.html
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_Route_Tables.html#RouteTables