Skip to content

AWS CDKでS3/Cloud Front/Route53でドメイン設定

公開日

概要

勉強がてらRoute53でドメインを契約したのでCDKでCloudFrontに設定する。

DnsValidatedCertificateがdeprecatedになったのでCertificateに置き換えたらクロスリージョン対応が必要になったメモ - Qiita
概要Route53とCloudFrontの紐づけとSSL証明書の発行をCDKを使って行ったメモ や AWS CDK v2を使ってSPA用のCloudFrontをデプロイしたメモ では、Route5…
DnsValidatedCertificateがdeprecatedになったのでCertificateに置き換えたらクロスリージョン対応が必要になったメモ - Qiita favicon https://qiita.com/hibohiboo/items/82e5ed43754a41f60108
DnsValidatedCertificateがdeprecatedになったのでCertificateに置き換えたらクロスリージョン対応が必要になったメモ - Qiita

上記Qiita記事にあるように DnsValidatedCertificate が非推奨になっており、推奨される実装ではクロスリージョン参照が必要になった。 初学者レベルだとまとまった手順がなかなか見つからず見事にハマったのでメモ。

CDK実装

余計なことせず最低限のことだけ実装。

アプリケーション

bin/domain-setteing-cdk.ts
#!/usr/bin/env node
import * as cdk from "aws-cdk-lib";
import {
  Certificate,
  CertificateValidation,
} from "aws-cdk-lib/aws-certificatemanager";
import "source-map-support/register";
import { DomainSetteingCdkStack } from "../lib/domain-setteing-cdk-stack";
 
const app = new cdk.App();
// スタックに対してアカウント・リージョンを指定する
// https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/configure-env.html#configure-env-how
const defaultEnv = {
  account: process.env.CDK_DEFAULT_ACCOUNT,
  region: process.env.CDK_DEFAULT_REGION,
};
// ドメインとデブロイ先のサブドメインを指定
const domainName = "kubozu.com";
const deployDomain = `bootcamp.${domainName}`;
 
// 証明書はus-east-1リージョンで作成する
// クロスリージョン参照を有効にする
const usStack = new cdk.Stack(app, `FrontCdkUsStack`, {
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: "us-east-1",
  },
  crossRegionReferences: true,
});
 
// Route53のホストゾーンを取得する
const zone = cdk.aws_route53.HostedZone.fromLookup(usStack, `hosted-zone`, {
  domainName: domainName,
});
 
// ホストゾーンに対してACMで証明書を作成する
const cert = new Certificate(usStack, `${domainName}-certificate`, {
  domainName: deployDomain,
  validation: CertificateValidation.fromDns(zone),
});
 
// ドメイン設定を行うスタックを作成
// 東京リージョンのS3バケットにCloudFrontを設定する
// クロスリージョン参照を有効にする
const domainSettingsStack = new DomainSetteingCdkStack(
  app,
  "DomainSetteingCdkStack",
  {
    env: defaultEnv,
    deployDomain: deployDomain,
    cert: cert,
    zone: zone,
    crossRegionReferences: true,
  }
);
// 依存関係を設定
domainSettingsStack.addDependency(usStack);
 

スタック

S3にアップロードするファイルはワークショップで配布されているものを利用。

Workshop Studio
Discover and participate in AWS workshops and GameDays
Workshop Studio favicon https://catalog.us-east-1.prod.workshops.aws/workshops/a9b0eefd-f429-4859-9881-ce3a7f1a4e5f/ja-JP/step1-webhosting/challenge1

静的コンテンツとしてzipがあるので "./lib/contents" 配下に配置。

(propsが雑)

lib/domain-setteing-cdk-stack.ts
import * as cdk from "aws-cdk-lib";
import { Certificate } from "aws-cdk-lib/aws-certificatemanager";
import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
import * as cloudfront_origins from "aws-cdk-lib/aws-cloudfront-origins";
import { ARecord, IHostedZone, RecordTarget } from "aws-cdk-lib/aws-route53";
import { CloudFrontTarget } from "aws-cdk-lib/aws-route53-targets";
import { BlockPublicAccess, Bucket } from "aws-cdk-lib/aws-s3";
import { BucketDeployment } from "aws-cdk-lib/aws-s3-deployment";
import { Construct } from "constructs";
 
interface DomainSetteingCdkStackProps extends cdk.StackProps {
  deployDomain: string;
  cert: Certificate;
  zone: IHostedZone;
}
 
export class DomainSetteingCdkStack extends cdk.Stack {
  constructor(
    scope: Construct,
    id: string,
    props: DomainSetteingCdkStackProps
  ) {
    super(scope, id, props);
 
    // s3 webサイト用バケット
    const bucketName = "任意のS3バケット名を指定";
    //
    const s3Bucket = new Bucket(this, "DomainSetteingS3Bucket", {
      bucketName: bucketName,
      blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
      autoDeleteObjects: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      websiteIndexDocument: "index.html",
    });
 
    // CloudFront ディストリビューションの作成
    // defaultBehaviorで色々指定しているが
    // origin
    // domainNames
    // certificate ※ドメイン指定する場合に証明書が必要
    // が重要
    const distribution = new cloudfront.Distribution(this, "Distribution", {
      defaultRootObject: "index.html",
      defaultBehavior: {
        origin:
          // S3 バケットへの OAC によるアクセス制御を設定
          cloudfront_origins.S3BucketOrigin.withOriginAccessControl(s3Bucket),
        allowedMethods: cloudfront.AllowedMethods.ALLOW_GET_HEAD,
        cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD,
        cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
        viewerProtocolPolicy:
          cdk.aws_cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
        responseHeadersPolicy:
          cdk.aws_cloudfront.ResponseHeadersPolicy.SECURITY_HEADERS,
      },
      httpVersion: cdk.aws_cloudfront.HttpVersion.HTTP2_AND_3,
      priceClass: cdk.aws_cloudfront.PriceClass.PRICE_CLASS_ALL,
      domainNames: props.deployDomain ? [props.deployDomain] : undefined,
      certificate: props.deployDomain ? props.cert : undefined,
    });
 
    // CloudFront Distribution の URL を出力
    new cdk.CfnOutput(this, "DistributionUrl", {
      value: `https://${distribution.distributionDomainName}`,
    });
 
    // s3バケットにWebサイト用のファイルをアップロード
    // ファイルはワークショップより取得したもの
    //
    new BucketDeployment(this, `${bucketName}-deploy-with-invalidation`, {
      sources: [cdk.aws_s3_deployment.Source.asset("./lib/contents")],
      destinationBucket: s3Bucket,
      // distribution: props.
      distribution: distribution,
      distributionPaths: ["/*"],
    });
 
    // Route53のエイリアスレコードでCloudFrontを指す
    new ARecord(this, "AliasRecord", {
      zone: props.zone,
      recordName: props.deployDomain,
      target: RecordTarget.fromAlias(new CloudFrontTarget(distribution)),
      ttl: cdk.Duration.minutes(900),
    });
  }
}
 

依存関係と生成順、リージョンの配置先に誤りがあるとデプロイ時にエラーになる。
不慣れなせいもあるがエラーの情報から追いにくく、Github Copilotに聞いても見当違いな修正案を提案してくるので地力が必要だと痛感…

いきなりワークショップやり始めないで以下読んでおけばよかったと思った。

【AWS グラレコ解説】使い慣れたプログラミング言語でクラウド環境を構築 ! AWS CDK をグラレコで解説 - builders.flash☆ - 変化を求めるデベロッパーを応援するウェブマガジン | AWS
クラウド環境のプロビジョニングと開発を効率化するためのオープンソースのソフトウェア開発フレームワーク、AWS CDK をグラレコで紹介します。
【AWS グラレコ解説】使い慣れたプログラミング言語でクラウド環境を構築 ! AWS CDK をグラレコで解説 - builders.flash☆ - 変化を求めるデベロッパーを応援するウェブマガジン | AWS favicon https://aws.amazon.com/jp/builders-flash/202309/awsgeek-aws-cdk/
【AWS グラレコ解説】使い慣れたプログラミング言語でクラウド環境を構築 ! AWS CDK をグラレコで解説 - builders.flash☆ - 変化を求めるデベロッパーを応援するウェブマガジン | AWS