0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CloudFrontをCDKでデプロイしてみた

Posted at

動機

Lightsail上にWordPressサイトを複数設置しているのですが、最近DDoS攻撃が激しくWAFを導入することにしました。
ただ、WAFはCloudFront、APIGateway、ALBにしか対応していないため、Lightsailに適用しようと思うと前段にALBまたはCloudFrontをおく必要があります。

じゃあ、CloudFrontを前段に置こう!

スクリーンショット 2023-07-13 10.35.06.png

ん?

ってことはCloudFrontのディストリビューションをサイトごとに作成しないといけない。。。
コンソール上でぽちぽちするのは結構大変だな。

ここでAWS-CDKの出番です。

AWS CDKとは

IaC(Infrastructure as Code)を行えるフレームワークです。
TypeScript、Python、Java、.NET、Goなどの様々なプログラミング言語でAWSのサービスをデプロイする処理を記述することができます。

私の場合、TypeScriptの経験があるので今回はTypeScriptでCloudFrontをデプロイするコードを書き、パラメータを変更するだけで複数のディストリビューションを作成できるようにしました。

前提条件

  • ACM(AmazonCertificateManager)およびWAF(WebApplicationFirewall)はすでに作成済みとします
  • 各種パラメータはdotenvを利用して.envファイルから取得することとします(dotenvインストール済みの前提)

ACMでの証明書発行もCDK上で行なってしまおうとしたのですが、証明書認証待ちでタイムアウトしてしまい、デプロイがロールバックするのでACMでの証明書発行はコンソール上で手動で行うことにしました。

実際のコード

以下のコマンドを実行してCDKプロジェクトを作成します。

$ cdk init app --language typescript

libフォルダにあるファイルを修正します。

cloud-front_stack.ts
import * as cdk from 'aws-cdk-lib'
import { Construct } from 'constructs'
import * as acm from 'aws-cdk-lib/aws-certificatemanager'
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
import 'dotenv/config'

export class WordpressCloudFrontStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props)

		// 証明書取得
	  const certificate = acm.Certificate.fromCertificateArn(
	    this,
	    process.env.SITE_CERT?? '',
	    process.env.CERT_ARN?? ''
    );

		// オリジン設定
		const origin = new origins.HttpOrigin(process.env.ORIGIN_DOMAIN_NAME?? '')

		// ディストリビューション作成
		const distribution = new cloudfront.Distribution(this, process.env.DISTRIBUTION_NAME?? '', {
  		defaultBehavior: {
  		  origin: origin,
  		  viewerProtocolPolicy:cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
  		  cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
  		},
			domainNames:[process.env.DOMAIN_NAME?? ''],
			certificate:certificate,
		  enableLogging: true, // Optional, this is implied if logBucket is specified
  		logBucket: new s3.Bucket(this, 'wordpress-cloudfront-log', {
    		objectOwnership: s3.ObjectOwnership.OBJECT_WRITER,
  		}),
  		logFilePrefix: process.env.DOMAIN_NAME?? ''+'/',
  		logIncludesCookies: false,
    })

		// ビヘイビアの追加
		const pathsStr = process.env.PATHS?? ''
		for(let path of pathsStr.split(':')){
			distribution.addBehavior(
				path,origin,
				{
					viewerProtocolPolicy:cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
					cachePolicy:cloudfront.CachePolicy.CACHING_DISABLED
				}
			)
		}
  }
}

また.envファイルに以下のように記述します。

.env
CDK_DEFAULT_ACCOUNT='[利用していないので空でいい]'
CDK_DEFAULT_REGION='[メインで使うリージョン]'
SITE_CERT='[ACMで作成した証明書の名前]'
CERT_ARN='[ACMで作成した証明書のARN]'
DOMAIN_NAME='[ACMで作成した証明書の ドメイン]'
ORIGIN_DOMAIN_NAME='[Lightsail上のWordPressに設定しているドメイン]'
DISTRIBUTION_NAME='[CloudFront上に作成するディストリビューションにつける名前]'
PATHS="/wp-admin/*:*.php"
WEB_ACL_ID="[WAFで作成したWebACLのID]"

PATHSはキャッシュしないファイルパスを指定しています。
今回はWordPressでキャッシュするとまずい/wp-admin/内のファイルおよびphpファイルに対してCACHING_DISABLEDポリシーを設定します。

まとめ

無事にCloudFrontディストリビューションをデプロイし、WAFのルールセットを反映させることができました。
今後もAWS-CDKをうまく利用しながら開発効率を上げていきたいと思います。

0
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?