Amazon CloudFront VPCオリジンとは
Amazon CloudFront VPCオリジンは、今年の11月にリリースされたCloudFrontの新機能です。
これまではALB、NLB、EC2等をオリジンにする場合はパブリックサブネットに配置する必要がありましたが、この機能によりプライベートサブネット内に配置できるようになりました。
TerraformのAmazon CloudFront VPCオリジン対応
terraform-provider-awsのv5.82.0で aws_cloudfront_vpc_origin
が追加され、TerraformでAmazon CloudFront VPCオリジンの設定が可能になりました。
Terraformでリソース作成
テスト用のALBを作成
今回は簡単にテストするために固定レスポンスを返すALBをプライベートサブネット内に作成します。
以下、いくつかポイントについて説明します。
- ALBのセキュリティグループにCloudFrontのマネージドプレフィックスリストを利用したルールを追加してCloudFrontからのアクセスを許可しておく
Update your security groups for the VPC private origins to explicitly allow the CloudFront managed prefix list. For more information, see Use the CloudFront managed prefix list.
- インターネットからのトラフィックを受信するためにインターネットゲートウェイを作成する
Internet gateway – Required so that your VPC can receive traffic from the internet. The internet gateway is not used for routing traffic to origins inside the subnet, and you don’t need to update the routing policies.
その他の要件についてはドキュメントを参照してください。
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-vpc-origins.html
locals {
availability_zones = [
"ap-northeast-1a",
"ap-northeast-1c",
"ap-northeast-1d",
]
}
data "aws_ec2_managed_prefix_list" "cloudfront" {
name = "com.amazonaws.global.cloudfront.origin-facing"
}
resource "aws_vpc" "this" {
cidr_block = "10.0.0.0/16"
}
# インターネットからのトラフィックを受信するために必要
# 存在しないとVPCオリジン作成時にエラーになります。
resource "aws_internet_gateway" "this" {
vpc_id = aws_vpc.this.id
}
resource "aws_subnet" "this" {
for_each = toset(local.availability_zones)
vpc_id = aws_vpc.this.id
availability_zone = each.key
cidr_block = cidrsubnet(aws_vpc.this.cidr_block, 8, index(local.availability_zones, each.key))
}
resource "aws_security_group" "private_alb" {
vpc_id = aws_vpc.this.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
# CloudFrontからのアクセスを許可
prefix_list_ids = [data.aws_ec2_managed_prefix_list.cloudfront.id]
}
}
resource "aws_lb" "private_alb" {
name = "private-alb"
internal = true
load_balancer_type = "application"
security_groups = [aws_security_group.private_alb.id]
subnets = [for subnet in aws_subnet.this : subnet.id]
}
resource "aws_lb_listener" "private_alb" {
load_balancer_arn = aws_lb.private_alb.arn
port = 80
protocol = "HTTP"
default_action {
type = "fixed-response"
fixed_response {
content_type = "text/plain"
message_body = "Hello"
status_code = "200"
}
}
}
VPCオリジンとディストリビューションを作成
ALBを指定してVPCオリジンを作成し、ディストリビューションにVPCオリジンをオリジンとして設定します。
resource "aws_cloudfront_vpc_origin" "private_alb" {
vpc_origin_endpoint_config {
name = "private-alb"
arn = aws_lb.private_alb.arn
http_port = 80
https_port = 443
origin_protocol_policy = "http-only"
origin_ssl_protocols {
quantity = 1
items = ["TLSv1.2"]
}
}
}
resource "aws_cloudfront_distribution" "private_alb" {
origin {
origin_id = "private_alb"
domain_name = aws_lb.private_alb.dns_name
vpc_origin_config {
vpc_origin_id = aws_cloudfront_vpc_origin.private_alb.id
}
}
enabled = true
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "private_alb"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "redirect-to-https"
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
}
terraform apply
してリソースを作成し、作成されたディストリビューションにアクセスすると、ALBにレスポンスとして設定した Hello
という文字列が返ってくることが確認できます。
まとめ
Terraformで比較的簡単にCloudFront VPCオリジンの設定ができることを確認できました。
今後、CloudFrontを使用する際に活用していきたいと思います!