🦔
Terraform を使って良い感じに Basic 認証できる CloudFront Functions を作成する
lib | version |
---|---|
terraform | 1.1.9 |
hashicorp/aws | 4.22.0 |
terraform.tfvars
で map
に好きなだけユーザーとパスワード突っ込んだら適当に Basic 認証できる CloudFront Functions 書き出してくれるのが欲しくてやってみたメモ。
# terraform.tfvars
# Basic 認証に設定するユーザーとパスワードを user = password で指定する。
# ココで必要なだけ指定する。
valid_users = {
spam = "spamsoamspam",
egg = "eggeggegg",
ham = "hamhamham"
}
# main.tf
# terraform.tfvars で指定する
variable "valid_users" {
type = map(string)
}
provider "aws" {
# CloudFront まわりはヴァージニアリージョンで設定するので region で設定しておく。
region = "us-east-1"
}
resource "aws_cloudfront_function" "basic_auth" {
name = "ExampleBasicAuth"
runtime = "cloudfront-js-1.0"
publish = true
# valid_users で指定した値を javascript 側で使う形に整形して埋め込む。
# 1. user と password を "user:password" の形に整形
# 2. base64encode で base64 する
# 3. "Basic xxxxxxx" の形に整形
# 4. カンマで連結して一つの文字列にする
# 5. javascriptの適当なところに差し込む
code = format(file("basic_auth.js"), join(", ", [
for u, p in var.valid_users : format("\"Basic %s\"", base64encode("${u}:${p}"))
]))
}
// basic_auth.js
function handler(event) {
// ココに main.tf で整形した認証情報が以下のような形で差し込まれる。
// [
// "Basic aaaaaa",
// "Basic bbbbbb",
// "Basic ccccc"
// ]
var validUsers = [%s]
var request = event.request;
var headers = request.headers;
if (
typeof headers.authorization === "undefined" ||
validUsers.indexOf(headers.authorization.value) === -1
) {
return {
statusCode: 401,
statusDescription: "Unauthorized",
headers: { "www-authenticate": { value: "Basic" } }
};
}
return request;
}
terraform plan
すれば最終的にどーゆー形で整形されて登録されるのかが確認できる。はず。
あとは terraform apply
すれば CloudFront Functions に登録されるので、紐付けたい aws_cloudfront_distribution
の default_cache_behavior
や ordered_cache_behavior
の function_association
に arn を設定してあげれば良い。
...
default_cache_behavior {
...
function_association {
# Basic 認証なので viewer-request を指定する
event_type = "viewer-request"
# ココで紐づける
function_arn = aws_cloudfront_function.basic_auth.arn
}
}
これをやってみるに当たって、以下のサイトを参考にさせていただきました。ありがとうございます!
毎度わたしは重箱の隅をつつくような内容ばかり :-P
Discussion