
AWS CDKでReactアプリをデプロイしてみた
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
AWS CDK (Cloud Development Kit) でS3とCloudFrontを利用したReactアプリのデプロイ方法を説明します。S3バケットへのアップロードからCloudFrontのキャッシュ削除までAWS CDKだけで出来ます。
なお、Reactに限らずAngularやVue.jsなど他のSPAの場合も同じような手順になります。
開発環境
| パッケージ名 | バージョン | 
| typescript | 3.7.2 | 
| aws-cdk | 1.20.0 | 
| @aws-cdk/aws-cloudfront | 1.20.0 | 
| @aws-cdk/aws-s3 | 1.20.0 | 
| @aws-cdk/aws-s3-deployment | 1.20.0 | 
| react | 16.12.0 | 
デプロイ手順
- AWS CDKをインストール
 - AWS CDKでデプロイ用のコードを書く
 - Create React AppでWEBアプリを作成
 - AWS CDKでデプロイ
 
やってみた
AWS CDKをインストール
AWS CDKをインストールします。
npm i -g aws-cdk
プロジェクトを作成します。
mkdir aws-cdk-deploy-react cd aws-cdk-deploy-react cdk init app --language=typescript
AWS CDKでデプロイ用のコードを書く
必要なパッケージをインストールします。
npm install @aws-cdk/aws-cloudfront @aws-cdk/aws-s3 @aws-cdk/aws-s3-deployment --save
デプロイ用のコードを書きます。
import * as cdk from '@aws-cdk/core';
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 iam from '@aws-cdk/aws-iam'
export class AwsCdkDeployReactStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    const websiteBucket = new s3.Bucket(this, 'WebsiteBucket', {
      websiteErrorDocument: 'index.html',
      websiteIndexDocument: 'index.html',
    });
    const websiteIdentity = new cloudfront.OriginAccessIdentity(
      this,
      'WebsiteIdentity',
    );
    const webSiteBucketPolicyStatement = new iam.PolicyStatement({
      actions: ['s3:GetObject'],
      effect: iam.Effect.ALLOW,
      principals: [
        websiteIdentity.grantPrincipal,
      ],
      resources: [`${websiteBucket.bucketArn}/*`],
    });
    websiteBucket.addToResourcePolicy(webSiteBucketPolicyStatement);
    const websiteDistribution = new cloudfront.CloudFrontWebDistribution(
      this,
      'WebsiteDistribution',
      {
        errorConfigurations: [
          {
            errorCachingMinTtl: 300,
            errorCode: 403,
            responseCode: 200,
            responsePagePath: '/index.html',
          },
          {
            errorCachingMinTtl: 300,
            errorCode: 404,
            responseCode: 200,
            responsePagePath: '/index.html',
          },
        ],
        originConfigs: [
          {
            s3OriginSource: {
              s3BucketSource: websiteBucket,
              originAccessIdentity: websiteIdentity,
            },
            behaviors: [
              {
                isDefaultBehavior: true,
              },
            ],
          },
        ],
        priceClass: cloudfront.PriceClass.PRICE_CLASS_ALL,
      },
    );
    new s3deploy.BucketDeployment(this, 'WebsiteDeploy', {
      sources: [s3deploy.Source.asset('./web/build')],
      destinationBucket: websiteBucket,
      distribution: websiteDistribution,
      distributionPaths: ['/*'],
    });
  }
}
aws-s3-deploymentのBucketDeploymentはローカルのファイルをS3バケットにデプロイします。また、distributionとdistributionPathsを指定することでCloudFrontのキャッシュ削除まで実行してくれます。
Create React AppでWEBアプリを作成
Reactアプリを作成します。tsconfig.jsonやpackage.jsonの競合を避けるため、プロジェクトのルートディレクトリに別のディレクトリを作成します。
npx create-react-app web --typescript # 新しいバージョンの場合 # npx create-react-app web --template typescript cd web npm run build cd ../
AWS CDKでデプロイ
CDKでデプロイするためのS3バケットを作成するため、最初の1回だけcdk bootstrapを実行します。
cdk bootstrap
tsconfig.jsonのexcludeにReactアプリのディレクトリを追加します。
{
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
  "exclude": ["cdk.out", "web"]
}
CDKのソースコードをビルドします。
npm run build
デプロイします。初回デプロイは完了までに10分ほど時間がかかります。
cdk deploy
デプロイ後、CloudFrontのドメインでアクセスすると、以下のような画面が表示されます。

試しにEdit src/App.tsx and save to reload.をHello World!に変更してデプロイしてみます。
cd web vim src/App.tsx # 内容を書き換え npm run build cd ../ cdk deploy
画面を更新するとHello World!が表示されることを確認できました。
まとめ
これまでCloudFormationとAWS CLIで実装していたデプロイが、AWS CDKだけで実現できるようになりました。キャッシュの削除もコンソールから手動で行う必要がなくなり、デプロイする際の負担が軽減されました。
参考
AWS CDK が GA! さっそく TypeScript でサーバーレスアプリケーションを構築するぜ【 Cloud Development Kit 】
[AWS CDK]S3へローカルファイルをデプロイしてWebサイトを公開する








