Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request - support custom domain in aws_cognito_user_pool_domain #5026

Closed
eigilsagafos opened this issue Jun 28, 2018 · 23 comments · Fixed by #6185
Closed

Feature Request - support custom domain in aws_cognito_user_pool_domain #5026

eigilsagafos opened this issue Jun 28, 2018 · 23 comments · Fixed by #6185
Labels
enhancement Requests to existing resources that expand the functionality or scope.
Milestone

Comments

@eigilsagafos
Copy link

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Description

Custom domain support was launced by AWS in June 2018 but not supported by Terraform. There is a new arn param for a certificate and if there is a certificate provided then the domain param will be the full domain. Right now validateCognitoUserPoolDomain function won't accept that.

New or Affected Resource(s)

  • aws_cognito_user_pool_domain

Potential Terraform Configuration

resource "aws_cognito_user_pool_domain" "main" {
  domain          = "auth.example.com"
  certificate_arn = "${aws_acm_certificate_validation.cert.certificate_arn}"
  user_pool_id    = "${aws_cognito_user_pool.pool.id}"
}

References

@bflad bflad added enhancement Requests to existing resources that expand the functionality or scope. service/cognito labels Jun 29, 2018
@ajb3ck
Copy link

ajb3ck commented Jun 29, 2018

@eigilsagafos have you found any way to do this pragmatically (without using the AWS Console)? I have not been able to find the functionality exposed in any of their APIs or via the CLI.

Would be awesome to see this as a functionality of terraform.

@eigilsagafos
Copy link
Author

@ajb3ck The AWS documentation is not updated as far as I know, but I inspected the traffic from the web dashboard and the only difference is that you pass the arn for the certificate.

@ajb3ck
Copy link

ajb3ck commented Aug 30, 2018

Just wanted to leave a note as the AWS Go SDK and Cognito API's have been updated to support this functionality. Would anyone be kind enough to pick up this effort?

Go SDK Docs for Cognito Identity Provider

Cognito API for Create User Pool Domain

@bflad
Copy link
Contributor

bflad commented Oct 31, 2018

Support for a new certificate_arn argument has been merged and will release with version 1.42.0 of the AWS provider, likely later today. 👍

@bflad
Copy link
Contributor

bflad commented Nov 1, 2018

This has been released in version 1.42.0 of the AWS provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.

@myedibleenso
Copy link

When creating a custom Cognito domain, the CloudFront distribution's DNS domain name is needed to create an alias record in Route 53. Looking at the docs, though, it doesn't appear that there is a data source for a aws_cloudfront_distribution.

Does anyone know if the domain name can be retrieved using the ARN in the output of this resource? For example, will the resource attribute for an aws_arn data source provide the DNS domain name?

@cloudlena
Copy link

I stumbled upon the same problem as @myedibleenso. It would be great to have the configuration of the aws_route53_record be part of the Custom Cognito domain example on https://www.terraform.io/docs/providers/aws/r/cognito_user_pool_domain.html.

@skehlet
Copy link

skehlet commented Nov 14, 2018

I was able to get my Cognito custom auth domain registered in Route53 with the following:

resource "aws_route53_record" "cognito_auth" {
  zone_id = "${data.aws_route53_zone.myzone.zone_id}"
  name    = "auth.${data.aws_route53_zone.myzone.name}"
  type    = "A"
  alias {
    name = "${aws_cognito_user_pool_domain.mydomain.cloudfront_distribution_arn}"
    // The following zone id is CloudFront.
    // See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget.html
    zone_id = "Z2FDTNDATAQYW2"
    evaluate_target_health = false
  }
}

@cloudlena
Copy link

Thanks, @skehlet. Hardcoding the zone_id isn't really an option for me though...

@skehlet
Copy link

skehlet commented Nov 14, 2018

@mastertinner Just for my own understanding, why can't you hardcode the zone id for CloudFront? Is there a case where the cloudfront_distribution_arn attribute exported by aws_cognito_user_pool_domain isn't CloudFront?

@myedibleenso
Copy link

Thanks, @skehlet. Based on the link you shared, it looks like CloudFront's Zone ID is always Z2FDTNDATAQYW2, so it might make sense for the configuration of such an alias record to be folded into aws_cognito_user_pool_domain.

Curious to hear what others think of this proposal...

@cloudlena
Copy link

cloudlena commented Nov 16, 2018

@skehlet, sorry I didn't properly read the link you added. In that case, hardcoding the zone_id is fine.

@cloudlena
Copy link

cloudlena commented Nov 26, 2018

@skehlet, sorry for bothering you again. I stumbled upon another problem. When creating the two resources, there seems to be a circular dependency:

resource "aws_route53_record" "auth" {
  zone_id = "${aws_route53_zone.main.id}"
  name    = "auth"
  type    = "A"

  alias {
    name                   = "${aws_cognito_user_pool_domain.main.cloudfront_distribution_arn}"
    zone_id                = "Z2FDTNDATAQYW2"                                                   // See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget.html
    evaluate_target_health = true
  }
}

resource "aws_cognito_user_pool_domain" "main" {
  domain          = "auth${var.resource_suffix}.${substr(aws_route53_zone.main.name, 0, length(aws_route53_zone.main.name) - 1)}"
  certificate_arn = "${aws_acm_certificate_validation.cert.certificate_arn}"
  user_pool_id    = "${aws_cognito_user_pool.main.id}"
}

If specified like that, Terraform will try to create the aws_cognito_user_pool_domain first because aws_route53_record references it as a variable. However, it won't succeed because, from the AWS API's perspective, the creation of the domain only succeeds if there is a valid alias record for the FQDN. How have you solved that problem?

@skehlet
Copy link

skehlet commented Nov 26, 2018

@mastertinner No worries, I think you're almost there, the issue is the parent domain (aws_route53_zone.main.name in your example) needs to already exist and be an A record, so you need to point it to something, for example your website.

I put a not-a-fully-working-app but hopefully good enough PoC up on github which creates the custom domain. Let me know if it helps. One thing relevant to what you pointed out, I had to add a depends_on to make the aws_cognito_user_pool_domain wait for the parent domain to be created.

@fkrauthan
Copy link

I have the same problem as @mastertinner . It seems like my aws_cognito_user_pool_domain deployment is stuck waiting for it to complete (I assume because it expects the cname record to be created). Which terraform will not do until after the pool domain is finished successful.

And yes I do have an A record for my base domain.

@miere
Copy link

miere commented Dec 31, 2018

Well, after struggling for a long time trying to setup a cognito user pool using custom domain I came to the conclusion that this feature is incomplete. Because of the nature of how AWS handle the custom domain creation, aws_cognito_user_pool_domain will wait until the DNS being proper configured on Route53. But, I would only use aws_route53_record to create an alias when I had the aws_cognito_user_pool_domain.my-custom-domain.cloudfront_distribution_arn available. Well, it's clear a deadlock situation which should be handled internally by terraform and not on my source code.

@skehlet
Copy link

skehlet commented Jan 2, 2019

I have a working example here. Can you compare it to what you have?

My custom cognito domain for the example is auth.aws.stevekehlet.com and here is the URL that starts the oauth2 flow with Cognito. If you mouse over that link you can see the custom domain, and if you click it you'll land on the Cognito login page and see the custom domain in your browser's URL box.

@miere
Copy link

miere commented Jan 3, 2019

Hi @skehlet, thanks for your reply.

I'm afraid I still didn't manage to fix the problem. Actually, my source code is quite similar to yours and I can't figure out the reason it doesn't work. Do you mind to take a look into my source code and the output log? Maybe a second pair of eyes would be great to figure out what is happening...

https://gist.github.com/miere/4f2c7c253216f771e8dc63b9c6ae88b3

@skehlet
Copy link

skehlet commented Jan 3, 2019

Hi @miere, I didn't finish looking through everything, but I saw your log (thank you for including!) and you ctrl-c'd after 17min, is this the problem you're seeing? When I was trying it, it really does take 30-45 minutes to finish.

@miere
Copy link

miere commented Jan 3, 2019

When I was trying it, it really does take 30-45 minutes to finish.

Unfortunately, 45 is a lot of time. I wonder how it would behave when I have to update my log in page, or need to change the Cognito's Pool configuration. Would my users face issues due to stale configuration? I'm not sure if I would have such a long maintenance window to apply these changes.

you ctrl-c'd after 17min, is this the problem you're seeing?

Not really, but let me share my thoughts with you:

  • The AWS Console states that it would take up to 15minutes to have the domain properly applied. And indeed, if you do it manually, or by using the AWS CLI, it take less than 15m to have the domain properly setup.
  • It was stuck at the aws_cognito_user_pool_domain.default execution. Although the docs doesn't state for how long it would take to change from the CREATING to ACTIVE state, in my local experiments it won't change if we don't update the DNS record to point to the correct CloudFront distribution.
  • That said I started to dig into the aws_cognito_user_pool_domain's source code to better understand how it works. To me it's clear that it waits until the status changes again to ACTIVE, what would never happen until the DNS register is updated.

I'll put a little more effort into this. Maybe, despite of my skepticism, I should wait more time to get it done.

@miere
Copy link

miere commented Jan 3, 2019

@skehlet As you've stated before, it took time (almost one hour) but it changed its status from CREATING to ACTIVE and therefore was able to assign a subdomain to it. I've also simulated a few changes on my User Pool and most of them were quite quick.

That said, it is obvious that I was wrong about this issue being unfinished. Despite of that I'd like to leave a few suggestions in order to improve the developer experience whilst using this particular resource:

  • It should clearly state that this would take a long time to finished. That could save me hours of trial and error.
  • The docs about this particular resource should definitely be update and include more examples. Luckily, I was capable to use Intellij's auto complete feature, AWS docs and few snippets found in the internet to move forward with this task. @skehlet working example would be a great start point, indeed.
  • I'm still a bit concerned about the time it takes to accomplish the first deployment. Most of CI/CD tools got used to impose low build times and encourage the build to be split into smaller pieces. In these cases, terraform would be restricted by this and the build would fail.
  • The validation strategy that checks if the status changed from CREATING to ACTIVE, in my opinion, could be optional. That would allow terraform to execute other tasks while the domain is being created, drastically lowering the build time and imposing a smaller the maintenance window in which users would experience stale configuration during upgrades.

@skehlet
Copy link

skehlet commented Jan 3, 2019

Hey @miere I'm glad you got it working! I think those are some valid points and would help people in the future. Related, there is one other big issue with Cognito custom domains for me, and that's the current hard limit of 4 custom domains per AWS account. I was originally planning on having one for each customer, but between that and the long time to provision, I have to figure out something else. AWS support told me to look into using API Gateway to reverse proxy Cognito's login page, which would avoid this limit, and might be faster to deploy too. Sounds unpleasant but doable. I haven't looked into it yet.

@ghost
Copy link

ghost commented Apr 1, 2020

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!

@ghost ghost locked and limited conversation to collaborators Apr 1, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement Requests to existing resources that expand the functionality or scope.
Projects
None yet
8 participants