LoginSignup
16
11

More than 1 year has passed since last update.

AWS CDK v2でOACってどうやってやるの?CloudFront+S3+OAC構築(コード付き-Typescript)

Posted at

はじめに

 AWS CDKでリソース作ってますか??
 最近、AWS CDKを見ること、触ることが多く、少しずつ仲良くなってきました。そんな中、AWS CDKでAmazon CloudFront オリジンアクセスコントロールをどうやってやるのか、困ったのでご紹介です。

アーキテクチャ

 以下の通り、利用者からアクセスされ、オリジンサーバとなるS3から表示用HTMLを利用者に返却するアーキテクチャです。よくあるやつですね。

名称未設定-ページ3.drawio.png

 上記のCloudFrontとS3のアクセス部分でオリジンアクセスコントロール(OAC)を利用します。OACを利用することでS3自体をパブリックにする必要がなくなり、S3への直接的な意図しないアクセスをできない様にします。
 下記の赤枠部分です。

名称未設定-ページ3.drawio (1).png

 従来は、オリジンアクセスアイデンティティ(OAI)を利用していましたが、OACが登場してからはOACが推奨されています。
 OACは、S3に対して安全にアクセスする形となり、OAIよりよりセキュアになっています。(OAC自体がよりセキュアでいつくかのオプション設定も可能になっています。)

 以下のブログで詳細が紹介されています。

 デベロッパーガイドはこちらです。

AWS CDKでのOAC

 では、さっそくやってみよう、とAWS CDKのリファレンスを覗きます。
(最初、みんなどうやって作ってるのかな?やっぱリファレンス?)

 aws-cdk-lib.aws_cloudfrontです。

 そして、眺めると「class OriginAccessIdentity」しかないと、気づきます。。。(2023/3/14時点)

 で、いろいろ調べるとここに行きつきました。まだ、L2ではサポートされていないようです。

 ということで、L1で頑張って作ることになりました。

AWS CDKでの実装(Typescript)

 作ったのが以下です。

各リソースのプロパティは省略しており、デフォルト値が利用される形になっています。利用される場合は、ご注意ください。

FrontendStack.ts
import { aws_cloudfront, aws_cloudfront_origins, aws_iam, aws_s3, Stack, StackProps } from 'aws-cdk-lib';
import { BlockPublicAccess } from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';

interface SubStackProps extends StackProps {
  accountId: string;
}

export class FrontendStack extends Stack {

  public readonly contentsBucket: aws_s3.IBucket;
  public readonly distribution: aws_cloudfront.IDistribution;

  constructor(scope: Construct, id: string, props: SubStackProps) {
    super(scope, id, props);

    // S3
    this.contentsBucket = new aws_s3.Bucket(this, 'ContentsBucket', {
      blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
    });

    // OAC
    // https://github.com/aws/aws-cdk/issues/21771
    const cfnOriginAccessControl = new aws_cloudfront.CfnOriginAccessControl(this, 'OriginAccessControl', {
      originAccessControlConfig: {
        name: 'OriginAccessControlForContentsBucket',
        originAccessControlOriginType: 's3',
        signingBehavior: 'always',
        signingProtocol: 'sigv4',
        description: 'Access Control',
      },
    });

    // CloudFront
    this.distribution = new aws_cloudfront.Distribution(this, 'Distribution', {
      comment: 'distribution.',
      defaultBehavior: {
        origin: new aws_cloudfront_origins.S3Origin(this.contentsBucket),
        allowedMethods: aws_cloudfront.AllowedMethods.ALLOW_ALL,
      },
      defaultRootObject: 'index.html',
      httpVersion: aws_cloudfront.HttpVersion.HTTP2_AND_3,
    });

    const cfnDistribution = this.distribution.node.defaultChild as aws_cloudfront.CfnDistribution;
    // OAI削除(勝手に設定されるため)
    cfnDistribution.addPropertyOverride('DistributionConfig.Origins.0.S3OriginConfig.OriginAccessIdentity', '');
    // OAC設定
    cfnDistribution.addPropertyOverride('DistributionConfig.Origins.0.OriginAccessControlId', cfnOriginAccessControl.attrId);

    // S3 - BucketPolicy
    const contentsBucketPolicyStatement = new aws_iam.PolicyStatement({
      actions: ['s3:GetObject'],
      effect: aws_iam.Effect.ALLOW,
      principals: [
        new aws_iam.ServicePrincipal('cloudfront.amazonaws.com'),
      ],
      resources: [`${this.contentsBucket.bucketArn}/*`],
    });
    contentsBucketPolicyStatement.addCondition('StringEquals', {
      'AWS:SourceArn': `arn:aws:cloudfront::${props.accountId}:distribution/${this.distribution.distributionId}`
    })
    this.contentsBucket.addToResourcePolicy(contentsBucketPolicyStatement);

  }

}

<注意点>

  • aws_cloudfront.DistributionがデフォルトでOAIを設定するようになっていますので、(無理矢理?)OACを利用するようになっています。
  • S3のバケットポリシーにOAIの設定が入ってしまいます。削除する部分まで入れていません。

スクリーンショット 2023-03-14 23.24.36.png

作成されたリソース(OAC)

 実際にデプロイすると、CloudFront、S3、OACが作成され、CloudFront distribution設定内にあるS3のオリジン設定を見ると以下の様に構成されます。OACとなっていますね。

image.png

まとめ

 今回はAWS CDKでCloudFront + S3 + OACを構築しました。やり方わかると意外とあっさりしていました。CloudFormationは対応できているけど、AWS CDKのL2はまだ対応されていない、というものも多々ありますので、参考になれば幸いです。

16
11
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
16
11