AmplifyとWAFを連携しアクセスコントロールする方法
この記事は LCL Advent Calendar 2024 の 17日目の記事です。S3+CloudFrontでの配信基盤の構築で詰まったポイント でした。
S3のアクセスコントロール周り複雑な分、ソリューション記事は助かりますね🙏
本日も同じくAWSアクセスコントロール関連の紹介をいたします!
はじめに
弊社のHPをリニューアルするにあたり、ECS(WordPress)で動いていたインフラ環境を、Amplify(Next.jsアプリ)+microCMSに移行することになりました。
新HPには、アクセス制限・ブラックリスト機能などのアクセスコントロール全般機能を付与したかったのですが、Amplifyだけだとそのような機能は付与できないようでした。
今回はCloudFront+WAFを紐付けたことで、アクセスコントロール機能を付与できたので、その方法をご紹介します!
結論
Amplifyの前段にCloudFrontを配置し、WAFを連携させることで、アクセスコントロールを可能にしました。
経緯
先述の通り、Amplifyでのアクセスコントロールは不可だったので、WAFを用いてアクセスコントロールを行おうと思いました。
WAFの連携にはCloudFrontが必要だったので、Amplify内部のCloudFrontに連携できないか、サポートセンターに問い合わせたところ、それは不可とのことだったので、Amplifyの前段にCloudFrontを配置して、そこにWAFを連携させました。
実装詳細
Terraformで実装したので、CloudFrontのコードの一部を紹介します。
Amplify, WAF, ACMとの連携箇所はコードのコメントをご参照ください。
実装意図等もコメントしてあります。
また、今回の記事では触れていませんが、AmplifyのBasic認証突破にはLambda@Edgeを使用しています。
resource "aws_cloudfront_distribution" "app" {
origin {
domain_name = var.origin_domain_name # Amplifyのエンドポイントを設定
origin_id = local.name_prefix # 任意の識別子
# 以下の数値の設定はお好みで
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "https-only"
origin_ssl_protocols = ["TLSv1.2"]
origin_keepalive_timeout = 60
origin_read_timeout = 60
}
}
# Route53に登録してあるAレコード
aliases = [var.domain_name]
enabled = true
is_ipv6_enabled = true
comment = "コメント"
# 以下でWAFと連携
web_acl_id = var.web_acl_id
viewer_certificate {
cloudfront_default_certificate = false
# 以下でACMと連携
acm_certificate_arn = var.acm_certificate_arn
minimum_protocol_version = "TLSv1.2_2021"
ssl_support_method = "sni-only"
}
default_cache_behavior {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD", "OPTIONS"]
target_origin_id = local.name_prefix
# Amplify内部のCloudFrontにキャッシュの設定があるので、前段のCloudFrontにはキャッシュをさせないよう設定してあります。
cache_policy_id = aws_cloudfront_cache_policy.no_cache_policy.id
# CloudFrontにBasic認証を設定しています。
function_association {
event_type = "viewer-request"
function_arn = aws_cloudfront_function.basic_auth.arn
}
# CloudFrontからのアクセスの場合、AmplifyのBasic認証を突破するLambdaです。
lambda_function_association {
event_type = "origin-request"
lambda_arn = aws_lambda_function.basic_auth_lambda.qualified_arn
}
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 0
max_ttl = 0
compress = false
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
}
参考記事
おわりに
Amplifyでデプロイしたアプリにも、開発者がハンドリング可能なアクセスコントロール機能があった方が便利だと思います。
前例が少なめだったので、今回の記事を執筆しました。
この記事が誰かのお役に立つことを願います🌱
Discussion