というものが2024年11月に来ました。
で、TerraformのAWS Providerでも、つい最近実装されてこの機能が設定できるようになったので、試してみたいと思います。
※ v5.82.0で追加されました。
細かい仕組みなどはドキュメントをご覧ください。
AWS Providerのドキュメントはこちら。
今回、試してみる構成は
Cloudfront - vpc origin - alb(private subnet)
のような感じになります。
お試しなので最低限の設定しかしていません。ご了承ください。
まず、ロードバランサーを作る
resource "aws_lb" "this" {
name = "vpc-origin-test"
internal = true
load_balancer_type = "application"
security_groups = [aws_security_group.this.id]
subnets = var.subnet_ids
}
resource "aws_security_group" "this" {
name = "vpc_origin_test"
vpc_id = var.vpc_id
}
resource "aws_vpc_security_group_egress_rule" "main" {
security_group_id = aws_security_group.this.id
cidr_ipv4 = "10.0.0.0/8"
from_port = 1
ip_protocol = "tcp"
to_port = 65535
}
resource "aws_vpc_security_group_ingress_rule" "main" {
security_group_id = aws_security_group.this.id
cidr_ipv4 = "10.0.0.0/8"
from_port = 80
ip_protocol = "tcp"
to_port = 80
}
# セキュリティグループの詳細は後で追記します。
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.this.arn
port = "80"
protocol = "HTTP"
default_action {
type = "fixed-response"
fixed_response {
content_type = "text/plain"
message_body = "Nekodaisuki!!!"
status_code = "200"
}
}
}
はい、できました。
VPCオリジンを作ってみる
CloudFrontディストリビューションのオリジンに紐づけると変更できなくなるんで、3つ作ります。テストのために入れ替えたいんです(と言いつつ2つしか使わなかったけど)。
resource "aws_cloudfront_vpc_origin" "https_only" {
vpc_origin_endpoint_config {
name = "https_only"
arn = aws_lb.this.arn
http_port = 80
https_port = 443
origin_protocol_policy = "https-only"
origin_ssl_protocols {
items = ["TLSv1.2"]
quantity = 1
}
}
}
resource "aws_cloudfront_vpc_origin" "http_and_https" {
vpc_origin_endpoint_config {
name = "http_and_https"
arn = aws_lb.this.arn
http_port = 80
https_port = 443
origin_protocol_policy = "match-viewer"
origin_ssl_protocols {
items = ["TLSv1.2"]
quantity = 1
}
}
}
resource "aws_cloudfront_vpc_origin" "http_only" {
vpc_origin_endpoint_config {
name = "http_only"
arn = aws_lb.this.arn
http_port = 80
https_port = 443
origin_protocol_policy = "http-only"
origin_ssl_protocols {
items = ["TLSv1.2"]
quantity = 1
}
}
}
aws_cloudfront_vpc_origin.https_only: Creation complete after 2m55s [id=vo_DZJH4ZRTpFpCy07MrMXXX3]
aws_cloudfront_vpc_origin.http_only: Creation complete after 2m55s [id=vo_5MYtzqRGd6CGEx9tXXXOIQ]
aws_cloudfront_vpc_origin.http_and_https: Creation complete after 3m15s [id=vo_1sRlzayRVWnEXXXRpbPngX]
完了までそこそこ時間かかります。
CloudFrontを作ってみる
locals {
origin_id = "example"
}
resource "aws_cloudfront_distribution" "main" {
#provider = aws.global
origin {
domain_name = aws_lb.this.dns_name
origin_id = local.origin_id
vpc_origin_config {
vpc_origin_id = aws_cloudfront_vpc_origin.http_only.id
}
}
enabled = true
restrictions {
geo_restriction {
restriction_type = "none"
locations = []
}
}
default_cache_behavior {
allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
cached_methods = ["GET", "HEAD"]
target_origin_id = local.origin_id
viewer_protocol_policy = "allow-all"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
}
この時点ではアクセスしてもちゃんとつながりません。
(`-´) < Tue Dec 24 23:47:48 $ curl -I https://d1XXXvzzbg9XXX.cloudfront.net
HTTP/2 504
(snip)
セキュリティグループの設定
多分 VPCオリジンを作った時に自動で作られたSGをごにょっとしてあげる必要があります。
data "aws_security_group" "vpc_origin_sg" {
name = "CloudFront-VPCOrigins-Service-SG"
}
resource "aws_vpc_security_group_ingress_rule" "vpc_origin" {
security_group_id = aws_security_group.this.id
from_port = 80
ip_protocol = "tcp"
to_port = 80
referenced_security_group_id = data.aws_security_group.vpc_origin_sg.id
}
わーい、表示できたぁぁぁ~~~~!
※ てか、なぜここだけChromeでアクセスした……?!
試すだけならばここまでで終了。
けど、ちょっと疑問があるので試してみる。
CloudFrontからALBへのアクセスをhttpsに出来るのか
以下、ざっと試したてみた結果を貼っておきます。
ALBを別のドメインでアクセスできるようにする。ACMも設定する。
resource "aws_acm_certificate" "cert" {
domain_name = var.record_name
validation_method = "DNS"
lifecycle {
create_before_destroy = true
}
}
data "aws_route53_zone" "cert" {
name = var.zone_name
}
resource "aws_route53_record" "cert" {
for_each = {
for dvo in aws_acm_certificate.cert.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}
allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = data.aws_route53_zone.cert.zone_id
}
resource "aws_route53_record" "alb" {
name = var.record_name
alias {
name = aws_lb.this.dns_name
zone_id = aws_lb.this.zone_id
evaluate_target_health = false
}
type = "A"
zone_id = data.aws_route53_zone.cert.zone_id
}
VPCオリジンを、https-onlyのに変更
resource "aws_cloudfront_distribution" "main" {
origin {
domain_name = var.record_name
origin_id = local.origin_id
vpc_origin_config {
vpc_origin_id = aws_cloudfront_vpc_origin.https_only.id
}
}
(snip)
セキュリティグループも443のみ通すように変更
resource "aws_vpc_security_group_ingress_rule" "main" {
security_group_id = aws_security_group.this.id
cidr_ipv4 = "10.0.0.0/8"
from_port = 443
ip_protocol = "tcp"
to_port = 443
}
resource "aws_vpc_security_group_ingress_rule" "vpc_origin" {
security_group_id = aws_security_group.this.id
from_port = 443
ip_protocol = "tcp"
to_port = 443
referenced_security_group_id = data.aws_security_group.vpc_origin_sg.id
}
ALBのリスナーも変更
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.this.arn
port = "443"
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
certificate_arn = aws_acm_certificate.cert.arn
default_action {
type = "fixed-response"
fixed_response {
content_type = "text/plain"
message_body = "Nekodaisuki!!!"
status_code = "200"
}
}
}
(`-´) < Thu Dec 26 12:50:45 $ curl https://d3gsoddhvrfXXX.cloudfront.net
Nekodaisuki!!!
よっしゃ……!
リスナーはHTTPSしかないので、HTTPSで通信できてることがわかるかなと思います。
最後に
作ったリソースは削除しましょう
(`-´) < Wed Dec 25 01:48:43 $ terraform destroy
なお、VPCオリジンの設定全部消しましたが CloudFront-VPCOrigins-Service-SG
は残ってました。けど、翌日見たらいなくなっていました。
ENIはすぐ消えてくれてました。
それでは。