Terraform-provider-aws: multiple origin in a cloudfront module

Created on 6 Apr 2018  ·  14Comments  ·  Source: hashicorp/terraform-provider-aws

Terraform Version

Terraform v0.11.5

  • provider.aws v1.13.0
  • provider.random v1.2.0

Affected Resource(s)

Please list the resources as a list, for example:
cloudfront

According to TF docs
https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html#origin
origin (Required) - One or more origins for this distribution (multiples allowed).

but when resource "aws_cloudfront_distribution" is inside a module, there is no way to pass dynamically a number of origins.
From a quick look on aws API docs there isnt a method to add extra origins either.

So TF needs a new resource that pulls the state, calculate the change in number of origins and sends it back as a single call.

References

similar https://github.com/terraform-providers/terraform-provider-aws/issues/3937

enhancement serviccloudfront terraform-0.12

Most helpful comment

Hello @FernandoMiguel
Can you detail the method of lists of lists, if at least something works

All 14 comments

Thanks for the issue @FernandoMiguel

So TF needs a new resource that pulls the state, calculate the change in number of origins and sends it back as a single call.

I'm curious how you're imagining this workflow happening, could you elaborate?

@catsby from the discussion i had with @tombuildsstuff , the idea would be for a TF resource to add/remove cloudfront origins.
i'm guessing similar to aws_s3_bucket_policy, where a user would create a new origin resource and attach it to an existing Distribution

does this make sense?

Yes it does, unfortunately the Cloudfront Distribution API doesn't allow you to create a distribution with no origins. S3 buckets can be created independently, and the policy added/removed independently 🤔

I'm fine with passing one origin in the module invocation if I can have a resource to add more.

I tried the method of lists of lists which kinda worked, but is definitely too complex for most users, specially without a good example in the docs.
A origin resource would make it much easier for humans to read and code.

I also think it would be great to be able to attach origins as separate TF resources similar to s3 bucket policies. I'm trying to create a cloudfront module that we can re-use but there is no easy way to create the module without knowing how many origins and their type (custom or S3) ahead of time. By creating separate resources I would be able to use count create as many as I need.

Would it be possible for the provider to do some error checking ahead of time and ensure there is at least one origin added to the distribution before applying and throw an error if there isn't?

Hello @FernandoMiguel
Can you detail the method of lists of lists, if at least something works

@catsby : As I need same function, I've started to work on it, but I'm not a dev, so it could be really improved for better.
You can see my start of progress here : https://github.com/terraform-providers/terraform-provider-aws/compare/master...sousmangoosta:issue4094

Why do I need this function ? I got a global cloudfront ditribution who contains a domain name, that we want to share withing different devops teams. Each team just need to refer to the cloudfront distribution ID, to update the distribution with new Origins and Beahaviors.

Here for create I retrieve existing cloudfront ditribution config, merge new origin items with existing ones, and send the new config to cloudfront. For now this workflow works.
For read, I retrieve the config, extract only origin-id(s) that matching with my tfstates one(s), and the compare works.

I will try to finish update and delete, and do same things for behaviors

EDIT: CRUD is now complete for aws_cloudfront_origin, will try to make same thing on behaviors.
EDIT2: CRUS is now ok for aws_cloudfront_behavior
EDIT3: I did quick and dirty code to manage aws_cloudfront_distribution resources.
Here I can't set a ForceNew on path, cause it delete all distribution.

I tried the method of lists of lists which kinda worked, but is definitely too complex for most users, specially without a good example in the docs.

@FernandoMiguel I would also love to hear more about this method. Much googling doesn't seem to bring anything related up.

@zwily @Menahem1 i havent touchted this in many months.
i'll probably have to reimplement this soon again, so i'll see what works and what doesnt

Hi folks 👋Terraform 0.12, which just released its first beta, can better handle this situation by supporting a new looping mechanism using the new for syntax. This mechanism is a generic solution to implementing "count"-like functionality for configuration blocks across any Terraform resource and I'd suggest its usage for these use cases.

Please do reach out if there are specific implementation details not possible with that support.

I wanted to provide the solution that I was able to get working based off of @FernandoMiguel idea of creating a list of lists. I am not sure if it is best practice, and is certainly not the cleanest (maintaining tfvars files), but appears to work for our needs. Hope it helps while we wait for the production release of Terraform v0.12. Note: This will also work with ordered cache behavior

main.tf

variable origin{type = "list"}

resource "aws_cloudfront_distribution" "cloudfront_distribution" {
  origin                 = "${var.origin}"
...

terraform.tfvars

origin = [{
        domain_name = "domain1.com"
        origin_id   = "id1"
        s3_origin_config = [{
            origin_access_identity = "origin-access-identity/cloudfront/<ID>"
            }]
    } ,
    {
        domain_name = "domain2.com"
        origin_id   = "id2"
        custom_origin_config = [{
            http_port              = 80
            https_port             = 443
            origin_keepalive_timeout = 5
            origin_read_timeout = 30
            origin_protocol_policy = "https-only"
            origin_ssl_protocols   = ["TLSv1.2","TLSv1.1"]
            }]
    }]

I guess now 012 is out and has dynamic blocks, and that should fix this.
Closing

@FernandoMiguel I went ahead and took an initial crack at this HERE

It is missing some features but is the general idea, I believe. Open to feedback!

I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

Was this page helpful?
0 / 5 - 0 ratings