CDKを使い始めたときにつまずいた点とその記述例

CDK 初見では夢のようにすごいものだと感じたんですが、使っているうちにかゆいところに手が届きにくかったり（届かないとは言ってない単に情報を調べにくい）、単純に機能開発がまだだったりして現実に返ってきているところです。

でも CDK で書き変えたあとは最高なので CDK はやっぱり良い文化だと思います。

## この記事の対応バージョン

- CDK 1.7
- Python 3.6

CDK は BREAKING CHANGES がまだまだ起きているので、情報を調べるときはどのバージョンを使っていたときの記事かを確認しましょう。

[Releases · aws/aws\-cdk · GitHub](https://github.com/aws/aws-cdk/releases)

## CDK に対応 Class がないリソースを作りたいとき

[CfnResource — AWS Cloud Development Kit 1\.7\.0 documentation](https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.core/CfnResource.html)

かなりお世話になりました。

```python
core.CfnResource(
    self, "SampleTopic",
    type="AWS::SNS::Topic",
    properties={
        "DisplayName": "Sample Topic",
        "TopicName": "sample-topic"
    }
)
```

## CDK に専用クラスもあるけど Properties が足りないとき

[CfnTopic — AWS Cloud Development Kit 1\.7\.0 documentation](https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_sns/CfnTopic.html)

`CfnXxxx` のような名前のクラスだと CFn のテンプレートに近い Properties が用意されています。

```python
topic = sns.CfnTopic(
    self, "SampleTopic",
    display_name="Sample Topic",
    kms_master_key_id="Your KMS ID",
    topic_name="sample-topic"
)
topic.add_override(
    path="Properties.DisplayName",
    value="Sample Topic Override"
)
```

後述する `add_override` `add_property_override` での同じ効果を得ることができます。


## CDK に専用クラスはあるけど一部リソース内容を書き換えたいとき

[CfnResource — AWS Cloud Development Kit 1\.7\.0 documentation](https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.core/CfnResource.html)

`add_override` で書き換え可能です。

```python
topic = sns.Topic(
    self, "SampleTopic",
    display_name="Sample Topic",
    topic_name="sample-topic"
)
topic.node.default_child.add_override(
    path="Properties.DisplayName",
    value="Sample Topic Override"
)
```

Properties 内のみの上書きなら `add_property_override` も使えます。

## リソースの Condition を設定したいとき

[CfnCondition — AWS Cloud Development Kit 1\.7\.0 documentation](https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.core/CfnCondition.html)

`Conditions` セクションは `CfnCondition` を使って作成。

```python
app = core.App()
my_stack = MyStack(
    app, "my-stack"
)
core.CfnCondition(
    my_stack, "IsNotTokyo",
    expression=core.Fn.condition_not(
        core.Fn.condition_equals(core.Aws.REGION, "ap-northeast-1")
    )
)
```

リソースの `Condition` は専用のメソッドがないため `add_override` で付与します。

```python
topic = sns.Topic(
    self, "SampleTopic",
    display_name="Sample Topic",
    topic_name=f"sample-topic"
)
topic.node.default_child.add_override(
    path="Condition",
    value="IsNotTokyo"
)
```

## 作成済みのリソースを参照したいとき

[Topic — AWS Cloud Development Kit 1\.7\.0 documentation](https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_sns/Topic.html)

`from_topic_arn` を使って `ITopic` 型を得ることができます。

```python
sns.Topic.from_topic_arn(
    self, "SampleTopic",
    topic_arn=f"arn:aws:sns:{core.Aws.REGION}:{core.Aws.ACCOUNT_ID}:SampleTopic"
)
```

ただし、この `from_xxxx_arn` のようなメソッドはすべてのクラスにあるわけではないため、そこは注意必要です。

## Logical ID を指定してテンプレート変更時のリソース置き換えを防ぎたい

CDK で吐き出したテンプレートに置き換えたいときに、 `Logical ID` の固定化はほぼ必須事項ですね。

```python
topic.node.default_child.override_logical_id("SampleTopic")
```

## CDKをアップグレードしたのに一部ライブラリが古いままになっている

aws-cdkだけnpmでアップグレードすればいいと思っていたんですが、
これだけだとまだ古いままのライブラリを使い続けてしまうケースがありました。

```
npm install -g aws-cdk
```

公式ドキュメントに書いてあったのですが、言語ごとにアップグレードを（場合によっては複数回）行う必要があるようです。

```
pip install --upgrade aws-cdk.core
```

ちゃんと目的のバージョンが使われているかは、 `cdk.out/manifest.json` で確認できます。

```json
  "runtime": {
    "libraries": {
      "@aws-cdk/cx-api": "1.11.0",
      "@aws-cdk/core": "1.1.0",
      "@aws-cdk/region-info": "1.1.0",
      "@aws-cdk/aws-iam": "1.1.0",
      ...
      "@aws-cdk/aws-config": "1.11.0",
      "jsii-runtime": "Python/3.7.0"
    }
  }
```

どうしても更新できなかったら venv を作り直してしまうのもありです（pythonの場合）