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

Missing AWS Cognito Support #8309

Closed
BerndWessels opened this issue Aug 19, 2016 · 31 comments
Closed

Missing AWS Cognito Support #8309

BerndWessels opened this issue Aug 19, 2016 · 31 comments

Comments

@BerndWessels
Copy link

Hi there,

Terraform Version

0.7.0

Affected Resource(s)

  • aws

Expected Behavior

Support for AWS Cognito Identities and User Pools

Actual Behavior

Not supported yet

References

https://aws.amazon.com/cognito/

Question

Is anybody already working on this?

@ndcollins
Copy link

Would LOVE to see this added

@lbracken
Copy link

lbracken commented Oct 4, 2016

Would also like to see this supported.

@padajo
Copy link

padajo commented Oct 6, 2016

Definitely would like to see this. It's pretty much the only thing missing from being able to have our entire infrastructure in terraform
.

@kesor
Copy link

kesor commented Oct 11, 2016

There is a start at https://github.com/riccardo-89/terraform-provider-awsaddons and I can't find it right now, but there was another project that started work on this.

@oli-g
Copy link

oli-g commented Oct 28, 2016

Please add the AWS Cognito resource! It's the only component of our stack without Terraform support.

@marcalpla
Copy link

+1

1 similar comment
@remojansen
Copy link

👍

@kfloz
Copy link

kfloz commented Jan 21, 2017

any update on this guys? Would also love to see cognito support soon its a pretty key service for mobile apps!

@9bryan
Copy link

9bryan commented Jan 24, 2017

I would love to see this functionality too... Or at least know if I can assume it will be there in the future.

@jonnyshaw89
Copy link

👍

3 similar comments
@spocki
Copy link

spocki commented Feb 7, 2017

👍

@vpalos
Copy link

vpalos commented Feb 20, 2017

+1

@lbernail
Copy link

lbernail commented Mar 3, 2017

👍

@blaltarriba
Copy link

I'm looking forward to this too, I want to use Cognito User pools as API Gateway authorizers.

+1

@helun
Copy link

helun commented Mar 10, 2017

👍

@Ninir
Copy link
Contributor

Ninir commented Mar 18, 2017

Hi guys,

Started the work here: #12846

@9bryan
Copy link

9bryan commented May 22, 2017

@Ninir ,

Thanks for doing this!!!

Any chance you're considering adding cognito-idp as well?

-Bryan

@wweiss
Copy link

wweiss commented May 31, 2017

Hi,

If anyone is interested, here is how I have worked around this for right now. This solution allows you to add a Cognito User Pool to an API Gateway api as an authorizer, and then, assign that Authorizer to resources.

This solution assumes that you will only be using a single authorizer... Fair warning :)

First, a module to find the first authorizer id on an api:

##Module for finding authorizer ID

## Variables
variable "api_id" {
  type        = "string"
  description = "Id of the API Gateway REST api to search."
}

variable "region" {
  type        = "string"
  description = "(Optional) Name of the AWS region to search."
  default     = ""
}

## Main
data "aws_region" "current" {
  current = "${length(var.region)>0 ? 0 : 1 }"
  name    = "${length(var.region)>0 ? "${var.region}" : "" }"
}

data "external" "authorizer" {
  program = ["aws", "apigateway", "get-authorizers", "--rest-api-id", "${var.api_id}", "--region", "${data.aws_region.current.name}", "--query", "items[0].{name:name,id:id,arn:authorizerUri}"]
}

## Output
output "id" {
  value = "${data.external.authorizer.result.id}"
}

output "arn" {
  value = "${data.external.authorizer.result.arn}"
}

output "name" {
  value = "${data.external.authorizer.result.name}"
}

Next, the module to create an authorizer on an API:

##Module for adding user pool to an API Gateway

## Variables
variable "region" {
  type        = "string"
  description = "(Optional) AWS Region of the API Gateway Resource."
  default     = ""
}

variable "api_id" {
  type        = "string"
  description = "Id of the API Gateway REST api to associate with the Cognito User Pool."
}

variable "authorizer_name" {
  type        = "string"
  description = "Name of the new authorizer"
}

variable "user_pool_arn" {
  type        = "string"
  description = "ARN of the Cognito User Pool to use as an authorizer."
}

## Main
data "aws_region" "current" {
  current = "${length(var.region)>0 ? 0 : 1 }"
  name    = "${length(var.region)>0 ? "${var.region}" : "" }"
}

module "authorizer" {
  source = ".." #Authorizer Search Module (Change this!)

  api_id = "${var.api_id}"
  region = "${data.aws_region.current.name}"
}

resource "null_resource" "main" {
  count = "${length(module.authorizer.id)<1?1:0}"

  triggers {
    updated = "${var.authorizer_name}-${var.api_id}-${var.user_pool_arn}"
  }

  provisioner "local-exec" {
    command = "aws apigateway create-authorizer --rest-api-id ${var.api_id} --name '${var.authorizer_name}' --type COGNITO_USER_POOLS --provider-arns '${var.user_pool_arn}' --identity-source 'method.request.header.Auhtorization' --region '${data.aws_region.current.name}'"
  }
}

module "output_data" {
  source = ".." #Authorizer Search Module (Change this!)

  api_id = "${var.api_id}"
  region = "${data.aws_region.current.name}"
}

## Output
output "id" {
  value = "${module.output_data.id}"
}

output "arn" {
  value = "${module.output_data.arn}"
}

output "name" {
  value = "${module.output_data.name}"
}

Finally, the module to attach the authorizer to a resource:

##Module for finding authorizer IDs

## Variables
variable "region" {
  type        = "string"
  description = "(Optional) AWS Region of the API Gateway Resource."
  default     = ""
}

variable "api_id" {
  type        = "string"
  description = "Id of the API Gateway REST api associated with the resource."
}

variable "authorizer_id" {
  type        = "string"
  description = "Authorizer id for the Cognito User Pool to use for authentication."
}

variable "resource_id" {
  type        = "string"
  description = "The id of the API Gateway Resource to attach the authorizer to."
}

variable "method" {
  type        = "string"
  description = "The http method of the API Gateway Resource."
}

## Main
data "aws_region" "current" {
  current = "${length(var.region)>0 ? 0 : 1 }"
  name    = "${length(var.region)>0 ? "${var.region}" : "" }"
}

resource "null_resource" "main" {
  triggers {
    updated = "${var.authorizer_id}-${var.api_id}-${var.resource_id}-${var.method}"
  }

  provisioner "local-exec" {
    command = "aws apigateway update-method --rest-api-id ${var.api_id} --resource-id '${var.resource_id}' --http-method ${var.method} --region '${data.aws_region.current.name}' --patch-operations op='replace',path='/authorizerId',value='${var.authorizer_id}' op='replace',path='/authorizationType',value='COGNITO_USER_POOLS'"
  }
}

Hope this is helpful to someone else!

@blaltarriba
Copy link

Great approach @billyboingo

Thanks for sharing!

@Ninir
Copy link
Contributor

Ninir commented Jun 6, 2017

This might be the next work if you guys want :)

@alexchilcott
Copy link

As someone who is currently building something out and butting up against the lack of Terraform support for Cognito, this would be very much appreciated!

@zsims
Copy link

zsims commented Aug 1, 2017

For the record, and future readers, at least terraform v0.9.11 supports:

resource "aws_api_gateway_method" "request_method" {
  rest_api_id = "my-id"
  resource_id = "resource-id"
  http_method = "GET"
  authorization = "COGNITO_USER_POOLS"
  authorizer_id = "user-pool-authorizer-id"
}

Even though the docs don't specify (it's given straight to the AWS API). This means you won't need the "attach" module in @billyboingo comment

@giuseppeborgese
Copy link

hi @zsims , I tried your code but
I have always the error
Error creating API Gateway Method: BadRequestException: Invalid authorizer ID specified. Setting the authorization type to CUSTOM or COGNITO_USER_POOLS requires a valid authorizer.
and it is not clear to me if it is possible create the authorizer inside the API GW
image

i'm using the version 0.9.11 as you indicated
Any help would be very appreciated thanks in advance

@zsims
Copy link

zsims commented Aug 8, 2017

@giuseppeborgese you still need to create the authorizer in the API. You can either use the first two modules that @billyboingo kindly shared, or create it via CloudFormation.

So assuming you've got an AWS Cognito User Pool already created, then you can use CloudFormation and can avoid calling the API (e.g. no custom modules):

# API
resource "aws_api_gateway_rest_api" "my_api" {
  name = "My API"
}

# User pool authorizer
resource "aws_cloudformation_stack" "user_pool_authorizer" {
  name = "my-api-user-pool-authorizer"
  template_body = <<STACK
  {
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "MyFancyUserPoolAuthorizer": {
      "Type": "AWS::ApiGateway::Authorizer",
      "Properties": {
        "IdentitySource": "method.request.header.Authorization",
        "Name": "MyFancyUserPoolAuthorizer",
        "ProviderARNs": ["MY AWS COGNITO USER POOL ARN"],
        "RestApiId": "${aws_api_gateway_rest_api.my_api.id}",
        "Type": "COGNITO_USER_POOLS"
      }
    }
  },
  "Outputs": {
    "AuthorizerId": {"Value": { "Ref": "MyFancyUserPoolAuthorizer" }}
  }
}
STACK
}

# API Resource
resource "aws_api_gateway_resource" "example" {
  rest_api_id = "${aws_api_gateway_rest_api.my_api.id}"
  parent_id = "${aws_api_gateway_rest_api.my_api.root_resource_id}"
  path_part = "example"
}

# API Method that uses the authorizer
resource "aws_api_gateway_method" "request_method" {
  rest_api_id = "${aws_api_gateway_rest_api.my_api.id}"
  resource_id = "${aws_api_gateway_resource.example.id}"
  http_method = "GET"
  authorization = "COGNITO_USER_POOLS"
  authorizer_id = "${aws_cloudformation_stack.user_pool_authorizer.outputs["AuthorizerId"]}"
}

@giuseppeborgese
Copy link

@zsims you are a genius , your solution work very well and it is also easy to understand and integrate. I don't know how to say thank you .

@giuseppeborgese
Copy link

giuseppeborgese commented Sep 8, 2017 via email

@Ninir
Copy link
Contributor

Ninir commented Sep 8, 2017

Hey folks,

Will try to end the work on Cognito User pools very quickly, including all the current options provided by the API.
Please be patient a bit more: winter is Cognito User Pools are coming! 😄

@sergiocruzado
Copy link

sergiocruzado commented Nov 2, 2017

how is Cognito User Pools (not federated identities) going?

@Ninir
Copy link
Contributor

Ninir commented Nov 7, 2017

Hi @beeva-sergiocruzado

It's going pretty well. There are a lot of things to manage (admin options, schema, etc), but it's getting into shape. You can follow the progression here: hashicorp/terraform-provider-aws#232

@sergiocruzado
Copy link

Thanks @Ninir

@ghost
Copy link

ghost commented Apr 6, 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 have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@hashicorp hashicorp locked and limited conversation to collaborators Apr 6, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests