みかづきメモ

プログラミング学習帳 ♪(✿╹ヮ╹)ノ 書いてあるコードは自己責任でご自由にどうぞ

AWS Cloud Development Kit で静的サイトをデプロイしたい

aws-cdk の更新をそこそこウォッチしているのですが、
最近のアップデートでファイルを投げることに対応していたので、やってみようと思います。


AWS CDK 自体の説明については、こちらの記事が詳しいです。

dev.classmethod.jp

一週間ほど前の更新の v0.13.0 で S3 Bucket Deployment 用のパッケージが追加されました。
このパッケージを使うことで、ビルドしたファイルなどを簡単に S3 へアップロードできます。

環境

  • AWS CDK v0.14.1 (TypeScript)
  • Node.js 10.12.0

AWS 側の構成は、

  • Certificate Manager (証明書作成済み)
  • CloudFront (ドメイン対応)
  • S3

AWS CDK での ACM は、 DNS 認証に対応していないようなので、自前で生成しておき、
そのときの証明書の ARN を控えておきます。

必要パッケージのインストール

デプロイするために必要なパッケージ類をインストールしていきます。
初めから入っているもの (SNS あたり) は全部消しちゃって OK です。

$ yarn add @aws-cdk/aws-certificatemanager @aws-cdk/aws-cloudfront @aws-cdk/aws-s3 @aws-cdk/aws-s3-deployment @aws-cdk/cdk

デプロイしたいファイル (ビルド成果物など) は、 objects ディレクトリに入れることにします。

$ ls -l
~\projects\cdk-autodeploy\objects>ls -l           
total 21                                                                    
-rw-r--r-- 1 mikazuki 197609 3086 Oct 27 17:14 become_a_patron_button.png
-rw-r--r-- 1 mikazuki 197609 6579 Oct 27 17:15 become_a_patron_button@2x.png
-rw-r--r-- 1 mikazuki 197609 6542 Oct 12 23:24 busy_banner.png

あとは構成を TypeScript コードで書いていきます。
私はこんな感じになりました。

#!/usr/bin/env node

import * as path from "path";

import * as cloudfront from "@aws-cdk/aws-cloudfront";
import * as s3 from "@aws-cdk/aws-s3";
import * as s3Deploy from "@aws-cdk/aws-s3-deployment";
import * as cdk from "@aws-cdk/cdk";

class GrahamStack extends cdk.Stack {
    constructor(parent: cdk.App, name: string, props?: cdk.StackProps) {
        super(parent, name, props);

        const bucket = new s3.Bucket(this, `GrahamS3`, {
            bucketName: "static.mochizuki.moe",
        });
        new s3Deploy.BucketDeployment(this, `GrahamS3BucketDeployment`, {
            // 先ほどデプロイしたいファイルを置いた場所を設定
            source: s3Deploy.Source.asset(path.resolve("./", "objects")),
            destinationBucket: bucket,
        });

        const originId = new cloudfront.cloudformation.CloudFrontOriginAccessIdentityResource(this, `OriginAccessIdentity`, {
            cloudFrontOriginAccessIdentityConfig: {
                comment: "static.mochizuki.moe"
            },
        });

        new cloudfront.CloudFrontWebDistribution(this, `GrahamCloudFront`, {
            aliasConfiguration: {
                // ACM で作成した証明書の ARN
                acmCertRef: "arn:aws:acm:us-east-1:011761533955:certificate/58d7ec39-e8d6-40c6-8697-5f6733be0b5b",
                names: ["static.mochizuki.moe"],
                sslMethod: cloudfront.SSLMethod.SNI,
                securityPolicy: cloudfront.SecurityPolicyProtocol.TLSv1_2_2018,
            },
            originConfigs: [
                {
                    s3OriginSource: {
                        s3BucketSource: bucket,
                        // CloudFront 側で再度適用する必要があります
                        originAccessIdentity: originId,
                    },
                    behaviors: [
                        { isDefaultBehavior: true }
                    ]
                }
            ],
            priceClass: cloudfront.PriceClass.PriceClass200,
        });
    }
}

const app = new cdk.App();

new GrahamStack(app, "GrahamStack");

app.run();

CloudFront と S3 のアクセス権限周りでは、 CDK だけではうまくいかないようなので、
CloudFront コンソールが側で「Yes, Update Bucket Policy」を押下する必要があります。

あとは、 yarn run build した後、 cdk deploy コマンドを叩くことでデプロイされます。
ちなみに、 objects 以下を変更した場合、もう一度 cdk deploy することで反映できます。

では~。