AWS CDKを使って複数リージョンにデプロイしてみる
2019-07-13

僕の中でCloudformationの不満点の一つに複数リージョンへの対応のイマイチ感がありました。一つのコードベースで複数リージョンを扱うことが難しい(無理?)と思っています。
( aws cloudformation deploy を複数回実行すればいいけどソレジャナイ感)

AWS CDKが無事GAされたということで, こちらでどうなのか試してみました。

Create an App with Multiple Stacks

ドキュメントに記載されています!
Create an App with Multiple Stacks

pythonの方が慣れているのでpythonで書き直して試していきたいと思います。

Getting Started

まずは cdk init していきます。


$ mkdir app/
$ cd app/
$ npx cdk init app --language python
$ rm -rf .env/

このときカレントディレクトリにファイルやディレクトリがあるとエラーが出てしまうのでクリーンな状態から実行するようにしましょう。

cdk init cannot be run in a non-empty directory!

virtualenvの環境は自前で準備済みなので, cdkが用意してくれた使わないファイル類は削除しています。

あとはガーッと書いていきます。
とりあえずEC2インスタンスを立てるだけにします。

  • requirements.txt

aws-cdk.core
aws-cdk.aws-ec2

$ pip install -r requirements.txt
  • app/app_stack.py

from aws_cdk import (
    aws_ec2 as ec2,
    core
)


class AppStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        image_id = ec2.AmazonLinuxImage(
            generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2).get_image(self).image_id
        ec2.CfnInstance(self,
                        'test-instance',
                        image_id=image_id
                        )

from aws_cdk import core
from app.app_stack import AppStack


app = core.App()
AppStack(app, "app-us-east-1", env={"region": "us-east-1"})
AppStack(app, "app-ap-northeast-1", env={"region": "ap-northeast-1"})
app.synth()

cdk コマンドで確認/実行していきます。

まず差分を取ってみます。何もデプロイしていない状態なので全てが差分表示されています。


$ npx cdk diff
Stack app-ap-northeast-1
Parameters
[+] Parameter SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter: {"Type":"AWS::SSM::Parameter::Value<String>","Default":"/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"}

Resources
[~] AWS::EC2::Instance test-instance testinstance replace
 └─ [+] ImageId (requires replacement)
     └─ {"Ref":"SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter"}

Stack app-us-east-1
Parameters
[+] Parameter SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter: {"Type":"AWS::SSM::Parameter::Value<String>","Default":"/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"}

Resources
[+] AWS::EC2::Instance test-instance testinstance

デプロイしてみます。


$ npx cdk deploy
Since this app includes more than a single stack, specify which stacks to use (wildcards are supported)
Stacks: app-ap-northeast-1 app-us-east-1

スタックを指定しないとダメだよとのエラーです。
ワイルドカード指定ができるようなので指定します。


$ npx cdk deploy '*'
app-ap-northeast-1
app-ap-northeast-1: deploying...
app-ap-northeast-1: creating CloudFormation changeset...
 0/3 | 23:18:07 | CREATE_IN_PROGRESS   | AWS::EC2::Instance | test-instance (testinstance)
 0/3 | 23:18:08 | CREATE_IN_PROGRESS   | AWS::CDK::Metadata | CDKMetadata
 0/3 | 23:18:09 | CREATE_IN_PROGRESS   | AWS::EC2::Instance | test-instance (testinstance) Resource creation Initiated
 0/3 | 23:18:11 | CREATE_IN_PROGRESS   | AWS::CDK::Metadata | CDKMetadata Resource creation Initiated
 1/3 | 23:18:11 | CREATE_COMPLETE      | AWS::CDK::Metadata | CDKMetadata
 2/3 | 23:18:42 | CREATE_COMPLETE      | AWS::EC2::Instance | test-instance (testinstance)
 3/3 | 23:18:44 | CREATE_COMPLETE      | AWS::CloudFormation::Stack | app-ap-northeast-1

 ✅  app-ap-northeast-1

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:252861321711:stack/app-ap-northeast-1/d70a2870-a4af-11e9-a079-068e2b92c6b0
app-us-east-1
app-us-east-1: deploying...
app-us-east-1: creating CloudFormation changeset...
 0/3 | 23:19:06 | CREATE_IN_PROGRESS   | AWS::CDK::Metadata | CDKMetadata
 0/3 | 23:19:07 | CREATE_IN_PROGRESS   | AWS::EC2::Instance | test-instance (testinstance)
 0/3 | 23:19:08 | CREATE_IN_PROGRESS   | AWS::CDK::Metadata | CDKMetadata Resource creation Initiated
 0/3 | 23:19:08 | CREATE_IN_PROGRESS   | AWS::EC2::Instance | test-instance (testinstance) Resource creation Initiated
 1/3 | 23:19:08 | CREATE_COMPLETE      | AWS::CDK::Metadata | CDKMetadata
 2/3 | 23:19:41 | CREATE_COMPLETE      | AWS::EC2::Instance | test-instance (testinstance)
 3/3 | 23:19:42 | CREATE_COMPLETE      | AWS::CloudFormation::Stack | app-us-east-1

 ✅  app-us-east-1

Stack ARN:
arn:aws:cloudformation:us-east-1:252861321711:stack/app-us-east-1/fad33ad0-a4af-11e9-be2f-0a0bad6f0bfa

無事コマンド一つで複数リージョンにデプロイできたようです!
リスト表示と再度diffをとって差分がないことを確認します。


$ npx cdk list
app-ap-northeast-1
app-us-east-1

$ npx cdk diff
Stack app-ap-northeast-1
There were no differences
Stack app-us-east-1
There were no differences

問題なさそうなのであとは忘れずにdestroyしておきます。


$ npx cdk destroy '*' --force

まとめ

  • 複数リージョン対応も簡単
  • 今回は同じ内容で複数リージョンにデプロイしたけど, 異なる内容でも問題なし
  • AWS CDKやってこうという気になった