目的
・AWS上の静的Webサイトホスティングを有効にしたS3をCloudFrontで公開。
・Cognito認証を実装。
前提条件
・Terraformを使用してAWS上にリソースを作成する。
・Lambda@Edgeを使用して実装する。
・作成する内容は以下と同様
TFファイル
resource "aws_cloudfront_distribution" "WebBucketDistribution" {
enabled = true
default_root_object = "index.html"
price_class = "PriceClass_200"
origin {
origin_id = "WebBucketOrigin"
domain_name = aws_s3_bucket.WebBucket.bucket_regional_domain_name
origin_access_control_id = aws_cloudfront_origin_access_control.WebBucketOriginAccessControl.id
}
viewer_certificate {
cloudfront_default_certificate = true
}
default_cache_behavior {
target_origin_id = "WebBucketOrigin"
viewer_protocol_policy = "redirect-to-https"
compress = true
cached_methods = ["GET", "HEAD"]
allowed_methods = ["GET", "HEAD"]
lambda_function_association {
event_type = "viewer-request"
lambda_arn = "${aws_lambda_function.AuthCognito.arn}:${aws_lambda_function.AuthCognito.version}"
}
cache_policy_id = aws_cloudfront_cache_policy.WebBucketCachePolicy.id
origin_request_policy_id = aws_cloudfront_origin_request_policy.WebBucketOriginRequestPolicy.id
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
}
resource "aws_iam_role" "auth_cognito_lambda_role" {
name = "AuthCognitoLambdaRole"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = ["lambda.amazonaws.com","edgelambda.amazonaws.com"]
}
},
]
})
}
resource "aws_iam_role_policy" "auth_cognito_lambda_policy" {
role = aws_iam_role.auth_cognito_lambda_role.id
policy = jsonencode({
Statement = [
{
Action = ["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents"]
Effect = "Allow"
Resource = ["arn:aws:logs:*:*:*"]
},
{
Action = ["lambda:GetFunction","lambda:EnableReplication*","iam:CreateServiceLinkedRole"]
Effect = "Allow"
Resource = "*"
},
]
})
}
data "archive_file" "lambda_auth_cognito" {
type = "zip"
source_file = "${path.module}/lambda/AuthCognito"
output_path = "${path.module}/lambda_zip/auth_cognito.zip"
}
resource "aws_lambda_function" "AuthCognito" {
filename = "${path.module}/lambda_zip/auth_cognito.zip"
function_name = "auth_cognito"
role = aws_iam_role.auth_cognito_lambda_role.arn
handler = "auth_cognito.handler"
runtime = "nodejs18.x"
source_code_hash = filebase64sha256("${path.module}/lambda/AuthCognito/auth_cognito.js")
timeout = 5
tracing_config {
mode = "Active"
}
publish = true
}
resource "aws_cognito_user_pool" "WebBucketUserPool" {
name = "terraform-user-pool"
admin_create_user_config {
allow_admin_create_user_only = false
}
alias_attributes = ["email","preferred_username"]
auto_verified_attributes = ["email"]
software_token_mfa_configuration {
enabled = true
}
mfa_configuration = "ON"
password_policy {
minimum_length = 8
require_uppercase = true
require_lowercase = true
require_numbers = true
require_symbols = true
temporary_password_validity_days = 7
}
schema {
name = "email"
attribute_data_type = "String"
mutable = true
required = true
}
schema {
name = "preferred_username"
attribute_data_type = "String"
mutable = true
required = false
}
schema {
name = "name"
attribute_data_type = "String"
mutable = true
required = true
string_attribute_constraints {
min_length = 1
max_length = 100
}
}
verification_message_template {
default_email_option = "CONFIRM_WITH_LINK"
email_subject = "メールアドレスの確認"
email_message = "あなたのメールアドレスを確認するには、以下のリンクをクリックしてください: {####}"
}
}
resource "aws_cognito_user_pool_domain" "WebBucketUserPoolDomain" {
domain = "terraform-${data.aws_caller_identity.self.account_id}"
user_pool_id = aws_cognito_user_pool.WebBucketUserPool.id
}
resource "aws_cognito_user_pool_client" "WebBucketUserPoolClient" {
name = "terraform-client"
user_pool_id = aws_cognito_user_pool.WebBucketUserPool.id
callback_urls = ["https://${aws_cloudfront_distribution.WebBucketDistribution.domain_name}"]
supported_identity_providers = ["COGNITO"]
allowed_oauth_flows = ["code"]
allowed_oauth_flows_user_pool_client = true
allowed_oauth_scopes = ["openid"]
}
◆aws_cloudfront.tf
・WebBucketDistribution(lambda_function_association):Lambda@Edgeの関連付けを追加
◆aws_iam.tf
・auth_cognito_lambda_role:Cognito認証Lambda用IAMロール
・auth_cognito_lambda_policy:「auth_cognito_lambda_role」に付与するポリシー
◆aws_lambda.tf
・lambda_auth_cognito:Lambda関数用のファイルをZip圧縮
・AuthCognito:Lambda関数定義
◆aws_cognito.tf
・WebBucketUserPool:Cognitoユーザプール
・WebBucketUserPoolDomain:Cognitoユーザプールドメイン
・WebBucketUserPoolClient:Cognitoユーザプールクライアント
Lambda
const { Authenticator } = require('cognito-at-edge');
const authenticator = new Authenticator({
region: 'user pool regionを指定',
userPoolId: 'user pool IDを指定',
userPoolAppId: 'user pool app client IDを指定',
userPoolDomain: 'user pool domainを指定',
});
exports.handler = async (request) => authenticator.handle(request);
動作確認
①Webサイトへアクセス
・サインイン画面が表示されることを確認
参考(前回記事)