【AWS CDK (Python)】 デプロイするリージョンを指定する方法

## はじめに
本記事は、私自身の備忘録を兼ねてAWS CDKをこれから始める方の一助になればと思い、AWS CDKの使い方等をまとめたものです。
今回は、AWS CDKを実行する際にデプロイするリージョンを指定する方法を確認しています。
なお、本記事は私自身の経験を基に記載していますが、間違いがあったらすみません。

## デプロイするリージョンを指定したい状況
AWS CDKでリソースをデプロイする際にメインのリージョンではなく他のリージョンを指定しないといけない状況が発生します。
例えば、
・S3でクロスリージョンレプリケーション先のバケットを作成する場合
・CloudFront用のWAF WebAclsやCloudWatchアラームを作成する場合
などです。
このようにリージョンを跨ってCDKスタックを実行する方法を確認します。

## 環境
本記事は以下の環境を使用して記載しています。
* AWS Cloud9
* AWS CDK：2.80.0
* Python： 3.10.11
* Node.js： 16.20.0

また、以下の記事に基づいてAWS CDKの環境を作成しています。
* [【AWS CDK/Python】 AWS CDKの始め方](https://qiita.com/takataka987/items/4448dbf06d8c70173305)

## デプロイするリージョンを指定する方法
では、本題のCDKスタックを実行する際にリージョンを指定する方法を確認します。今回は、S3バケットを東京リージョンと大阪リージョンそれぞれに作成したいと思います。
リージョンを指定するには、app.pyでStackオブジェクトを作成する際に`env`パラメータでリージョンを指定することで可能です。
app.py、cdk_app/cdk_app_stack.pyをそれぞれ以下のようにしました。
app.pyで、リージョンに東京リージョン(ap-northeast-1)を指定しています。また、cdk_app/cdk_app_stack.pyでは、バケット名にリージョンを付けるようにしました。
```python：app.py
#!/usr/bin/env python3
import os
import aws_cdk as cdk
from cdk_app.cdk_app_stack import CdkAppStack

app = cdk.App()

CdkAppStack(app, "CdkAppStack-1",
        env={
            'region': "ap-northeast-1"
        },
    )

app.synth()
```

```python:cdk_app/cdk_app_stack.py
from aws_cdk import (
    Stack,
    aws_s3 as s3,
    RemovalPolicy
)
from constructs import Construct
import random, string

class CdkAppStack(Stack):

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

        region = kwargs["env"]["region"]

        s3bucket = s3.Bucket(
            self,
            "MyS3Bucket-" + region,
            bucket_name = "cdk-test-bucket-" + region,
            versioned=True,
            removal_policy=RemovalPolicy.DESTROY
        )
```

この状態でプロビジョニングします。
```console
(.venv) user_name:~/environment/cdk-app (master) $ cdk deploy

✨  Synthesis time: 19.05s

(中略)
CdkAppStack-1: deploying... [1/1]
CdkAppStack-1: creating CloudFormation changeset...

 ✅  CdkAppStack-1

✨  Deployment time: 36.61s

Stack ARN:
(中略)

✨  Total time: 55.66s
```

マネージメントコンソールからS3バケットを確認してみると、東京リージョンで作成されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445559/87cc633e-5d6d-3da0-2745-e234304e72bb.png)

次に、app.pyを修正して、S3バケットを作成するスタックを追加し、追加したスタックには大阪リージョン(ap-northeast-3)を指定します。
```python：app.py
#!/usr/bin/env python3
import os
import aws_cdk as cdk
from cdk_app.cdk_app_stack import CdkAppStack

app = cdk.App()

CdkAppStack(app, "CdkAppStack-1",
        env={
            'region': "ap-northeast-1"
        },
    )
# ↓↓ スタックを追加＆リージョンを大阪リージョンに指定
CdkAppStack(app, "CdkAppStack-2",
        env={
            'region': "ap-northeast-3"
        },
    )

app.synth()
```

では、デプロイしてみます。（スタックが複数になったので、`cdk deploy`の際は`--all`を付けています。）
```console
(.venv) user_name:~/environment/cdk-app (master) $ cdk diff
Stack CdkAppStack-1
There were no differences
Stack CdkAppStack-2
Parameters
[+] Parameter BootstrapVersion BootstrapVersion: {"Type":"AWS::SSM::Parameter::Value<String>","Default":"/cdk-bootstrap/xxxxxxxxx/version","Description":"Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"}

Resources
[+] AWS::S3::Bucket MyS3Bucket-ap-northeast-3 MyS3Bucketapnortheast3XXXXXXXX 

Other Changes
[+] Unknown Rules: {"CheckBootstrapVersion":{"Assertions":[{"Assert":{"Fn::Not":[{"Fn::Contains":[["1","2","3","4","5"],{"Ref":"BootstrapVersion"}]}]},"AssertDescription":"CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."}]}}

(.venv) user_name:~/environment/cdk-app (master) $ cdk deploy --all

✨  Synthesis time: 16.95s

(中略)
CdkAppStack-1: deploying... [1/2]

 ✅  CdkAppStack-1 (no changes)

✨  Deployment time: 0.31s

Stack ARN:
(中略)

✨  Total time: 17.26s

(中略)
CdkAppStack-2: deploying... [2/2]
CdkAppStack-2: creating CloudFormation changeset...

 ✅  CdkAppStack-2

✨  Deployment time: 36.57s

Stack ARN:
(中略)

✨  Total time: 53.52s
```

マネージメントコンソールからS3バケットを確認してみると、先ほど作成した東京リージョンのS3バケットとは別に大阪リージョンでも新しくS3バケットが作成されていることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445559/db82a412-07eb-2fad-40e4-93f9cc04d4af.png)

## まとめ
AWS CDKでデプロイの際にリージョンを指定する方法を確認しました。スタックを作成する際にリージョンをパラメータで渡すだけなので簡単ですね。スタックの中でリージョンを跨いでリソースを作成することはできませんので、複数リージョンでリソースを作成する場合は、リージョン毎にスタックを分けましょう。
最後まで読んでいただいてありがとうございます。
少しでも参考になれば幸いです。
#### 参考文献
* [AWS Cloud Development Kit (AWS CDK) v2デベロッパーガイド](https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/home.html)
* [AWS CDK Python Reference](https://docs.aws.amazon.com/cdk/api/v2/python/index.html)