この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
CloudFormationにインポート機能が追加されたことで作成済みスタックのリファクタリングができるようになりました。今回は実際にリファクタリングしてみたいと思います。
目次
概要
上記のように1つのスタックですべてのリソースを管理しているとします。これを下記のように2つのスタックに分割したいと思います。分割の方針としてはネットワークレイヤとアプリケーションレイヤというイメージです。
準備
1つのテンプレートでリソースを作成
すべてのリソースが1つのテンプレートで作成されている状態にします。下記のテンプレートをdemo.ymlとして保存します。今回はマネジメントコンソールを利用し、スタック名をdemo-stack
とします。これで準備は完了です。
demo.yml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
# VPC
DemoVpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:
- Key: Name
Value: demo-vpc
# サブネット
DemoPriSubnet:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: 'ap-northeast-1a'
CidrBlock: 10.0.1.0/24
VpcId: !Ref DemoVpc
Tags:
- Key: Name
Value: demo-pri-subnet
# セキュリティグループ
DemoSG:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: DemoSG
GroupName: demo-sg
VpcId: !Ref DemoVpc
Tags:
- Key: 'Name'
Value: 'demo-sg'
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: '80'
ToPort: '80'
CidrIp: 0.0.0.0/0
#インスタンス
DemoWeb:
Type: 'AWS::EC2::Instance'
Properties:
ImageId: 'ami-079e6fb1e856e80c1'
InstanceType: 't2.micro'
SecurityGroupIds:
- !GetAtt DemoSG.GroupId
SubnetId: !Ref DemoPriSubnet
Tags:
- Key: 'Name'
Value: 'demo-web'
リファクタリング
リソースが削除されないようにする
これからリファクタリングを行っていきますが、このまま管理外にするとセキュリティグループとEC2が削除されてしまいます。管理外にする前にDeletionPolicy
属性をRetain
に更新します。これによりテンプレートからリソースの記述を削除した場合でもリソースが保持されます。下記が更新したdemo.ymlです。
demo.yml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
# VPC
DemoVpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:
- Key: Name
Value: demo-vpc
# サブネット
DemoPriSubnet:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: 'ap-northeast-1a'
CidrBlock: 10.0.1.0/24
VpcId: !Ref DemoVpc
Tags:
- Key: Name
Value: demo-pri-subnet
# セキュリティグループ
DemoSG:
Type: "AWS::EC2::SecurityGroup"
DeletionPolicy: Retain # ← 追加行
Properties:
GroupDescription: DemoSG
GroupName: demo-sg
VpcId: !Ref DemoVpc
Tags:
- Key: 'Name'
Value: 'demo-sg'
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: '80'
ToPort: '80'
CidrIp: 0.0.0.0/0
#インスタンス
DemoWeb:
Type: 'AWS::EC2::Instance'
DeletionPolicy: Retain # ← 追加行
Properties:
ImageId: 'ami-079e6fb1e856e80c1'
InstanceType: 't2.micro'
SecurityGroupIds:
- !GetAtt DemoSG.GroupId
SubnetId: !Ref DemoPriSubnet
Tags:
- Key: 'Name'
Value: 'demo-web1'
マネジメントコンソールからdemo-stack
を選択 → 「更新する」→「既存のテンプレートを置き換える」→「テンプレートファイルのアップロード」より上記の更新したテンプレートをアップロードします。
「変更はありません」と表示されていますが、そのままスタックを更新します。
イベントを確認するとEC2とセキュリティグループが更新されていることがわかります。
スタックから分割するリソースを管理外にする
リソースを管理外にするにはテンプレートからリソースを削除してスタックを更新します。下記はEC2とセキュリティグループの記述を削除したものです。加えて、分割するテンプレートからVPCとサブネットをクロススタック参照できるように、VPCとSubnetのIDを出力しています。
demo-nw.yml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
# VPC
DemoVpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:
- Key: Name
Value: demo-vpc
# サブネット
DemoPriSubnet:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: 'ap-northeast-1a'
CidrBlock: 10.0.1.0/24
VpcId: !Ref DemoVpc
Tags:
- Key: Name
Value: demo-pri-subnet
Outputs:
DemoVpc:
Value: !Ref DemoVpc
Export:
Name: DemoVpc
DemoPriSubnet:
Value: !Ref DemoPriSubnet
Export:
Name: DemoPriSubnet
demo-nw.yml
として保存し、先程と同じようにテンプレートをアップロードしてスタックを更新します。
変更セットにはEC2インスタンスとセキュリティグループが削除されると表示されていますが、このまま更新します。
イベントを確認するとEC2インスタンスとセキュリティグループはDELETE_SKIPPED
となっており実際には削除されていないことが確認できます。EC2画面でも確認してみてください。
管理外にしたリソースをあたらしいスタックにインポート
新しいスタック用に下記のテンプレートをdemo-app.yml
として保存します。VpcId
、SubnetId
をImportValue
にしています。また、インポートするリソースはDeletionPolicy
をRetain
にする必要があります。
demo-app.yml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
# セキュリティグループ
DemoSG:
Type: "AWS::EC2::SecurityGroup"
DeletionPolicy: Retain
Properties:
GroupDescription: DemoSG
GroupName: demo-sg
VpcId: !ImportValue DemoVpc
Tags:
- Key: 'Name'
Value: 'demo-sg'
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: '80'
ToPort: '80'
CidrIp: 0.0.0.0/0
#インスタンス
DemoWeb:
Type: 'AWS::EC2::Instance'
DeletionPolicy: Retain
Properties:
ImageId: 'ami-079e6fb1e856e80c1'
InstanceType: 't2.micro'
SecurityGroupIds:
- !GetAtt DemoSG.GroupId
SubnetId: !ImportValue DemoPriSubnet
Tags:
- Key: 'Name'
Value: 'demo-web'
次に「既存のリソースを仕様(リソースをインポート)」を選択します。
「概要をインポート」では「次へ」をクリック
上記テンプレートをアップロードし「次へ」をクリック
インポートするEC2インスタンスのInstanceId
とセキュリティグループのGroupId
を入力し「次へ」をクリック
スタック名にdemo-app-stack
と入力し「次へ」をクリック
変更にEC2インスタンスとセキュリティグループがImport
と表示されていることを確認し「リソースをインポート」をクリック
IMPORT_COMPLETE
と表示されたらリソースを確認します。EC2インスタンスとセキュリティグループが管理下にあることが確認できます。
最初に作成したスタックにはVPCとサブネットのみが管理下に置かれています。
これでリファクタリングは完了です。
まとめ
スタックがリファクタリングできることを確認しました。巨大なスタックを管理している場合は分割することでメンテナンスしやすくなることもあります。運用にお困りの方はリファクタリングを検討してみてはいかがでしょうか。
ただ、運用環境で行う場合は、事前に検証を行ってください。