1
1

OACのL2 Constructを使って、CloudFront+S3での静的コンテンツ配信をやってみた

Last updated at Posted at 2024-09-08

はじめに

AWSサービスを用いて静的コンテンツを配信する場合、S3とCloudFrontを組み合わせて構築することが一般的かと思いますが、この際セキュリティを強化するためにOAC(Origin Access Control)の設定が推奨されています。OACを設定することで、S3バケットへの直接的なアクセスを防ぎ、CloudFront経由の安全なアクセスだけを許可することが可能となります。
上記の構成をCDKで構築する場合、L2 Constructが提供されていなかったため、構築が少し手間でした。しかし、CDKのバージョン2.156.0から、OACのL2 Constructがサポートされるようになりました。これにより簡単にOACを構成できるようになったので、早速試してみました。

OACとは

OAC(Origin Access Control)とは、CloudFrontとS3バケット間のセキュアなアクセスを制御するための仕組みです。元々OAI(Origin Access Identity)という方法があったのですが、現在ではOACの方が推奨される方法となっています。
詳しくは下記の記事をご覧ください。
https://dev.classmethod.jp/articles/amazon-cloudfront-origin-access-control/

動作環境

  • Node.js 20.15.0
  • TypeScript 5.5.2
  • AWS CDK v2(2.156.0)

cdkのバージョン2.156.0からのサポートされた機能なので、2.156.0未満のバージョンを使用している場合はバージョンアップ対応をお願いします。

L2 Constructを使ったOACの実装

CloudFrontのdistributionを作成する時に、S3BucketOrigin.withOriginAccessControlを使ってOriginとなるS3を指定することで、OACを設定しています。
appディレクトリにindex.htmlファイルを格納しており、このファイルを静的コンテンツ配信用のS3 バケットにdeployしています。

lib/static_site-stack.ts
import {
  RemovalPolicy,
  Stack,
  StackProps,
  aws_cloudfront as cloudfront,
  aws_cloudfront_origins as cloudfront_origins,
  aws_s3 as s3,
  aws_s3_deployment as s3_deployment,
} from 'aws-cdk-lib';
import { Construct } from 'constructs';

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

    // 静的コンテンツを配置する S3 バケットを作成
    const staticContentBucket = new s3.Bucket(this, 'StaticContentBucket', {
      removalPolicy: RemovalPolicy.DESTROY,
    });

    // CloudFront ディストリビューションを作成
    const distribution = new cloudfront.Distribution(this, 'Distribution', {
      defaultRootObject: 'index.html',
      defaultBehavior: {
        viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
        origin: cloudfront_origins.S3BucketOrigin.withOriginAccessControl(staticContentBucket)
      },
    });

    // 静的コンテンツをS3にデプロイ
    new s3_deployment.BucketDeployment(this, 'staticContentDeploy', {
      sources: [s3_deployment.Source.asset('./app')],
      destinationBucket: staticContentBucket,
      distribution: distribution,
      distributionPaths: ['/*'],
    });
  }
}
app/index.html
<h1>Hello, World!</h1>

たったこれだけの記述でOACが設定できるようになりました。

動作確認

cdkで作成したリソースの設定が問題ないか、マネージメントコンソールから確認してみます。

ディストリビューションドメインからのアクセス確認

CloudFrontのディストリビューションドメイン名を確認して、ブラウザからアクセスしてみます。
image.png
image.png
Hello, World!が表示されました。

オリジンの設定の確認

また、CloudFrontのオリジンを確認してみるとOACが設定されていること確認できます。
image.png

直接S3にアクセスできないことの確認

次に静的コンテンツを設置したS3に直接アクセスしてみます。
Origin domain欄に記載されているURLにブラウザからアクセスしてみます。
image.png
ブラウザからS3に直接アクセスできないことも確認できました。

S3バケットポリシーの確認

静的コンテンツをデプロイしたS3バケットのバケットポリシーを確認してみます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::staticwebstack-frontendstaticcontentbucketf9d324c0-yrfwytyz71ki/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::AccountId:distribution/E25JIDG0CN8B70"
                }
            }
        }
    ]
}

上記のようなポリシーが作成されていて、cdkで作成したディストリビューションからのアクセスのみを許可していることがわかります。

(補足)L2がない場合のcdkでのOAC実装方法

以下の記事では、L2 Constructがサポートされていなかった時にcdkでOACを設定するやり方について紹介されています。
s3バケットポリシーの変更やCloudFrontのオリジン設定の変更などを記述する必要があり、結構手間だったんではないでしょうか。
https://zenn.dev/thyt_lab/articles/d6423c883882b7

まとめ

本記事では、OACのL2 Constructの使って、安全に静的コンテンツを配信する方法を試してみました。L2 ConstructがサポートされたことでCDKでの実装も簡単になったかと思うで、是非使っていきたいと思います。

参考

https://github.com/aws/aws-cdk/releases/tag/v2.156.0
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudfront_origins-readme.html

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1