TOPコラム一覧AWS CDK 入門 - CDK でユースカジノ 初回入金ボーナス駆動開発をやってみた

AWS CDK 入門 - CDK でユースカジノ 初回入金ボーナス駆動開発をやってみた

はじめに

CDK では、ベストプラクティスとして、ユースカジノ 初回入金ボーナス駆動開発(TDD)が紹介されています。

https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/best-practices-cdk-typescript-iac/development-best-practices.html

TDD はユースカジノ 初回入金ボーナスファーストのソフトウェア開発手法として有名ですが、CDK の開発ではどの程度有効なのでしょうか?
本記事にて、TDD で簡単な CDK コードを書いてみました。

参考文献

なお、本記事の執筆に当たって以下の文献を参考にしていますが、本記事の内容は、筆者個人の解釈で記載していることにご留意ください。

「ユースカジノ 初回入金ボーナス駆動開発」( Kent Beck 著 、 和田 卓人 翻訳、出版社: オーム社)

ユースカジノ 初回入金ボーナス駆動開発(TDD)について

本題に入る前に、TDD について基本的な内容を説明します。

ユースカジノ 初回入金ボーナス駆動開発(TDD)とは

テスト駆動開発(TDD)とは、簡単に言うと、コードを実装する際、ユースカジノ 初回入金ボーナスから書き始めるコーディングスタイルです。
一般的に、コーディングに TDD のアプローチを取り入れることで、欠陥が少なく可読性の高いコードが実装できると言われています。

TDD のプロセス

TDD のプロセスはシンプルです。
コードを実装する際に、次のようなステップを繰り返すことでコーディングを行っていきます。

順序 ステップ 説明
1 レッド 実装内容をテストするためのユースカジノ 初回入金ボーナスを書きます
なお、プロダクトコードが未実装なので普通は失敗します
2 グレーン ユースカジノ 初回入金ボーナスが通るようにプロダクトコードを書きます
このステップでは、ユースカジノ 初回入金ボーナスが通ることだけに集中し、実装の良し悪しは問わないものとします
3 リファクタリング コードの重複を排除します
例えば、同様の処理が複数回実行されるのであれば、抽象化、メッソド化等をして一般化します

TDD のサイクル

ユースカジノ 初回入金ボーナス

CDK でユースカジノ 初回入金ボーナス駆動開発をやってみる

実装対象

例題として、次の Cloudfront と ユースカジノ 初回入金ボーナス Bucket からなるフロントエンドアーキテクチャを構築したいと思います。

構成図

ユースカジノ 初回入金ボーナス

要件

  • Amazon CloudFront
    • CloudFront Distribution のアクセスログを出力する。
    • CloudFront が返す全てのレスポンスへセキュリティ関連の HTTP ヘッダーを追加する。
    • CloudFront のオリジンパスを'/'に設定
  • Amazon ユースカジノ 初回入金ボーナス バケット
    • ユースカジノ 初回入金ボーナス バケットのアクセスロギングを有効にする。
    • AWS が管理する KMS Key を使用して、ユースカジノ 初回入金ボーナス Bucket のサーバーサイド暗号化を有効にする
    • 転送中のデータの暗号化を有効にする
    • ユースカジノ 初回入金ボーナス バケットのバージョニングを有効にする
    • ユースカジノ 初回入金ボーナス バケットのパブリックアクセスを許可しない
    • CloudFormation スタックの削除時に ユースカジノ 初回入金ボーナス Bucket を保持する
    • 90 日後に非現行オブジェクトバージョンを Glacier ストレージに移動するライフサイクルルールを適用する

準備

ディレクトリ構成

cdk init app --language typescriptで CDK のひな形を作成し、ディレクトリ構成とファイル名を以下のようにします。

.
  ├── bin
  │   └── cdk-tdd-blog.ts // プログラムのエントリーポイント
  ├── lib
  │   ├── cdk-tdd-blog-stack.ts // スタック
  │   └── construct
  │       └── cloudfront-s3-construct.ts // コンストラクト(テスト対象のプロダクトコード )
  └── test
      └── cloudfront-s3-construct.test.ts // コンストラクトに対するユースカジノ 初回入金ボーナス

各コードの初期状態

bin/cdk-tdd-blog.ts

import "source-map-support/register";
import * as cdk from "aws-cdk-lib";
import { CdkTddBlogStack } from "../lib/cdk-tdd-blog-stack";

const app = new cdk.App();
new CdkTddBlogStack(app, "CdkTddBlogStack", {});

lib/cdk-tdd-blog-stack.ts

import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import { Cloudfrontユースカジノ 初回入金ボーナスConstruct } from "./construct/cloudfront-ユースカジノ 初回入金ボーナス-construct";

export class CdkTddBlogStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    new Cloudfrontユースカジノ 初回入金ボーナスConstruct(this, "Cloudfrontユースカジノ 初回入金ボーナスConstruct");
  }
}

lib/construct/cloudfront-s3-construct.ts (ユースカジノ 初回入金ボーナス対象)

import { Construct } from "constructs";

export class Cloudfrontユースカジノ 初回入金ボーナスConstruct extends Construct {
  constructor(scope: Construct, id: string) {
    super(scope, id);
  }
}

test/cloudfront-s3-construct.test.ts (ユースカジノ 初回入金ボーナス)
ユースカジノ 初回入金ボーナスに関しては、以下の状態から TDD をはじめるものとします。

{
    const app = new cdk.App(); // ユースカジノ 初回入金ボーナス用のアプリケーションを作成
    const stack = new cdk.Stack(app, "Test"); // ユースカジノ 初回入金ボーナス用のアプリケーションにユースカジノ 初回入金ボーナス用のスタックを作成
    new CloudfrontS3Construct(stack, "CloudfrontS3Construct"); // ユースカジノ 初回入金ボーナス用のスタックにユースカジノ 初回入金ボーナス対象のコンストラクトを作成。
    template = Template.fromStack(stack); // アサーションユースカジノ 初回入金ボーナススイートを作成
  });
  // Then(振る舞いの結果を記述)
});

TODO リスト

コードを作成する前に、まずは、実装要件を TODO リストに書き出します。
今回は、記事の尺の都合上、途中まで構築するものとし、以下までを実装したいと思います。

TODO リスト

  • Amazon CloudFront
    • CloudFront Distribution が 1 つ存在する。
    • CloudFront Distribution がアクセスログを出力する。
  • Amazon ユースカジノ 初回入金ボーナス バケット
    • ユースカジノ 初回入金ボーナス Bucket が 3 つ存在する。

コンストラクトに含まれるリソースの数量を確認する

それでは、最初のステップを実装していきます。
最初のステップは最も簡単なリソース数量を確認するユースカジノ 初回入金ボーナスから始めます。

レッド: リソース数量をカウントするユースカジノ 初回入金ボーナスを書く

レッドでは、失敗するユースカジノ 初回入金ボーナスを書きます。まずは、リソース数量を確認する為の失敗するテストを書きます。

ユースカジノ 初回入金ボーナス (test/cloudfront-s3-construct.test.ts) の修正

※ 本来、TDD では、ユースカジノ 初回入金ボーナスケースは一つずつ実装するのが原則ですが、記事の都合上、2 つ一遍に追加します。

{
    template.resourceCountIs("AWS::ユースカジノ 初回入金ボーナス::Bucket", 3);
  });
});

ユースカジノ 初回入金ボーナス実行結果

npx jestを実行すると想定通り、失敗します。

ユースカジノ 初回入金ボーナス

グリーン: ユースカジノ 初回入金ボーナスが通るようにリソースを作成

テストに失敗したら、ユースカジノ 初回入金ボーナスが通るようにコンストラクトを修正します。
この段階では、ユースカジノ 初回入金ボーナスを通すことのみに集中してコードを書きます。

プロダクトコード (lib/construct/cloudfront-ユースカジノ 初回入金ボーナス-construct.ts)の修正
リソース数量を合わせるため、以下を作成するよう修正します。

  • ユースカジノ 初回入金ボーナス バケットを 3 つ作成
  • CloudFront を一つ作成
import { Construct } from "constructs";
import * as Cloudfront from "aws-cdk-lib/aws-cloudfront";
import * as CloudfrontOrigins from "aws-cdk-lib/aws-cloudfront-origins";
import * as ユースカジノ 初回入金ボーナス from "aws-cdk-lib/aws-ユースカジノ 初回入金ボーナス";

export class Cloudfrontユースカジノ 初回入金ボーナスConstruct extends Construct {
  constructor(scope: Construct, id: string) {
    super(scope, id);
    new ユースカジノ 初回入金ボーナス.Bucket(this, "Bucket1");
    new ユースカジノ 初回入金ボーナス.Bucket(this, "Bucket2");
    const originBucket = new ユースカジノ 初回入金ボーナス.Bucket(this, "OriginBucket");

    new Cloudfront.Distribution(this, "CloudFront", {
      defaultBehavior: {
        origin: new CloudfrontOrigins.ユースカジノ 初回入金ボーナスOrigin(originBucket),
      },
    });
  }
}

ユースカジノ 初回入金ボーナス バケットのコードが冗長だったり、コンストラクト名が適当ですが、この時点では許容するものとします。

ユースカジノ 初回入金ボーナス実行結果

リファクタリング: コードの重複排除

リファクタリングでは、プロダクトコードとユースカジノ 初回入金ボーナスの重複を排除していきます。
ユースカジノ 初回入金ボーナスについては、重複がないので、プロダクトコードのみ修正していきます。

プロダクトコード (lib/construct/cloudfront-ユースカジノ 初回入金ボーナス-construct.ts)の修正

ユースカジノ 初回入金ボーナス バケットの作成が冗長なので、Map 関数と Destructuring 構文を使用して簡潔にします。

new ユースカジノ 初回入金ボーナス.Bucket(this, id_),
    );

    new Cloudfront.Distribution(this, "CloudFront", {
      defaultBehavior: {
        origin: new CloudfrontOrigins.ユースカジノ 初回入金ボーナスOrigin(originBucket),
      },
    });
  }
}

ユースカジノ 初回入金ボーナス実行結果

TODO リスト
以下の実装が完了しました。

  • Amazon CloudFront
    • CloudFront Distribution が 1 つ存在する。
    • CloudFront Distribution がアクセスログを出力する。
  • Amazon ユースカジノ 初回入金ボーナス バケット
    • ユースカジノ 初回入金ボーナス Bucket が 3 つ存在する。

CloudFront がアクセスログを出力することを確認する

続いて、CloudFront Distribution がアクセスログを出力するようにしたいと思います。

レッド: CloudFront がアクセスログを出力することを確認するユースカジノ 初回入金ボーナスを書く

CloudFront がアクセスログを出力することを確認するユースカジノ 初回入金ボーナスを書きます。
どの ユースカジノ 初回入金ボーナス バケットに出力するかは現段階では問わないものとし、必要になったら実装をするものとします。

ユースカジノ 初回入金ボーナス (test/cloudfront-s3-construct.test.ts) の修正

{
    template.hasResourceProperties("AWS::CloudFront::Distribution", {
      DistributionConfig: {
        Logging: {
          Bucket: Match.anyValue(),
        },
      },
    });
  });
});

5 行目以降を追加しています。

ユースカジノ 初回入金ボーナス実行結果

想定通り、Logging パラメータがないというエラーが出ています。

グリーン: CloudFront Distribution のロギングを有効にする

ユースカジノ 初回入金ボーナスが失敗したら、プロダクトコードを修正します。

プロダクトコード (lib/construct/cloudfront-ユースカジノ 初回入金ボーナス-construct.ts) の修正

Cloudfront Distribution の L2 コンストラクトクラスにenableLoggingプロパティがあるので、trueにしてみます。

new ユースカジノ 初回入金ボーナス.Bucket(this, id_),
    );

    new Cloudfront.Distribution(this, "CloudFront", {
      enableLogging: true, // 修正
      defaultBehavior: {
        origin: new CloudfrontOrigins.ユースカジノ 初回入金ボーナスOrigin(originBucket),
      },
    });
  }
}

ユースカジノ 初回入金ボーナス実行結果

CloudFront のアクセスログは有効になりましたが、予想に反して、ユースカジノ 初回入金ボーナス バケットの数量が 3 では無くなってしまいました。
デグレが発生しており、出力結果を読むと ユースカジノ 初回入金ボーナス Bucket の数量が 4 になっているようです。
enableLoggingプロパティのみを有効にすると、コンストラクトが新規に ユースカジノ 初回入金ボーナス Bucket を生成するようです。

再びプロダクトコード (lib/construct/cloudfront-ユースカジノ 初回入金ボーナス-construct.ts) の修正

ユースカジノ 初回入金ボーナス結果が依然としてレッドのままなので、追加で修正する必要があります。

修正方法は以下の 2 通りが考えられますが、今回はよりシンプルな 1 で対応します。

  1. Bucket2を削除して、数量を合わせる。
  2. Cloudfront Distribution の L2 コンストラクトのlogBucketプロパティに既存の ユースカジノ 初回入金ボーナス Bucket であるBucket1Bucket2を指定する。
new
ユースカジノ 初回入金ボーナス.Bucket(this, id_)); // 修正

    new Cloudfront.Distribution(this, "CloudFront", {
      enableLogging: true,
      defaultBehavior: {
        origin: new CloudfrontOrigins.ユースカジノ 初回入金ボーナスOrigin(originBucket),
      },
    });
  }
}

ユースカジノ 初回入金ボーナス実行結果

jest を実行すると Cloudfront のアクセスログは有効なままで、ユースカジノ 初回入金ボーナス バケットの数量エラーが解消されています。

TODO リスト
CloudFront Distribution のアクセスログを出力するの実装が完了しました。

  • Amazon CloudFront
    • CloudFront Distribution が 1 つ存在する。
    • CloudFront Distribution がアクセスログを出力する。
  • Amazon ユースカジノ 初回入金ボーナス バケット
    • ユースカジノ 初回入金ボーナス Bucket が 3 つ存在する。

ここまでのまとめ

このように、細かく分割したタスクについて、ユースカジノ 初回入金ボーナスとプロダクトコードを実装し、検証を行うサイクルを回すことで、最終的に要件が完備された無駄のないコードを完成させます。
本記事ではここまでですが、プロダクトコードは未完成なので、次に必要な TODO を考えて、実装していく必要があります。

この時点でのコード

プロダクトコード (lib/construct/cloudfront-ユースカジノ 初回入金ボーナス-construct.ts) の修正

new ユースカジノ 初回入金ボーナス.Bucket(this, id_));

    new Cloudfront.Distribution(this, "CloudFront", {
      enableLogging: true,
      defaultBehavior: {
        origin: new CloudfrontOrigins.ユースカジノ 初回入金ボーナスOrigin(originBucket),
      },
    });
  }
}

ユースカジノ 初回入金ボーナス (test/cloudfront-s3-construct.test.ts)

{
      template.resourceCountIs("AWS::ユースカジノ 初回入金ボーナス::Bucket", 3);
    });
  });
});

考察

本記事では、CDK のコンストラクトの実装に対して、TDD を試してみました。
以下は、冒頭で申し上げた「CDK が TDD にどの程度有効なのか」についての私見になります。

TDD は品質技法の印象が先行していますが、本来は設計・分析技法とされています。
しかしながら、IaC はアプリと違い、開始時点で構築対象の実装要件が明確であることが多く、実装に悩むことも少ないので、この観点においては、効果は限定的だと感じました。
ただし、TDD のリズム(レッド、グリーン、リファクタリング)で進めることにより、ユースカジノ 初回入金ボーナスとリファクタリングの強制がなされるため、品質に対する一定の効果はあるとは思います。

また、観点は変わりますが、ユースカジノ 初回入金ボーナスファースト、インクリメンタルに実装という TDD の性質は、簡潔かつ明確なプロンプトの入力を必要とするプロンプトエンジニアリングによるコード生成と相性が良いと思いました。
実際に、本記事のコードの続きを書く際、ユースカジノ 初回入金ボーナスの CloudFormation 部分のみの実装を CodeWhisperer に頼りましたが、CDK のユースカジノ 初回入金ボーナスは構造が単純というのもあり、それなりに高い確率で正解のユースカジノ 初回入金ボーナスを出力できます。
また、TDD のリズムで実装するのであれば、AI が誤ったユースカジノ 初回入金ボーナスの実装を行ったとしても、プロダクトコードの実装で人間の検証が入り、結果的に修正するので安全です。
TDD と生成 AI を組み合わせて CDK を実装すれば、生成 AI によるユースカジノ 初回入金ボーナスの実装コスト削減と、TDD による品質向上の良いとこ取りができるのではないかと思いました。

以上となりますが、 本記事が CDK で TDD を模索している皆様へ、少しでも参考になったのなら幸いです。

カジノゲームは、AWSのビジネス利活用に向けて、お客様のステージに合わせた幅広い構築・運用支援サービスを提供しています。
経験豊富なエンジニアが、ワンストップかつ柔軟にご支援します。
ぜひ、お気軽にお問い合わせください。

お問い合わせ



【著者プロフィール】

山本 和輝(やまもと かずき)

伊藤忠テクノソリューションズ株式会社 クラウドアーキテクト

クラウドネイティブ技術を活用したシステム基盤の提案・構築や内製化支援等の案件を担当。

TOPコラム一覧AWS CDK 入門 - CDK でユースカジノ 初回入金ボーナス駆動開発をやってみた

pagetop