devops-stack-module-oidc-aws-cognito

A DevOps Stack module to deploy and configure AWS Cognito as an OIDC provider.

You can simply use this module to create an OIDC client to use throughout the DevOps Stack applications or you can use it to entirely the needed resources for that OIDC client as well as a group and users with administrative access.

Usage

This module can be declared by adding the following block on your Terraform configuration:

module "oidc" {
  source = "git::https://github.com/camptocamp/devops-stack-module-oidc-aws-cognito.git?ref=<RELEASE>"

  cluster_name = module.eks.cluster_name
  base_domain  = module.eks.base_domain

  cognito_user_pool_id     = resource.aws_oidc_pool.pool.id
  cognito_user_pool_domain = resource.aws_cognito_user_pool_domain.pool_domain.domain
}

The above declaration assumes that you have created a Cognito pool and domain yourself, which you can do manually or you can create the following resources in your Terraform code:

resource "aws_cognito_user_pool" "pool" {
  name = module.eks.cluster_name
}

resource "aws_cognito_user_pool_domain" "pool_domain" {
  domain       = module.eks.cluster_name
  user_pool_id = aws_cognito_user_pool.pool.id
}

If you want this module to take charge of creating the Cognito pool and domain automatically, you simply need to activate the variable create_pool:

module "oidc" {
  source = "git::https://github.com/camptocamp/devops-stack-module-oidc-aws-cognito.git?ref=<RELEASE>"

  cluster_name = module.eks.cluster_name
  base_domain  = module.eks.base_domain

  create_pool = true
}

You can go even further and provide a map of users to the module and it will take care of creating an administrator group called devops-stack-admin with the users you specified. AWS Cognito will take the user’s e-mail addresses to send a temporary password in clear text, so these addresses need to be valid. For now, we devised this user creation in the code mainly as a way to bootstrap ephemeral clusters used for testing. To do this, you need to populate the user_map variable with an object for each user:

module "oidc" {
  source = "git::https://github.com/camptocamp/devops-stack-module-oidc-aws-cognito.git?ref=<RELEASE>"

  cluster_name = module.eks.cluster_name
  base_domain  = module.eks.base_domain

  create_pool = true

  user_map = {
    johndoe = {
      username   = "johndoe"
      first_name = "John"
      last_name  = "Doe"
      email      = "john.doe@example.com"
    }
    janedoe = {
      username   = "janedoe"
      first_name = "Jane"
      last_name  = "Doe"
      email      = "jane.doe@example.com"
    }
  }
}
Only the username and e-mail fields on each user are required. Besides, since the e-mail is a scope required by most of our apps, the e-mail is automatically set as verified when the users are created.
All users will belong to the administrators group and will have high privileges in applications such as Argo CD.

The module contains an output called devops_stack_admins where you can get a map containing every username and their respective e-mail.

OIDC Configuration

By default, the OIDC client is configured to allow returning to the canonical URLs of the default DevOps Stack applications. You can however use the variable callback_urls if you want to add any other callback URLs for the OIDC client:

module "oidc" {
  source = "git::https://github.com/camptocamp/devops-stack-module-oidc-aws-cognito.git?ref=<RELEASE>"

  cluster_name = module.eks.cluster_name
  base_domain  = module.eks.base_domain

  cognito_user_pool_id     = resource.aws_oidc_pool.pool.id
  cognito_user_pool_domain = resource.aws_cognito_user_pool_domain.pool_domain.domain

  callback_urls = [
    "https://callback1.url/oauth/callback",
    "https://callback2.url/login/generic_oauth",
  ]
}

The module provides and output called oidc containing the OIDC configuration that is to be passed on to other modules. This output is an object that outputs the content of local.oidc:

locals {
  oidc = {
    issuer_url              = format("https://cognito-idp.%s.amazonaws.com/%s", data.aws_region.current.name, local.cognito_user_pool_id)
    oauth_url               = format("https://%s.auth.%s.amazoncognito.com/oauth2/authorize", local.cognito_user_pool_domain, data.aws_region.current.name)
    token_url               = format("https://%s.auth.%s.amazoncognito.com/oauth2/token", local.cognito_user_pool_domain, data.aws_region.current.name)
    api_url                 = format("https://%s.auth.%s.amazoncognito.com/oauth2/userInfo", local.cognito_user_pool_domain, data.aws_region.current.name)
    client_id               = resource.aws_cognito_user_pool_client.client.id
    client_secret           = resource.aws_cognito_user_pool_client.client.client_secret
    oauth2_proxy_extra_args = []
  }
}

Technical Reference

Requirements

The following requirements are needed by this module:

Providers

The following providers are used by this module:

Required Inputs

The following input variables are required:

base_domain

Description: Base domain of the cluster. Value used for the ingress of .

Type: string

cluster_name

Description: Name given to the cluster. Value used for the ingress' URL of the application.

Type: string

Optional Inputs

The following input variables are optional (have default values):

callback_urls

Description: List of URLs where the authentication server is allowed to return during the authentication flow. Will be concatenated with the default URLs pertaining to the DevOps Stack.

Type: list(string)

Default: []

cognito_user_pool_domain

Description: Domain prefix of the Cognito user pool to use (custom domain currently not supported!). If the variable create_pool is activated, the module will create its own pool and this variable will not be used.

Type: string

Default: null

cognito_user_pool_id

Description: ID of the Cognito user pool to use. If the variable create_pool is activated, the module will create its own pool and this variable will not be used.

Type: string

Default: null

create_pool

Description: Boolean to activate the creation of the pool. If set as true you cannot specify the variables cognito_user_pool_id and cognito_user_pool_domain.

Type: bool

Default: false

dependency_ids

Description: IDs of the other modules on which this module depends on.

Type: map(string)

Default: {}

user_map

Description: List of users to be added to the default admin group. Note that all fields are mandatory. These users will be given a temporary password on their invitation e-mail, so the address needs to be valid.

Type:

map(object({
    username   = string
    email      = string
    first_name = optional(string)
    last_name  = optional(string)
  }))

Default: {}

Outputs

The following outputs are exported:

cognito_user_pool_id

Description: ID of the Cognito user pool. It will either be the ID of the pool created by this module or simply the ID that was given to the variable cognito_user_pool_id.

devops_stack_admins

Description: Map containing the usernames and e-mails of the created users from var.user_map.

id

Description: ID to pass other modules in order to refer to this module as a dependency.

oidc

Description: Object containing multiple OIDC configuration values.

Reference in table format

Show tables

= Requirements

Name Version

aws

>= 4

>= 3

= Providers

Name Version

aws

>= 4

>= 3

= Resources

Name Type

resource

resource

resource

resource

resource

resource

resource

resource

data source

= Inputs

Name Description Type Default Required

Base domain of the cluster. Value used for the ingress of .

string

n/a

yes

List of URLs where the authentication server is allowed to return during the authentication flow. Will be concatenated with the default URLs pertaining to the DevOps Stack.

list(string)

[]

no

Name given to the cluster. Value used for the ingress' URL of the application.

string

n/a

yes

Domain prefix of the Cognito user pool to use (custom domain currently not supported!). If the variable create_pool is activated, the module will create its own pool and this variable will not be used.

string

null

no

ID of the Cognito user pool to use. If the variable create_pool is activated, the module will create its own pool and this variable will not be used.

string

null

no

Boolean to activate the creation of the pool. If set as true you cannot specify the variables cognito_user_pool_id and cognito_user_pool_domain.

bool

false

no

IDs of the other modules on which this module depends on.

map(string)

{}

no

List of users to be added to the default admin group. Note that all fields are mandatory. These users will be given a temporary password on their invitation e-mail, so the address needs to be valid.

map(object({
    username   = string
    email      = string
    first_name = optional(string)
    last_name  = optional(string)
  }))

{}

no

= Outputs

Name Description

ID of the Cognito user pool. It will either be the ID of the pool created by this module or simply the ID that was given to the variable cognito_user_pool_id.

Map containing the usernames and e-mails of the created users from var.user_map.

id

ID to pass other modules in order to refer to this module as a dependency.

Object containing multiple OIDC configuration values.