この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
大阪オフィスのYui(@MayForBlue)です。
タイトルの通り、CloudFormationでEC2インスタンスの休止機能を有効化できるようになったので、実際にやってみました!
公式ドキュメント
AWS CloudFormation を使用して、オンデマンドおよびリザーブドインスタンスの Amazon EC2 の休止機能を有効にする
目次
休止機能とは
インスタンスをシャットダウンする前に現在の作業状態をEBSルートボリュームに保存し、次回起動時にその内容を読み込んで開始させる機能です。
通常のシャットダウンとは違い、作業内容を保持することができます。
公式ドキュメント
Linux インスタンスの休止
Hibernate Your Windows Instance
必要な条件
インスタンスファミリー、インスタンスサイズ、ルートボリュームの暗号化など、休止機能を有効化するためには必要な条件が複数あります。
詳細はこちらをご覧ください。
休止の前提条件
CloudFormationでEC2インスタンスの休止機能を有効化する
実際にやってみました。
まず、休止機能を有効化しなかったインスタンスはこんな感じです。
インスタンスの休止が選択できず、詳細タブでも休止動作が無効になっていることが確認できます。
有効化する
休止機能の有効化に必要なプロパティを書いてテンプレートを流しました。
以下が休止機能を有効化するための設定です。
HibernationOptions:
Configured: true
EC2のテンプレートはこんな感じです。(一部抜粋)
EBSルートデバイスの暗号化やインスタンスタイプなど、今回必要な設定も盛り込んでいます。
(テンプレート全体の内容はコチラ)
EC2Instance01:
Type: "AWS::EC2::Instance"
Properties:
InstanceType: "m4.large"
HibernationOptions:
Configured: true
BlockDeviceMappings:
- DeviceName: "/dev/xvda"
Ebs:
DeleteOnTermination: true
VolumeType: "gp2"
VolumeSize: "30"
Encrypted: true
実際に流してみると、インスタンスの休止が選択でき、詳細タブでも休止動作が有効になっていることが確認できました!
今回使用したCloudFormationテンプレート
ネットワーク周りとEC2インスタンス周りでスタックを分け、パラメータのプロジェクト名に同じ値を渡すことで、EC2のスタックからネットワークのリソースを参照するようにしています。
ネットワーク用
AWSTemplateFormatVersion: "2010-09-09"
Description:
Network Create
Parameters:
ProjectName:
Type: String
Resources:
# -------------------------------
# VPC
# -------------------------------
# VPC Create
VPC:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: "10.1.0.0/16"
EnableDnsSupport: true
EnableDnsHostnames: true
InstanceTenancy: default
Tags:
- Key: Name
Value: !Sub "${ProjectName}-vpc"
# InternetGateway
InternetGateway:
Type: "AWS::EC2::InternetGateway"
Properties:
Tags:
- Key: Name
Value: !Sub "${ProjectName}-igw"
# IGW Attach
InternetGatewayAttachment:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
# -------------------------------
# Subnet
# -------------------------------
# Public SubnetA Create
PublicSubnetA:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: "ap-northeast-1a"
CidrBlock: "10.1.10.0/24"
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${ProjectName}-public-subnet-a"
# Public RouteTableA
PublicRouteTableA:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${ProjectName}-public-route-a"
# Routing
# PublicRouteA
PublicRouteA:
Type: "AWS::EC2::Route"
Properties:
RouteTableId: !Ref PublicRouteTableA
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref InternetGateway
# RouteTable Associate
# PublicRouteTableA - PublicSubnetA
PublicSubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PublicSubnetA
RouteTableId: !Ref PublicRouteTableA
Outputs:
# VPC
VPC:
Value: !Ref VPC
Export:
Name: !Sub "${ProjectName}-vpc"
VPCCIDR:
Value: "10.1.0.0/16"
Export:
Name: !Sub "${ProjectName}-vpc-cidr"
# Subnet
PublicSubnetA:
Value: !Ref PublicSubnetA
Export:
Name: !Sub "${ProjectName}-public-subnet-a"
PublicSubnetACIDR:
Value: "10.1.10.0/24"
Export:
Name: !Sub "${ProjectName}-public-subnet-a-cidr"
EC2インスタンス用
AWSTemplateFormatVersion: "2010-09-09"
Description:
EC2 Instance Create
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "ProjectName"
Parameters:
- ProjectName
- Label:
default: "EC2Instance Configuration"
Parameters:
- KeyPairName
- EC2InstanceAMI
- SSHAccessSourceIP
ParameterLabels:
KeyPairName:
default: "KeyPairName"
EC2InstanceAMI:
default: "AMI ID"
SSHAccessSourceIP:
default: "SSH AccessSourceIP"
# -------------------------------
# Input Parameters
# -------------------------------
Parameters:
ProjectName:
Type: String
# EC2Instance
KeyPairName:
Type: AWS::EC2::KeyPair::KeyName
Default: ""
EC2InstanceAMI:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
SSHAccessSourceIP:
Type: String
AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$'
Resources:
# -------------------------------
# IAM Role for EC2
# -------------------------------
EC2IAMRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: !Sub "${ProjectName}-WebServer-role"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- "ec2.amazonaws.com"
Action:
- "sts:AssumeRole"
Path: "/"
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"
- "arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess"
EC2InstanceProfile:
Type: "AWS::IAM::InstanceProfile"
Properties:
Path: "/"
Roles:
- Ref: EC2IAMRole
InstanceProfileName: !Sub "${ProjectName}-WebServer-profile"
# -------------------------------
# EC2Instance AZ-A
# -------------------------------
EC2Instance01:
Type: "AWS::EC2::Instance"
Properties:
Tags:
- Key: Name
Value: !Sub "${ProjectName}-WebServer-01"
ImageId: !Ref EC2InstanceAMI
InstanceType: "m4.large"
KeyName: !Ref KeyPairName
IamInstanceProfile: !Ref EC2InstanceProfile
SecurityGroupIds:
- !Ref ManagedSecurityGroup
- !Ref WebSecurityGroup
SubnetId: { "Fn::ImportValue": !Sub "${ProjectName}-public-subnet-a" }
HibernationOptions:
Configured: true
BlockDeviceMappings:
- DeviceName: "/dev/xvda"
Ebs:
DeleteOnTermination: true
VolumeType: "gp2"
VolumeSize: "30"
Encrypted: true
# -------------------------------
# SecurityGroup for Managed(SSH)
# -------------------------------
ManagedSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
VpcId: { "Fn::ImportValue": !Sub "${ProjectName}-vpc" }
GroupName: !Sub "${ProjectName}-managed-sg"
GroupDescription: "SecurityGroup for Managed"
Tags:
- Key: "Name"
Value: !Sub "${ProjectName}-managed-sg"
# Rule
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Ref SSHAccessSourceIP
# -------------------------------
# SecurityGroup for WebServer
# -------------------------------
WebSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
VpcId: { "Fn::ImportValue": !Sub "${ProjectName}-vpc" }
GroupName: !Sub "${ProjectName}-web-sg"
GroupDescription: "SecurityGroup for WebServer"
Tags:
- Key: "Name"
Value: !Sub "${ProjectName}-web-sg"
# -------------------------------
# ElasticIP for EC2Instance01
# -------------------------------
ElasticIP01:
Type: "AWS::EC2::EIP"
Properties:
Domain: vpc
ElasticIPAssociate01:
Type: AWS::EC2::EIPAssociation
Properties:
AllocationId: !GetAtt ElasticIP01.AllocationId
InstanceId: !Ref EC2Instance01
最後に
休止機能を使用する可能性があるインスタンスを作成する場合にもCloudFormationで構築できるようになったので、地味に嬉しいアップデートではないでしょうか!
以上、大阪オフィスのYui(@MayForBlue)でした(`・ω・´)
参考リンク
AWS CloudFormation を使用して、オンデマンドおよびリザーブドインスタンスの Amazon EC2 の休止機能を有効にする