[AWS CDK] S3 + CloudFrontの構築とOriginAccessIdentity周りについて

[AWS CDK] S3 + CloudFrontの構築とOriginAccessIdentity周りについて

2022-03-099 min read

目次

  1. 概要
  2. 構成のポイント
  3. cdk-stack
  4. 参考にしたサイト

概要

AWS CDK で S3 + cloudfront構成を構築しました。

その際のStackの実装メモです。

OriginAccessIdentity

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html

OriginAccessIdentityを利用することで、S3に直接アクセスされることなくcloudfrontのみからの参照に絞ることができます。

構成のポイント

  • AWS CDK v2を利用 (2.14.0)
  • CloudFront S3 を利用
  • S3へのアクセス制限はOriginAccessIdentityを利用

CDK Stack

実装

以下、Stackのソースです。

import {
  aws_cloudfront as cloudfront,
  aws_cloudfront_origins as cloudfrontOrigins,
  aws_iam as iam,
  aws_s3 as s3,
  aws_s3_deployment as s3deploy,
  Duration,
  RemovalPolicy,
  Stack,
  StackProps,
} from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class AppStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 'StaticContentsBucket', {
      bucketName: 'cloudfront-s3-test-20220309',
      removalPolicy: RemovalPolicy.DESTROY,
    });

    const oai = new cloudfront.OriginAccessIdentity(
      this,
      'OriginAccessIdentity',
    );

    bucket.addToResourcePolicy(
      new iam.PolicyStatement({
        actions: ['s3:GetObject'],
        effect: iam.Effect.ALLOW,
        principals: [
          new iam.CanonicalUserPrincipal(
            oai.cloudFrontOriginAccessIdentityS3CanonicalUserId,
          ),
        ],
        resources: [`${bucket.bucketArn}/*`],
      }),
    );

    new cloudfront.Distribution(this, 'Distribution', {
      comment: 'distribution for website',
      defaultRootObject: 'index.html',
      defaultBehavior: {
        allowedMethods: cloudfront.AllowedMethods.ALLOW_GET_HEAD,
        cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD,
        cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
        viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
        origin: new cloudfrontOrigins.S3Origin(bucket),
      },
      errorResponses: [
        {
          ttl: Duration.seconds(300),
          httpStatus: 403,
          responseHttpStatus: 403,
          responsePagePath: '/error.html',
        },
        {
          ttl: Duration.seconds(300),
          httpStatus: 404,
          responseHttpStatus: 404,
          responsePagePath: '/error.html',
        },
      ],
      priceClass: cloudfront.PriceClass.PRICE_CLASS_ALL,
    });
  }
}

deploy後のバケットポリシー

deploy後バケットポリシーを確認します。

Origin Access Identityが適用されており、直接バケットを参照できないような設定になっています。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXXXX"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::cloudfront-s3-test-20220309/*"
    }
  ]
}

deploy後のcloudfrontのorigin access identityの設定

aws cliが利用できる環境で次のコマンドでOAIを確認します。

echo "CNAME DomainName OAI[1] OAI[2] OAI[3]" > /tmp/awscli.tmp;\
aws cloudfront list-distributions --query "DistributionList.Items[].\
[Aliases.Items[0],\
DomainName, \
Origins.Items[0].S3OriginConfig.OriginAccessIdentity, \
Origins.Items[1].S3OriginConfig.OriginAccessIdentity, \
Origins.Items[2].S3OriginConfig.OriginAccessIdentity]" \
--output text >> /tmp/awscli.tmp;\
column -t /tmp/awscli.tmp;\
rm /tmp/awscli.tmp

実行後、以下の様にorigin access identityが適用されていたら成功です。

CNAME    DomainName                 OAI[1]                                            OAI[2]  OAI[3]
None     XXXXXXXXX.cloudfront.net   origin-access-identity/cloudfront/E31XXXXXXXXXXX  None    None
None     YYYYYYYYY.cloudfront.net   origin-access-identity/cloudfront/E31YYYYYYYYYYY  None    None
None     XXXXXXXXX.cloudfront.net   origin-access-identity/cloudfront/EHNXXXXXXXXXXX  None    None

origin access identtity が反映されない件について

上記のコードの

origin: new cloudfrontOrigins.S3Origin(bucket),

について反映されないという問題を耳にしました。

試したところ、macOS(v2.14.0)だと成功しwindows(wsl(v2.15.0))だと失敗しました。

はっきりとした理由までは分かりませんでした。

参考にしたサイト

Tags
javascript(110)
node.js(54)
linux(54)
amazon%20aws(47)
typescript(45)
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0(36)
%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86(30)
html5(29)
php(24)
centos(24)
python(22)
%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0(21)
mac(21)
mysql(20)
canvas(19)
opencv(17)
%E9%9B%91%E8%AB%87(16)
docker(16)
wordpress(15)
atcoder(14)
apache(12)
%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92(12)
%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9(12)
amazon%20s3(12)
red%20hat(12)
prisma(12)
ubuntu(11)
github(10)
git(10)
vue.js(10)
%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86100%E6%9C%AC%E3%83%8E%E3%83%83%E3%82%AF(10)
mariadb(10)
react(9)
aws%20cdk(9)
css3(8)
%E5%8F%AF%E8%A6%96%E5%8C%96(8)
%E5%B0%8F%E3%83%8D%E3%82%BF(8)
nestjs(8)
amazon%20lightsail(7)
next.js(7)
%E3%83%96%E3%83%AD%E3%82%B0(6)
cms(6)
oracle(6)
perl(6)
gitlab(6)
iam(5)
amazon%20ec2(5)
%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93(5)
aws%20amplify(5)
curl(4)
Author
githubzennqiita
ただの備忘録です。

※外部送信に関する公表事項