はじめに
AWS リソース(CloudFront や S3)をアプリと同じように管理したいと思い「CloudFormation より簡単!?AWS CDK で楽々 IaC 実践」を参考に CDK で CloudFront + S3 環境を構築してみました。
対象読者
- AWS CDK を初めて使う方
- IaC(Infrastructure as Code)に興味がある方
- CloudFront + S3 の構成を手軽に試したい方
AWS CDK の基本概念
この記事を参考にしてください。
さっそく環境構築から
以降は Windows11 向けの解説です。その他の OS 利用者はダウンロード先やコマンドは必要に応じて読み替えて実行してください。
ステップ1:Node.js のインストール
> node -v && npm -v
v20.16.0
10.8.1
ステップ2:AWS CLIのインストール
> aws --version
aws-cli/2.15.15 Python/3.11.6 Windows/10 exe/AMD64 prompt/off
ステップ3:AWS認証情報の設定
3-1. IAMユーザーの作成とアクセスキーの設定
1. AWSマネジメントコンソールにログイン
2. IAMサービスにアクセス

4. ユーザー名欄に任意のユーザー名を入力し、「次へ」をクリック

5. 「ポリシーを直接アタッチする」を選択し、許可ポリシーで「AdministratorAccess」を検索してチェックし「次へ」をクリック

検証時は「AdministratorAccess」を設定していますが、実際の開発時は必要な権限のみ付与してください。
7. 作成したユーザーを選択して、「セキュリティ認証情報」タブの「アクセスキーを作成」をクリック

8. ユースケースから「コマンドラインインターフェイス (CLI)」を選択して、下部の確認マークをチェックして「次へ」をクリック

10. アクセスキーが作成されました!
作成されたアクセスキーは必ず .csv ファイルでダウンロードし保管してください。
AWSマネジメントコンソール等で確認できません。(忘れた場合は再作成となります。)
アクセスキーとシークレットアクセスキーは誰にも知られないように!
GitHub などの公開リポジトリにプッシュしてはいけません。
3-2. AWS CLIの設定
ターミナルで下記コマンドを実行し、認証情報を設定します
> aws configure
- AWS Access Key ID: 先ほど作成したアクセスキー
- AWS Secret Access Key: 先ほど作成したシークレットアクセスキー
- Default region name: リージョン指定 東京 (ap-northeast-1) にしました。
- Default output format: 出力結果の形式 初期値の json にしました。
もう一度 aws configure コマンドを実行すると再設定できます。
ステップ4:CDK のインストール
> npm install -g aws-cdk
> cdk --version
2.1100.1 (build db19110)
ステップ5:CDK環境の初期化(ブートストラップ)
> cdk bootstrap aws://ACCOUNT-NUMBER/REGION
ACCOUNT-NUMBER と REGION は、自分のAWSアカウント番号とリージョンに置き換えてください。
成功すると以下の通り CloudFormation で「CDKToolkit」という名前のスタックが作成されます。

「CDKToolkit」スタックにより作成されたバケットや IAM ロールは削除しないでください。
削除すると CDK が正常に機能しなくなります。
ステップ6:CDK プロジェクトの作成
1. 作業ディレクトリの作成
my-cdk-app というディレクトリを作成しています。
お好きな名前に変更してください。
> mkdir my-cdk-app && cd my-cdk-app
my-cdk-app>
2. CDK プロジェクトの作成
my-cdk-app> cdk init app --language=typescript
※成功すると my-cdk-app 内にいろいろファイルが作られます。
テンプレートの作成
以下 my-cdk-app で作成した場合の例です。該当の ts ファイルを修正してください。
必要に応じて読み替えて変更してください。
スタック(Stack)
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import {
aws_s3 as s3,
aws_cloudfront as cloudfront,
aws_cloudfront_origins as cloudfront_origins,
} from 'aws-cdk-lib';
export class S3CloudfrontStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const s3Bucket = new s3.Bucket(this, 'WebSiteBucket', {
bucketName: `s3-bucket-${cdk.Aws.ACCOUNT_ID}-${cdk.Aws.REGION}`,
autoDeleteObjects: true,
removalPolicy: cdk.RemovalPolicy.DESTROY,
// S3バケットのパブリックアクセスを拒否(デフォルト)
publicReadAccess: false,
websiteIndexDocument: 'index.html',
// S3へのパブリックアクセスを全て拒否(デフォルト)
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
});
const oac = new cloudfront.S3OriginAccessControl(this, 'OAC', {
originAccessControlName: `${id}-oac`,
// 認証の設定
// SIGV4:認証プロトコル(現状唯一)
// ALWAYS/NO_OVERRIDE:CloudFrontが認証するリクエストの選定
signing: cloudfront.Signing.SIGV4_ALWAYS,
});
const distribution = new cloudfront.Distribution(this, 'Distribution', {
// CloudFrontディストリビューションのデフォルト動作を各種設定
defaultBehavior: {
// オリジンの指定
origin: cloudfront_origins.S3BucketOrigin.withOriginAccessControl(
s3Bucket,{
originAccessLevels: [cloudfront.AccessLevel.READ],
},
),
},
// S3からではなくCloudFrontから配信するのでこちらでルートオブジェクトを指定
defaultRootObject: 'index.html',
});
const url = new cdk.CfnOutput(this, 'URL', {
value: distribution.domainName,
description: 'Website URL'
});
}
}
アプリ(App)
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
import { S3CloudfrontStack } from '../lib/my-cdk-app-stack';
const app = new cdk.App();
new S3CloudfrontStack(app, 'S3CloudfrontStack', {
});
デプロイ
my-cdk-app> cdk deploy
時間がかかりますので気長に待ちましょう!
成功すると以下の通り CloudFormation で「S3CloudfrontStack」という名前のスタックが作成されます。

S3 バケットの確認と index.html の作成
-
AWSマネジメントコンソールで S3 サービスにアクセスし「s3-bucket-XXXXX-リージョン」のバケットが作成されていることを確認します。

-
そのバケットに index.html をアップロードします。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TEST</title>
</head>
<body>
<h1>TEST</h1>
<p>テストページです。</p>
</body>
</html>
動作確認
OAC の確認
-
AWSマネジメントコンソールで S3 サービスにアクセスし、対象バケットの「プロパティ」→「静的ウェブサイトホスティング」から「バケットウェブサイトエンドポイント」をコピーします。

-
ご利用のブラウザで「バケットウェブサイトエンドポイント」にアクセスすると「403 Forbidden」が表示されます。(成功)

CloudFront 経由でアクセス
片付け
作成したリソースは cdk destroy で削除可能です。
S3 バケット内にファイルがあってもリソースは削除されました。
my-cdk-app> cdk destroy
まとめ
環境構築にてこずりましたが、先人たちの知恵に助けられました。
(参考サイトの方々、ありがとうございました。🙇♂️)
不要になった際、コマンド1つで削除できるのは、やっぱり便利ですね!
また yaml とは違い、条件分岐やループを活用できるそうなので、今後チャレンジしてみようと思います。
この記事が、誰かのお役に立てば幸いです。




