【AWS】CDKでApi Gatewayを`cdk deploy`コマンドで自動デプロイまで実現する方法

# 概要
AWS CDKでApi Gatewayを構築後、何度もエンドポイントを追加・削除したりする検証作業をしていると

「毎回管理コンソールに行ってデプロイボタン押すの面倒だなぁ...」

と思うことありませんでしょうか。

`cdk deploy`コマンドで一緒にデプロイまでしてくれたらいいのにな、と思い、調査してみたところ、実現できたので、紹介します。

# 方法
調べてみると、aws公式のrepostで紹介されていました。

https://repost.aws/questions/QUAH1opLNSQVWFFnKpF-1ZTQ/the-problem-of-updating-the-apigateway-stage-in-aws-cdk

上記記事によれば、自動でデプロイさせたい場合は、以下ののような方法があるらしい

```typescript
    this.myApi = new apig.RestApi(this, 'MyApi', {
      deploy: false,
    });
    // force APIG deployment to be recreated every time even if no changes
    const prodDeploy = new apig.Deployment(this, 'MyApiProdDeployment' + new Date().toISOString(), {
      api: this.myApi,
      description: 'prod deployment',
    })
    this.myApiStage = new apig.Stage(this, 'MyApiProdStage', {
      deployment: prodDeploy,
      metricsEnabled: true,
      loggingLevel: apig.MethodLoggingLevel.INFO,
      stageName: this.STAGE_NAME,
    })
    this.myApi.deploymentStage = this.myApiStage;
```
        
大事な部分は`new Date().toISOString()`の箇所です。

Python形式の方が慣れているので、Pythonで記述すると以下のようになります。

```py
        api = apigateway.RestApi(self, "Sample-ApiGateway",
            rest_api_name="Sample-ApiGateway",
            description="sample-api-gateway",
            cloud_watch_role=False, # 自動生成をオフ
            deploy=False
        )

        apigateway.CfnAccount(self, "Sample-ApiGatewayAccount",
            cloud_watch_role_arn=api_gateway_role.role_arn
        )

        deployment = apigateway.Deployment(self, "Sample-ApiDeployment-{datetime.now().isoformat()}",
            api=api,
            description="prod deployment"
        )

        stage = apigateway.Stage(self, "Sample-ApiStage",
            deployment=deployment,
            stage_name="prod",
            logging_level=apigateway.MethodLoggingLevel.INFO,
            data_trace_enabled=True,
            access_log_destination=apigateway.LogGroupLogDestination(api_gateway_log_group),
            access_log_format=apigateway.AccessLogFormat.json_with_standard_fields(
                caller=True,
                http_method=True,
                ip=True,
                protocol=True,
                request_time=True,
                resource_path=True,
                response_length=True,
                status=True,
                user=True
            )
        )

        api.deployment_stage = stage

```

まず、`deploy=False`にすることで、デフォルトのデプロイメントとステージは作成されなくなります。
代わりに、デプロイメントとステージを手動で作成するのが後半の記述です。

そして`datetime.now().isoformat()`を使用しているのは、
apigateway.Deployment の ID に現在の日時を含めることで、
毎回異なるデプロイメントが作成されるようにするためです。

`datetime.now().isoformat()`の部分がない場合、新しいデプロイメントが走りません。
新しくリソースを作成した場合などに自動でデプロイされなくなってしまいます。
（上述のtypescriptのrepostでは`new Date().toISOString()`の箇所に該当）


## 備忘
ちなみに`stage_name`に何も指定しないでデプロイした場合は自動で`prod`ステージが作成されます。
CDK公式ドキュメントにも記載あり

> Deployments
By default, the RestApi construct will automatically create an API Gateway Deployment and a “prod” Stage which represent the API configuration you defined in your CDK app. This means that when you deploy your app, your API will have open access from the internet via the stage URL.


https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_apigateway/README.html