なつねこメモ

主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ

書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。

2018/10/27

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

カテゴリー:AWSTypeScript

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


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

【awslabs 探訪】AWS Cloud Development Kit (AWS CDK)を使ってみた | DevelopersIO

一週間ほど前の更新の 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:012345678901: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 することで反映できます。

では~。