TerraformでLambda@Edgeを登録する。
ここではBasic認証をサンプルとして設定する。
1. IAM Roleつくる
provider "aws" {
profile = "my-profile"
}
resource "aws_iam_role" "lambda-edge" {
name = "lambda-edge"
assume_role_policy = "${data.aws_iam_policy_document.lambda-assume-role.json}"
}
data "aws_iam_policy_document" "lambda-assume-role" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com", "edgelambda.amazonaws.com"]
}
}
}
resource "aws_iam_role_policy_attachment" "basic" {
role = "${aws_iam_role.lambda-edge.name}"
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
resource "aws_iam_role_policy" "lambda-edge-cloudwatch-log-group" {
name = "lambda-edge-cloudwatch-log-group"
role = "${aws_iam_role.lambda-edge.name}"
policy = "${data.aws_iam_policy_document.cloudwatch-log-group-lambda-edge.json}"
}
2. Lambda functionをつくる
usernameとpasswordのところは適宜書き換える。
lambda/basic_auth/index.js
'use strict';
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
const credentials = [
{user: 'username', pass:'password'}
];
const headers = request.headers;
if (headers.authorization) {
const authorized = credentials.some(({user, pass}) => {
const secret = new Buffer(`${user}:${pass}`).toString('base64');
return headers.authorization[0].value.split(' ')[1] === secret;
});
if (authorized) {
callback(null, request);
return;
}
}
callback(null, {
status: '401',
statusDescription: '401 Unauthorized',
headers: {
'www-authenticate': [{ key: 'WWW-Authenticate', value: 'Basic' }]
}
});
}
archive_fileでzip化して登録する。
publish = trueにしておくとバージョンが発行される。
Lambda@Edgeにはバージョンがないと設定できない。
Lambda@Edge用のLambda Functionはus-east-1に登録するのが必須。
provider "aws" {
region = "us-east-1"
profile = "my-profile"
alias = "virginia"
}
data "archive_file" "basic_auth" {
type = "zip"
source_dir = "lambda/basic_auth"
output_path = "lambda/dst/basic_auth.zip"
}
resource "aws_lambda_function" "basic_auth" {
provider = "aws.virginia"
filename = "${data.archive_file.basic_auth.output_path}"
function_name = "basic_auth"
role = "${data.aws_iam_role.lambda-edge.arn}"
handler = "index.handler"
source_code_hash = "${data.archive_file.basic_auth.output_base64sha256}"
runtime = "nodejs8.10"
publish = true
memory_size = 128
timeout = 3
}
3. CloudFrontに設定
qualified_arnがバージョン付きのarnなのでこれを設定する。
resource "aws_cloudfront_distribution" "site" {
# ...
lambda_function_association = [
{
event_type = "viewer-request"
lambda_arn = "${aws_lambda_function.basic_auth.qualified_arn}"
}
]
}
}