Cloud9 で AWS CDK Python を使ってみる

## 準備

必要なツール類の確認

```
$ node -v                                                                                                                                                                                 
v16.16.0
$ cdk --version 
2.32.1 (build 79cbe95)
$ python --version
Python 3.7.10
```

ディレクトリ(cdk)を作成し、移動する。

```
mkdir cdk && cd cdk
```

`cdk init` コマンドでプロジェクトを作成する。

```
cdk init sample-app --language python
```

仮想環境のアクティベート化。

```
source .venv/bin/activate
```

aws-cdk-lib と constructs のインストール。

```
pip install -r requirements.txt
```

`cdk bootstrap` コマンドで、CDKToolkitスタックをデプロイする。
***「CDKToolkit」が適用されているリージョンでは再度実行する必要はありません***

```
cdk bootstrap aws://<AWS アカウント　ID>/<リージョン>
```

このコマンドにより、CDKを利用するために必要なIAM、ECR、S3などの、Cloudformationスタック、CDKToolkit が作成されるようです。

![スクリーンショット 2022-07-27 19.27.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/f813c1a3-9176-9447-37d7-2510c657842d.png)

## やってみる1

`cdk/cdk_stack.py` でどのようなAWSリソースを構築していきたいかを記述する。とりあえずは、サンプルとしてあるものをそのまま使います。

```python:cdk/cdk_stack.py
from constructs import Construct
from aws_cdk import (
    Duration,
    Stack,
    aws_iam as iam,
    aws_sqs as sqs,
    aws_sns as sns,
    aws_sns_subscriptions as subs,
)


class CdkStack(Stack):

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

        queue = sqs.Queue(
            self, "CdkQueue",
            visibility_timeout=Duration.seconds(300),
        )

        topic = sns.Topic(
            self, "CdkTopic"
        )

        topic.add_subscription(subs.SqsSubscription(queue))
```

`cdk synth` コマンドを実行してみると、`cdk/cdk_stack.py` の、Cfnテンプレート化のyamlファイルとして出力される。

```yaml
$ cdk synth
Resources:
  CdkQueueBA7F247D:
    Type: AWS::SQS::Queue
    Properties:
      VisibilityTimeout: 300
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
    Metadata:
      aws:cdk:path: cdk/CdkQueue/Resource
  CdkQueuePolicy9CB1D142:
    Type: AWS::SQS::QueuePolicy
    Properties:
      PolicyDocument:
        Statement:
          - Action: sqs:SendMessage
            Condition:
              ArnEquals:
                aws:SourceArn:
                  Ref: CdkTopic7E7E1214
            Effect: Allow
            Principal:
              Service: sns.amazonaws.com
            Resource:
              Fn::GetAtt:
                - CdkQueueBA7F247D
                - Arn
        Version: "2012-10-17"
      Queues:
        - Ref: CdkQueueBA7F247D
    Metadata:
      aws:cdk:path: cdk/CdkQueue/Policy/Resource
  CdkQueuecdkCdkTopic33B437C257F995AC:
    Type: AWS::SNS::Subscription
    Properties:
      Protocol: sqs
      TopicArn:
        Ref: CdkTopic7E7E1214
      Endpoint:
        Fn::GetAtt:
          - CdkQueueBA7F247D
          - Arn
    Metadata:
      aws:cdk:path: cdk/CdkQueue/cdkCdkTopic33B437C2/Resource
  CdkTopic7E7E1214:
    Type: AWS::SNS::Topic
    Metadata:
      aws:cdk:path: cdk/CdkTopic/Resource
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:H4sIAAAAAAAA/1WNQQ6CMBBFz8K+HQUWHoALILg3UGocwRY6bQxpendpm5i4mf//y0umgrqCshg+xMU08wVH8L0dxMwOdPe0Efirk06y5qFySbfVC4r9B/MMjNTh924kYXC1qFU0/vZNrygiTSWEWDtJ2hmRfjRaTRjNwNrdPrU61XCB8ly8CJEbpyy+JXQ5vx+285q+AAAA
    Metadata:
      aws:cdk:path: cdk/CDKMetadata/Default
    Condition: CDKMetadataAvailable
Conditions:
  CDKMetadataAvailable:
    Fn::Or:
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - af-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-northeast-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-northeast-2
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-2
          - Fn::Equals:
              - Ref: AWS::Region
              - ca-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - cn-north-1
          - Fn::Equals:
              - Ref: AWS::Region
              - cn-northwest-1
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-north-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-2
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-3
          - Fn::Equals:
              - Ref: AWS::Region
              - me-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - sa-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-east-2
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - us-west-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-west-2
Parameters:
  BootstrapVersion:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /cdk-bootstrap/hnb659fds/version
    Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]
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.
```

`cdk deploy` コマンドでサンプルをデプロイし成功し、Cfnスタックを確認すると、リソースがデプロイされていることが確認できます。
![スクリーンショット 2022-07-26 20.12.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/27ee6ab6-7ef2-d410-d0ab-25a8cb3f16a3.png)

## やってみる2

せっかくなので、ドキュメントに沿って、SQSにプロパティを追加してみます。

**encryption (Optional[QueueEncryption])** – Whether the contents of the queue are encrypted, and by what type of key. Be aware that encryption is not available in all regions, please see the docs for current availability details. Default: Unencrypted

**queue_name (Optional[str])** – A name for the queue. If specified and this is a FIFO queue, must end in the string ‘.fifo’. Default: CloudFormation-generated name

https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_sqs/Queue.html

```python:cdk/cdk_stack.py
class CdkStack(Stack):

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

        queue = sqs.Queue(
            self, "CdkQueue",
            visibility_timeout=Duration.seconds(300), 
            encryption=sqs.QueueEncryption.KMS_MANAGED,    ##追加
            queue_name="cdksqs"                            ##追加
        )
```

`cdk synth` コマンドで確認します。

```yaml
Resources:
  CdkQueueBA7F247D:
    Type: AWS::SQS::Queue
    Properties:
      KmsMasterKeyId: alias/aws/sqs  ##追加
      QueueName: cdksqs              ##追加
      VisibilityTimeout: 300
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
    Metadata:
      aws:cdk:path: cdk/CdkQueue/Resource
```

`cdk deploy` コマンドでデプロイします。名前 と 暗号化 が更新されていることがわかります。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/2aed2a98-63b2-0331-9b0e-73ca23420d0c.png)