如何使用 terraform 将 Cloudfront 连接到私有 s3 存储桶?

如何使用 terraform 将 Cloudfront 连接到私有 s3 存储桶?

我已经完成了 90%,但似乎 cloudfront 从 s3 收到 500 个错误?我确定我做错了什么。我读过各种亚马逊文档,但对我来说,这些文档似乎太模糊了,可能毫无用处。

resource "aws_s3_bucket" "Artifacts" {
    bucket = "my.domain.tld"
    acl    = "private"
    versioning {
        enabled = true
    }
}

module "BucketPolicy" {
    source = "../modules/S3CloudFrontBucketPolicy"
    bucket_id = "${aws_s3_bucket.Artifacts.id}"
    arn = "${aws_s3_bucket.Artifacts.arn}"
    principal = "${module.ArtifactsCloudfront.oai_principal}"
}

module "ArtifactsCloudfront" {
    source = "../modules/CloudFrontS3"
    zone_id = "${aws_route53_zone.Primary.id}"
    root = "/"
    origin_fqdn = "${aws_s3_bucket.Artifacts.bucket_domain_name}"
    user_fqdn = "${aws_s3_bucket.Artifacts.bucket}"
}

CloudFrontS3

variable "user_fqdn" {}
variable "origin_fqdn" {}
variable "zone_id" {}
variable "root" {}

output "oai_principal" {
    value = "${aws_cloudfront_origin_access_identity.OAI.iam_arn}"
}

resource "aws_acm_certificate" "Cert" {
    domain_name = "${var.user_fqdn}"
    validation_method = "DNS"
    tags {
        env = "${terraform.env}"
    }
}

resource "aws_route53_record" "ValidationDNS" {
    name = "${aws_acm_certificate.Cert.domain_validation_options.0.resource_record_name}"
    type = "${aws_acm_certificate.Cert.domain_validation_options.0.resource_record_type}"
    zone_id = "${var.zone_id}"
    records = ["${aws_acm_certificate.Cert.domain_validation_options.0.resource_record_value}"]
    ttl = 60
}

resource "aws_acm_certificate_validation" "CertValidation" {
    certificate_arn = "${aws_acm_certificate.Cert.arn}"
    validation_record_fqdns = ["${aws_route53_record.ValidationDNS.fqdn}"]
}

resource "aws_route53_record" "DomainName" {
    zone_id = "${var.zone_id}"
    name = "${var.user_fqdn}"
    type = "CNAME"
    ttl = "300"
    records = [
        "${aws_cloudfront_distribution.Distribution.domain_name}"]
}

resource "aws_cloudfront_origin_access_identity" "OAI" {
}

resource "aws_cloudfront_distribution" "Distribution" {
    aliases = ["${var.user_fqdn}"]
    origin {
        domain_name = "${var.origin_fqdn}"
        origin_id = "${var.origin_fqdn}"

        s3_origin_config {
            origin_access_identity = "${aws_cloudfront_origin_access_identity.OAI.cloudfront_access_identity_path}"
        }
    }

    enabled = true
    is_ipv6_enabled = true
    default_root_object = "${var.root}"

    default_cache_behavior {
        allowed_methods = [
            "GET",
            "HEAD",
            "OPTIONS"]
        cached_methods = [
            "GET",
            "HEAD",
            "OPTIONS"]

        forwarded_values {
            cookies {
                forward = "none"
            }

            query_string = true
        }
        default_ttl = 3600
        max_ttl = 86400
        min_ttl = 60
        target_origin_id = "${var.origin_fqdn}"
        viewer_protocol_policy = "https-only"
        compress = true
    }

    price_class = "PriceClass_100"

    restrictions {
        geo_restriction {
            restriction_type = "whitelist"
            locations = ["US"]
        }
    }

    viewer_certificate {
        acm_certificate_arn = "${aws_acm_certificate_validation.CertValidation.certificate_arn}"
        ssl_support_method = "sni-only"
        minimum_protocol_version = "TLSv1.1_2016"
    }
    tags {
        env = "${terraform.env}"
    }
}

S3CloudFrontBucketPolicy

variable "principal" {}
variable "arn" {}
variable "bucket_id" {}

resource "aws_s3_bucket_policy" "Policy" {
    bucket = "${var.bucket_id}"
    policy = "${data.template_file.Policy.rendered}"
}

data "template_file" "Policy" {
    vars {
        arn = "${var.arn}"
        oai = "${var.principal}"
    }
    template = <<POLICY
{
  "Id": "Policy1520441044381",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1520439447147",
      "Action": [
        "s3:*"
      ],
      "Effect": "Allow",
      "Resource": "$${arn}/*",
      "Principal": {
        "AWS": [
          "$${oai}"
        ]
      }
    }
  ]
}
POLICY
}

然而当我尝试下载某些东西时

无法满足请求。CloudFront 目前在从 Amazon S3 请求对象时遇到问题。

我做错了什么?我需要修复什么?

答案1

我的政策内容如下:

data "aws_iam_policy_document" "s3_policy" {
  statement {
    actions   = ["s3:GetObject"]
    resources = ["${aws_s3_bucket.current.arn}/*"]

    principals {
      type        = "AWS"
      identifiers = ["${var.origin_access_identity_arn}"]
    }
  }

  statement {
    actions   = ["s3:ListBucket"]
    resources = ["${aws_s3_bucket.current.arn}"]

    principals {
      type        = "AWS"
      identifiers = ["${var.origin_access_identity_arn}"]
    }
  }
}

相关内容