【问题标题】:Dynamically add origin/cache behavior to existing CloudFront distro将源/缓存行为动态添加到现有 CloudFront 发行版
【发布时间】:2019-08-03 09:52:50
【问题描述】:

我相信我在 AWS apiaws_cloudfront_distribution 模块(版本 v0.11)中遇到了限制。我想要完成的是动态将源和缓存行为添加到现有的 CloudFront 分配。

我知道这可以通过AWS CLI 以某种方式实现。下面显示了一个示例(来自update-distribution documentation。我的问题与如何使用 terraform 简化此实现有关(显示在代码 sn-p 下方)。

$ JSON_OUTPUT=$(aws cloudfront get-distribution-config --id=<MY-DISTROS-ID>)
$ echo $JSON_OUTPUT
{
  "ETag": "E2ABCDEFGHIJKL",
  "DistributionConfig": {
    "CacheBehaviors": {
      "Quantity": 0
    },
    "Origins": {
      "Items": [
        {
          ...origin-info-for-default-cache-behavior
        }
      ],
      "Quantity": 1
    },
    "Enabled": true,
    "DefaultCacheBehavior": {
      ...default-cache-behavior
    },
    ...more-cloudfront-stuff
}
$ # remove the ETag
$ # add an entry to the DistributionConfig.Origins.Items array
$ # add an array of Items to the DistributionConfig.CacheBehaviors.Items = [{ the cache behavior }] and set Quantity = 1
$ # save DistributionConfig key value to a file file:///tmp/new-distro-config.json
$ aws cloudfront update-distribution --id <MY-DISTROS-ID> --distribution-config file:///tmp/new-distro-config.json --if-match E2ABCDEFGHIJKL

这将成功地向现有 CloudFront 发行版添加新的缓存行为和来源。

我想使用 terraform 实现同样的最终目标,以便我可以在 S3 中保持状态。因此,例如,使用 terraform,我会

  • 构建云端发行版
  • 来自另一个 terraform 模块
    • 使用数据块导入云端发行版
    • 添加一次性缓存行为和来源

在 pseudocode-terraform 中,为了更清楚起见,下面的代码块进一步说明了这一点

# original CloudFront distro
resource "aws_cloudfront_distribution" "my-distro" {
  aliases = ["${var.my_alias_domain}"]

  origin {
    ...origin-info-for-default-cache-behavior
  }

  enabled = true

  default_cache_behavior {
    ...default-cache-behavior
  }

  ...more-cloudfront-stuff

}

然后在另一个 terraform 模块中(以及将来的某个时间),效果是

data "terraform_remote_state" "CloudFront" {
  backend = "s3"

  config {
    acl    = "bucket-owner-full-control"
    bucket = "${var.CloudFront_BUCKET}"
    key    = "${var.CloudFront_KEY}"
    region = "${var.CloudFront_REGION}"
  }
}

resource "aws_cloudfront_distribution_origin" "next-origin" {
  cloudfront_distribution_id = "${data.terraform_remote_state.CloudFront.id}"

  origin {
    ...origin-info-for-default-cache-behavior
  }

  ordered_cache_behavior {
    ...origin-info-for-cache-behavior
  }
}

我很清楚aws_cloudfront_distribution_origin 不是 terraform 中的资源。我只是在写这个伪代码来传达我想要完成的事情。这是一个实际的用例,用于拆分应该全部位于同一域下的服务。

在写完这一切之后,我假设我应该在这种情况下直接放弃 terraform 来代替 AWS CLI。但是,如果其他人使用 terraform 实现了这一点,我很想听听这是怎么可能的。

【问题讨论】:

    标签: amazon-cloudfront terraform terraform-provider-aws


    【解决方案1】:

    答案是 terraform v0.11 无法做到这一点(据我所知,其他情况仍然可以接受建议)。我试图通过设置count 属性来动态增加origin/ordered_cache_behavior 参数。类似于以下内容

    variable "s3_buckets_info" {
      type        = "list"
      description = "S3 buckets information"
      default = [{
        domain_name = "this.is.a.domain.com"
        app = "this.is.the.app"
        env = "this.is.the.env"
        path = "/match/this/path"
      }, {
        domain_name = "that.is.a.domain.com"
        app = "that.is.the.app"
        env = "that.is.the.env"
        path = "/match/that/path"
      }]
    }
    
    resource "aws_cloudfront_distribution" "eb_app" {
      aliases = ["${var.docs_alias_domain}"]
    
      origin {
        count       = "${length(var.s3_buckets_info)}"
    
        domain_name = "${lookup(var.s3_buckets_info[count.index + 1], "domain_name")}"
        origin_id   = "${lookup(var.s3_buckets_info[count.index + 1], "app")}-${lookup(var.s3_buckets_info[count.index + 1], "env")}"
        origin_path = ""
    

    然后我遇到了origin[0].count 不是一个可接受的论点的问题。经过更多谷歌搜索后,我发现了以下 GH 问题:

    这让我沮丧地意识到,为了利用这种行为,需要for and for-each 功能,这些功能目前仅在v0.12.0-beta1 中可用,他们建议不要在生产中使用这些功能,因为,嗯,这是一个测试版。

    【讨论】:

      【解决方案2】:

      我继续在 terraform 版本 12 中对此进行了破解。欢迎反馈!

      dynamic "origin" {
          for_each = [for i in "${var.dynamic_custom_origin_config}" : {
            name                     = i.domain_name
            id                       = i.origin_id
            path                     = i.origin_path
            http_port                = i.http_port
            https_port               = i.https_port
            origin_keepalive_timeout = i.origin_keepalive_timeout
            origin_read_timeout      = i.origin_read_timeout
            origin_protocol_policy   = i.origin_protocol_policy
            origin_ssl_protocols     = i.origin_ssl_protocols
          }]
          content {
            domain_name = origin.value.name
            origin_id   = origin.value.id
            origin_path = origin.value.path
            custom_origin_config {
              http_port                = origin.value.http_port
              https_port               = origin.value.https_port
              origin_keepalive_timeout = origin.value.origin_keepalive_timeout
              origin_read_timeout      = origin.value.origin_read_timeout
              origin_protocol_policy   = origin.value.origin_protocol_policy
              origin_ssl_protocols     = origin.value.origin_ssl_protocols
            }
          }
        }
      

      更多细节和其他示例可以在这里找到:https://github.com/jmgreg31/terraform_aws_cloudfront

      【讨论】:

      • 您应该在此处内联 minimal reproducible example,而不是链接到 GitHub。照原样,您的答案基本上是仅链接的答案,此处不鼓励这样做。
      • @ydaetskcoR 谢谢,我继续并更新了我的评论以包含 OP 想要做的代码 sn-p
      猜你喜欢
      • 2018-01-06
      • 2014-09-06
      • 1970-01-01
      • 2021-09-27
      • 2016-01-09
      • 1970-01-01
      • 2011-05-04
      • 1970-01-01
      • 2014-10-23
      相关资源
      最近更新 更多