1
2

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 リソース(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サービスにアクセス
IAM


3. 「ユーザー」→「ユーザーを追加」をクリック
ユーザーを追加


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


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

検証時は「AdministratorAccess」を設定していますが、実際の開発時は必要な権限のみ付与してください。

6. 「ユーザーの作成」をクリック
ユーザーの作成


7. 作成したユーザーを選択して、「セキュリティ認証情報」タブの「アクセスキーを作成」をクリック
アクセスキーの作成


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


9. 「アクセスキーを作成」をクリック
アクセスキーを作成


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-NUMBERREGION は、自分の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)

my-cdk-app/lib/my-cdk-app-stack.ts
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)

my-cdk-app/bin/my-cdk-app.ts
#!/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」という名前のスタックが作成されます。
deploy

S3 バケットの確認と index.html の作成

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

  2. そのバケットに index.html をアップロードします。

index.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>TEST</title>
    </head>
    <body>
        <h1>TEST</h1>
        <p>テストページです。</p>
    </body>
</html>

動作確認

OAC の確認

  1. AWSマネジメントコンソールで S3 サービスにアクセスし、対象バケットの「プロパティ」→「静的ウェブサイトホスティング」から「バケットウェブサイトエンドポイント」をコピーします。
    バケットウェブサイトエンドポイント

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


CloudFront 経由でアクセス

  1. AWSマネジメントコンソールで CloudFront サービスにアクセスし、対象ディストリビューションの「ディストリビューションドメイン名」をコピーします。
    ディストリビューションドメイン名

  2. ご利用のブラウザで「ディストリビューションドメイン名」にアクセスすると作成したテストページが表示されます。(成功)
    テストページ


片付け

作成したリソースは cdk destroy で削除可能です。
S3 バケット内にファイルがあってもリソースは削除されました。

my-cdk-app> cdk destroy

まとめ

環境構築にてこずりましたが、先人たちの知恵に助けられました。
(参考サイトの方々、ありがとうございました。🙇‍♂️)
不要になった際、コマンド1つで削除できるのは、やっぱり便利ですね!
また yaml とは違い、条件分岐やループを活用できるそうなので、今後チャレンジしてみようと思います。
この記事が、誰かのお役に立てば幸いです。

参考サイト

1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?