cloudpack あら便利カレンダー 2017 の18日目です。
AWS で静的ウェブサイトといえば S3 + CloudFront ですが、その構成を CloudFormation で作る際にあら便利な Tips を入れていこうという記事です。
とりあえず起動してみる
AWS コンソールにログインした状態で、このリンクから Stack を起動できます。
Stack が起動したら、 Outputs
の URL
にアクセスすれば CloudFront/S3 に置かれた静的ページが閲覧できるはずです。
このテンプレートが置いてあるバケットは誰でも List/Get できるので、
$ aws s3 sync s3://cfn-staticweb-example/ .
すれば CloudFormation テンプレートとカスタムリソース用の Lambda ファンクションのソースが入った zip が落ちてきます。そのあとに aws cloudformation create-stack
コマンドで起動するもよし、内容を見るも改造するもよしです。
さらに、このファイル一式を生成しているコードは y13i/cfn-staticweb-example にあります。 Serverless Framework を使いつつ、 serverless deploy
はせず、 serverless package
して出力されたファイルを一部改変して S3 バケットに上げるということをしています。
CFn でどんなあら便利があるの?
CloudFront の利用する・しないの切り替え
CloudFront Distribution は作成にかなり時間が掛かります。このテンプレートでは CloudFront を使わないことも選べるようにしました。
CloudFormation の Conditions を使い、 UseCloudFront
という Parameter が true
の時のみ Distribution を作成します。さらに S3 Bucket Policy で読み取りを許可する参照元は
UseCloudFront
がtrue
- CloudFront からのみ可(Origin Access Identity を使用)
UseCloudFront
がfalse
- どこからでも可
と切り替わるようにしています。
CloudFront の各種パラメーターの切り替え
ACM (AWS Certificate Manager)で発行した証明書をAcmCertificateArn
パラメーターで指定した場合は Distribution で ViewerCertificate
として使用するようにしています。
指定しない場合(値が空文字)の場合はAWS::NoValue
擬似要素を使って、そもそも ViewerCertificate
が指定されていないように振る舞うようになっています。
同様に、 Distribution Alias も Parameter で指定された場合のみ設定するテンプレートになっています。
Origin Access Identity の作成
Origin Access Identity は普通には CloudFormation で作成できません!
なんで対応していないのか疑問に思うところですが、文句を言ってもしかたないので Custom Resource を使って Lambda Function に作成させています。
インデックスドキュメントの生成
CloudFormation でサポートされている S3 のリソースはBucket 、 BucketPolicy のみです。バケットの内容物は CloudFormation では管理できません。
しかし、前項と同様にカスタムリソースを使えばどうにでもなります。
ここでは、 Parameter で受け付けた IndexDocumentTitle
とIndexDocumentBody
をejs テンプレートに流し込む処理をして HTML を生成し、バケットに置くという処理をさせてみました。
まとめ
Lambda とその周辺環境がそこそこ枯れてきたことで、 Lambda-backed Custom Resource がだいぶ使いやすくなったと感じます。つまり、 CloudFormation の使い勝手も増しているということです。
地味ながら進化を続ける CFn をあら便利に使っていきましょう。