2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS CDKで学ぶIaCの基本 ― CloudFront + S3最小構成を作って壊してみる

2
Last updated at Posted at 2026-02-20

はじめに

社内R&Dの一環として、AWS CDKを用いてCloudFront + S3の最小構成で静的Webサイトを構築しました。
目的は以下です。

  • IaC(Infrastructure as Code)による構築手順の理解
  • 作成→削除のライフサイクル検証

システム構成

以下が今回構築した最小構成のアーキテクチャです。

開発環境

  • OS:Windows 11
  • エディタ:Visual Studio Code
  • AWS CLI:v2
  • AWS CDK:v2

CDKプロジェクト作成

1.作業用ディレクトリの作成

任意の作業場所で、以下のコマンドを実行します。

mkdir cdk-cloudfront-s3-sample
cd cdk-cloudfront-s3-sample

※ ディレクトリ名は任意ですが、
本記事ではcdk-cloudfront-s3-sampleとします。

2.TypeScriptテンプレートでCDKプロジェクト作成

以下のコマンドを実行します。

cdk init app --language typescript

このコマンドにより、CDKアプリケーションの雛形が生成され、
依存関係も自動的にインストールされます。

3.スタック作成

cdk init app --language typescript で生成された
lib/cdk-cloudfront-s3-sample-stack.ts を編集し、CloudFront + S3 の構成を実装します。

lib/cdk-cloudfront-s3-sample-stack.ts コード全体

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
import * as s3deploy from 'aws-cdk-lib/aws-s3-deployment';

export class CdkCloudfrontS3SampleStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // S3バケットを作成
    const bucket = new s3.Bucket(this, 'DemoSiteBucket', {
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, // バケットの公開アクセスを全てブロック
      encryption: s3.BucketEncryption.S3_MANAGED, // S3管理の暗号化を有効化
      removalPolicy: cdk.RemovalPolicy.DESTROY,  // スタック削除時にバケットも削除
      autoDeleteObjects: true, // バケット内オブジェクトも自動削除
    });

    // S3は非公開のまま、CloudFrontからのみ署名付きリクエストでアクセスさせるため
    // OAC(Origin Access Control)を使用する
    const s3Origin = origins.S3BucketOrigin.withOriginAccessControl(bucket);

    // CloudFrontディストリビューションを作成し、S3バケットをオリジンとして設定
    const dist = new cloudfront.Distribution(this, 'DemoDistribution', {
      defaultBehavior: {
        origin: s3Origin,
        viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
      },
      defaultRootObject: 'index.html',
    });

    // S3バケットにローカルの静的サイトコンテンツをデプロイ
    new s3deploy.BucketDeployment(this, 'DeployDemo', {
      sources: [s3deploy.Source.asset('./website-demo')], // ローカルのwebsite-demoディレクトリをソースとして指定
      destinationBucket: bucket, // 配置先のS3バケットを指定
      distribution: dist, // CloudFrontディストリビューションを指定して、デプロイ後にキャッシュを無効化
      distributionPaths: ['/*'], // CloudFrontの全パスのキャッシュを無効化
    });

    // CloudFrontのURLを出力
    new cdk.CfnOutput(this, 'CloudFrontUrl', {
      value: `https://${dist.distributionDomainName}`,
      description: 'CloudFront distribution URL',
    });
  }
}

OAC(Origin Access Control)
OACはCloudFrontがSigV4署名付きリクエストでS3へアクセスする仕組みです。
S3は公開せず、特定Distributionからのみアクセス可能にできます。

sources: [s3deploy.Source.asset('./website-demo')]
デモページとして、website-demo/index.html を用意しています。
BucketDeployment により、このディレクトリ配下の静的ファイルがS3へアップロードされます。

4.静的コンテンツの準備

CloudFront で配信するための、最小構成の静的コンテンツを用意します。

CDKプロジェクト(cdk-cloudfront-s3-sample)のルート直下にwebsite-demo ディレクトリを作成し、 その配下に index.html を作成します。

mkdir website-demo

website-demo/index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>CDK Demo</title>
</head>
<body>
  <h1>Hello, CloudFront + S3!</h1>
</body>
</html>

5.binファイル設定

bin配下のtsファイル(bin/cdk-cloudfront-s3-sample.ts)がアプリケーションのエントリポイントになります。
ここでスタックを読み込み、AWS CLI の設定に基づいてデプロイ対象の環境(account / region)を指定します。

以下のように編集してください。

bin/cdk-cloudfront-s3-sample.ts コード全体

#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
import { CdkCloudfrontS3SampleStack } from '../lib/cdk-cloudfront-s3-sample-stack';

const app = new cdk.App();

new CdkCloudfrontS3SampleStack(app, 'CdkCloudfrontS3SampleStack', {
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: process.env.CDK_DEFAULT_REGION,
  },
});

検証

1.デプロイ

以下のコマンドでスタックをデプロイします。

cdk deploy CdkCloudfrontS3SampleStack --profile <プロファイル名>

--profile で指定した AWS CLI プロファイルに、利用するアカウントおよびリージョンが設定されている前提です。

確認プロンプトについて

cdk deploy および cdk destroy 実行時には、以下のような確認プロンプトが表示される場合があります。

... (y/n)

処理はこの入力待ちで一時停止するため、続行する場合は y を入力してください。

デプロイ完了後、CloudFrontのURLがログに出力されます。

Outputs:
CdkCloudfrontS3SampleStack.CloudFrontUrl = https://xxxxx.cloudfront.net

このURLにアクセスすることで、デプロイした静的サイトを確認できます。

必要に応じて、以下のコマンドでも出力値を確認できます。

aws cloudformation describe-stacks --stack-name CdkCloudfrontS3SampleStack --query "Stacks[0].Outputs" --output table --region <リージョン名> --profile <プロファイル名>

検証ポイント
CloudFrontのURLから正常にデモページが表示されることを確認しました。

S3直アクセスが拒否されることを確認

S3に配置された index.html を、S3のオブジェクトURLから直接取得します。
その結果、403 AccessDenied となり、S3が非公開であることを確認できます。

curl -i https://<bucket>.s3.ap-northeast-1.amazonaws.com/index.html
# HTTP/1.1 403 Forbidden
# ~
# <Error><Code>AccessDenied</Code>~

上記の <bucket> には、実際に作成されたS3バケット名を指定します。

S3バケット名の確認方法
バケット名は、AWSコンソールから確認できます。

  • AWSコンソール → S3 → CDKで作成された対象バケットを選択

※ S3バケット名は、スタック名およびリソースの論理IDを元に、一意な名前として自動生成されます。

2.再デプロイ

index.html を修正後、再度 cdk deploy を実行します。

検証ポイント
CloudFrontのURLは変更されないことを確認しました。

3.削除

以下のコマンドでスタックを削除します。

cdk destroy CdkCloudfrontS3SampleStack --profile <プロファイル名>

削除後、以下のコマンドでスタックが存在しないことを確認

aws cloudformation describe-stacks --stack-name CdkCloudfrontS3SampleStack --region <リージョン名> --profile <プロファイル名>

検証ポイント
削除済みの場合、以下のようなエラーが表示されます。

An error occurred (ValidationError) when calling the DescribeStacks operation: Stack with id CdkCloudfrontS3SampleStack does not exist

このエラーは、スタックが正常に削除されていることを示しています。

4.削除後の再デプロイ

再度デプロイを実行。

検証ポイント
削除前とは異なるURLが発行されていることを確認しました。

今回の検証で分かったこと

  • AWS CDKを使うことで、インフラをコードで定義し、コマンド実行により環境を構築できる。
  • OACを利用することで、S3を公開せずCloudFront経由のみでアクセス可能な構成にできる。
  • destroyしない限りCloudFrontのURLは変わらず、削除後の再デプロイでは新しいURLが発行される。
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?