├── .github
├── CODEOWNERS
└── workflows
│ └── main.yml
├── examples
├── user-pool-with-default-settings
│ ├── outputs.tf
│ ├── main.tf
│ └── README.md
├── complete
│ ├── outputs.tf
│ ├── main.tf
│ └── README.md
└── README.md
├── versions.tf
├── .pre-commit-config.yaml
├── resource-server.tf
├── test
├── unit_disabled_test.go
├── unit_complete_test.go
├── unit_minimal_test.go
├── unit-disabled
│ └── main.tf
├── unit-minimal
│ └── main.tf
├── README.md
└── unit-complete
│ └── main.tf
├── .gitignore
├── .golangci.yml
├── outputs.tf
├── go.mod
├── CONTRIBUTING.md
├── Makefile
├── CHANGELOG.md
├── LICENSE
├── main.tf
├── variables.tf
├── README.md
└── README.tfdoc.hcl
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @mariux @mineiros-io/terraform-service-catalog
2 |
--------------------------------------------------------------------------------
/examples/user-pool-with-default-settings/outputs.tf:
--------------------------------------------------------------------------------
1 | output "user_pool" {
2 | description = "The full `aws_cognito_user_pool` object."
3 | value = module.cognito_user_pool.user_pool
4 | }
5 |
--------------------------------------------------------------------------------
/versions.tf:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------------
2 | # SET TERRAFORM AND PROVIDER REQUIREMENTS FOR RUNNING THIS MODULE
3 | # ------------------------------------------------------------------------------
4 |
5 | terraform {
6 | required_version = ">= 0.12.20, < 2.0"
7 |
8 | required_providers {
9 | aws = ">= 3.50, < 5.0"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/mineiros-io/pre-commit-hooks
3 | rev: v0.3.1
4 | hooks:
5 | - id: terraform-fmt
6 | - id: terraform-validate
7 | exclude: ^examples|.terraform/
8 | - id: tflint
9 | - id: golangci-lint
10 | - id: phony-targets
11 | - id: markdown-link-check
12 | args: ['-p'] # When adding the -p flag, markdown-link-check will always with an exit code 0, even if dead links are found
13 | verbose: true # Forces the output of the hook to be printed even when the hook passes.
14 |
--------------------------------------------------------------------------------
/resource-server.tf:
--------------------------------------------------------------------------------
1 | resource "aws_cognito_resource_server" "resource_server" {
2 | for_each = var.module_enabled ? { for resource in var.resource_servers : resource.identifier => resource } : {}
3 | identifier = each.value.identifier
4 | name = try(each.value.name, null)
5 | user_pool_id = aws_cognito_user_pool.user_pool[0].id
6 |
7 | dynamic "scope" {
8 | for_each = try(each.value.scopes, [])
9 |
10 | content {
11 | scope_name = scope.value.scope_name
12 | scope_description = scope.value.scope_description
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/examples/complete/outputs.tf:
--------------------------------------------------------------------------------
1 | output "user_pool" {
2 | description = "All outputs exposed by the module."
3 | value = merge(module.cognito_user_pool, { client_secrets = null })
4 | }
5 |
6 | output "clients" {
7 | description = "All Cognito User Pool Client resources associated with the Cognito User Pool."
8 | value = { for client in module.cognito_user_pool.clients : client.name => merge(client, { client_secret = null }) }
9 | }
10 |
11 | output "client_secrets" {
12 | description = "The secrets of all created Cognito User Pool Client resources."
13 | value = module.cognito_user_pool.client_secrets
14 | sensitive = true
15 | }
16 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: CI/CD Pipeline
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 |
11 | env:
12 | AWS_SECRET_ACCESS_KEY: ${{ secrets.MINEIROS_TESTING_AWS_SECRET_ACCESS_KEY }}
13 | AWS_ACCESS_KEY_ID: ${{ secrets.MINEIROS_TESTING_AWS_ACCESS_KEY_ID }}
14 |
15 | jobs:
16 | pre-commit:
17 | runs-on: ubuntu-latest
18 | name: Static Analysis
19 | steps:
20 | - name: Checkout
21 | uses: actions/checkout@v2
22 | - name: Run pre-commit
23 | run: make test/pre-commit
24 |
25 | unit-tests:
26 | runs-on: ubuntu-latest
27 | name: Unit Tests
28 | steps:
29 | - name: Checkout
30 | uses: actions/checkout@v2
31 | - name: Run Unit Tests
32 | run: make test/unit-tests
33 |
--------------------------------------------------------------------------------
/examples/user-pool-with-default-settings/main.tf:
--------------------------------------------------------------------------------
1 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 | # DEPLOY A COGNITO USER POOL
3 | # This example deploys a Cognito User Pool with default settings that are
4 | # defined in the variables.tf file of this module.
5 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 |
7 | # ------------------------------------------------------------------------------
8 | # PROVIDER CONFIGURATION
9 | # ------------------------------------------------------------------------------
10 |
11 | provider "aws" {
12 | region = "us-east-1"
13 | }
14 |
15 | # ------------------------------------------------------------------------------
16 | # THE COGNITO USER POOL WITH DEFAULT SETTINGS
17 | # ------------------------------------------------------------------------------
18 |
19 | module "cognito_user_pool" {
20 | source = "mineiros-io/cognito-user-pool/aws"
21 | version = "~> 0.9.0"
22 |
23 | name = "example-userpool"
24 | }
25 |
--------------------------------------------------------------------------------
/test/unit_disabled_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/gruntwork-io/terratest/modules/terraform"
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func TestUnitDisabled(t *testing.T) {
11 | t.Parallel()
12 |
13 | terraformOptions := &terraform.Options{
14 | TerraformDir: "unit-disabled",
15 | Vars: map[string]interface{}{
16 | "aws_region": "us-east-1",
17 | },
18 | Upgrade: true,
19 | }
20 |
21 | defer terraform.Destroy(t, terraformOptions)
22 |
23 | terraform.InitAndPlan(t, terraformOptions)
24 | stdout := terraform.ApplyAndIdempotent(t, terraformOptions)
25 |
26 | resourceCount := terraform.GetResourceCount(t, stdout)
27 | assert.Equal(t, 0, resourceCount.Add, "No resources should have been created. Found %d instead.", resourceCount.Add)
28 | assert.Equal(t, 0, resourceCount.Change, "No resources should have been changed. Found %d instead.", resourceCount.Change)
29 | assert.Equal(t, 0, resourceCount.Destroy, "No resources should have been destroyed. Found %d instead.", resourceCount.Destroy)
30 | }
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # IntelliJ files
2 | .idea_modules
3 | *.iml
4 | *.iws
5 | *.ipr
6 | .idea/
7 | build/
8 | */build/
9 | out/
10 |
11 | # macOS files
12 | .history
13 | .DS_Store
14 |
15 | # Local .terraform directories
16 | **/.terraform/*
17 |
18 | # .tfstate files
19 | *.tfstate
20 | *.tfstate.*
21 |
22 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most
23 | # .tfvars files are managed as part of configuration and so should be included in
24 | # version control.
25 | #
26 | # example.tfvars
27 |
28 | # Ignore override files as they are usually used to override resources locally and so
29 | # are not checked in
30 | override.tf
31 | override.tf.json
32 | *_override.tf
33 | *_override.tf.json
34 |
35 | # Include override files you do wish to add to version control using negated pattern
36 | #
37 | # !example_override.tf
38 |
39 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
40 | # example: *tfplan*
41 | *.tfplan
42 |
43 | # Go best practices dictate that libraries should not include the vendor directory
44 | vendor
45 |
46 | # Terratest directory used to store temporary data
47 | .test-data
48 |
49 | # Terraform crash log files
50 | crash.log
51 |
--------------------------------------------------------------------------------
/test/unit_complete_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/gruntwork-io/terratest/modules/terraform"
7 | )
8 |
9 | func TestUnitComplete(t *testing.T) {
10 | t.Parallel()
11 |
12 | terraformOptions := &terraform.Options{
13 | TerraformDir: "unit-complete",
14 | Vars: map[string]interface{}{
15 | "aws_region": "us-east-1",
16 | },
17 | Upgrade: true,
18 | }
19 |
20 | defer terraform.Destroy(t, terraformOptions)
21 |
22 | terraform.InitAndPlan(t, terraformOptions)
23 | terraform.ApplyAndIdempotent(t, terraformOptions)
24 |
25 | // Replace ApplyAndIdempotent() check with below code if provider and terraform report output changes that
26 | // can not be prevented due to some bugs in this feature
27 |
28 | // terraform.Apply(t, terraformOptions)
29 |
30 | // stdout := terraform.Plan(t, terraformOptions)
31 |
32 | // resourceCount := terraform.GetResourceCount(t, stdout)
33 | // assert.Equal(t, 0, resourceCount.Add, "No resources should have been created. Found %d instead.", resourceCount.Add)
34 | // assert.Equal(t, 0, resourceCount.Change, "No resources should have been changed. Found %d instead.", resourceCount.Change)
35 | // assert.Equal(t, 0, resourceCount.Destroy, "No resources should have been destroyed. Found %d instead.", resourceCount.Destroy)
36 | }
37 |
--------------------------------------------------------------------------------
/test/unit_minimal_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/gruntwork-io/terratest/modules/terraform"
7 | )
8 |
9 | func TestUnitMinimal(t *testing.T) {
10 | t.Parallel()
11 |
12 | terraformOptions := &terraform.Options{
13 | TerraformDir: "unit-minimal",
14 | Vars: map[string]interface{}{
15 | "aws_region": "us-east-1",
16 | },
17 | Upgrade: true,
18 | }
19 |
20 | defer terraform.Destroy(t, terraformOptions)
21 |
22 | terraform.InitAndPlan(t, terraformOptions)
23 | terraform.ApplyAndIdempotent(t, terraformOptions)
24 |
25 | // Replace ApplyAndIdempotent() check with below code if provider and terraform report output changes that
26 | // can not be prevented due to some bugs in this feature
27 |
28 | // terraform.Apply(t, terraformOptions)
29 |
30 | // stdout := terraform.Plan(t, terraformOptions)
31 |
32 | // resourceCount := terraform.GetResourceCount(t, stdout)
33 | // assert.Equal(t, 0, resourceCount.Add, "No resources should have been created. Found %d instead.", resourceCount.Add)
34 | // assert.Equal(t, 0, resourceCount.Change, "No resources should have been changed. Found %d instead.", resourceCount.Change)
35 | // assert.Equal(t, 0, resourceCount.Destroy, "No resources should have been destroyed. Found %d instead.", resourceCount.Destroy)
36 | }
37 |
--------------------------------------------------------------------------------
/test/unit-disabled/main.tf:
--------------------------------------------------------------------------------
1 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 | # EMPTY FEATURES (DISABLED) UNIT TEST
3 | # This module tests an empty set of features.
4 | # The purpose is to verify no resources are created when the module is disabled.
5 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 |
7 | variable "aws_region" {
8 | description = "(Optional) The AWS region in which all resources will be created."
9 | type = string
10 | default = "us-east-1"
11 | }
12 |
13 | terraform {
14 | required_providers {
15 | aws = {
16 | source = "hashicorp/aws"
17 | version = "~> 4.0"
18 | }
19 | }
20 | }
21 |
22 | provider "aws" {
23 | region = var.aws_region
24 | }
25 |
26 | # DO NOT RENAME MODULE NAME
27 | module "test" {
28 | source = "../.."
29 |
30 | name = "example-cognito-user-pool"
31 |
32 | module_enabled = false
33 |
34 | # add all required arguments
35 |
36 | # add all optional arguments that create additional resources
37 | }
38 |
39 | # outputs generate non-idempotent terraform plans so we disable them for now unless we need them.
40 | # output "all" {
41 | # description = "All outputs of the module."
42 | # value = module.test
43 | # }
44 |
--------------------------------------------------------------------------------
/test/unit-minimal/main.tf:
--------------------------------------------------------------------------------
1 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 | # MINIMAL FEATURES UNIT TEST
3 | # This module tests a minimal set of features.
4 | # The purpose is to test all defaults for optional arguments and just provide the required arguments.
5 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 |
7 | variable "aws_region" {
8 | description = "(Optional) The AWS region in which all resources will be created."
9 | type = string
10 | default = "us-east-1"
11 | }
12 |
13 | terraform {
14 | required_providers {
15 | aws = {
16 | source = "hashicorp/aws"
17 | # always test with exact version to catch unsupported blocks/arguments early
18 | # this should match the minimal version in versions.tf
19 | version = "3.50.0"
20 | }
21 | }
22 | }
23 |
24 | provider "aws" {
25 | region = var.aws_region
26 | }
27 |
28 | # DO NOT RENAME MODULE NAME
29 | module "test" {
30 | source = "../.."
31 |
32 | name = "example-cognito-user-pool"
33 |
34 | # add only required arguments and no optional arguments
35 | }
36 |
37 | # outputs generate non-idempotent terraform plans so we disable them for now unless we need them.
38 | # output "all" {
39 | # description = "All outputs of the module."
40 | # value = module.test
41 | # }
42 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | [
][homepage]
2 |
3 | [![GitHub tag (latest SemVer)][badge-semver]][releases-github]
4 | [![license][badge-license]][apache20]
5 | [![Terraform Version][badge-terraform]][releases-terraform]
6 | [![Join Slack][badge-slack]][slack]
7 |
8 | # Examples for using this Mineiros module
9 |
10 | - [complete/] Deploy a Cognito User Pool with custom settings.
11 | - [user-pool-with-default-settings/] Deploy a Cognito User Pool with custom settings.
12 |
13 |
14 | [complete/]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/examples/complete
15 | [user-pool-with-default-settings/]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/examples/user-pool-with-default-settings
16 |
17 | [homepage]: https://mineiros.io/?ref=terraform-aws-cognito-user-pool
18 |
19 | [badge-license]: https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg
20 | [badge-terraform]: https://img.shields.io/badge/terraform-1.x%20|%200.15%20|%200.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform
21 | [badge-slack]: https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack
22 | [badge-semver]: https://img.shields.io/github/v/tag/mineiros-io/terraform-aws-cognito-user-pool.svg?label=latest&sort=semver
23 |
24 | [releases-github]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/releases
25 | [releases-terraform]: https://github.com/hashicorp/terraform/releases
26 | [apache20]: https://opensource.org/licenses/Apache-2.0
27 | [slack]: https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg
28 |
--------------------------------------------------------------------------------
/.golangci.yml:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------------------------------------------------
2 | # GOLANG LINTER RULES
3 | # ----------------------------------------------------------------------------------------------------------------------
4 |
5 | # configure golangci-lint
6 | # see https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml
7 | issues:
8 | exclude-rules:
9 | - path: _test\.go
10 | linters:
11 | - dupl
12 | - gosec
13 | - goconst
14 | linters:
15 | enable:
16 | - bodyclose
17 | - deadcode
18 | - depguard
19 | - dupl
20 | - errcheck
21 | - gocritic
22 | - gofmt
23 | - goconst
24 | - goimports
25 | - gosec
26 | - gosimple
27 | - revive
28 | - govet
29 | - ineffassign
30 | - interfacer
31 | - misspell
32 | - nakedret
33 | - prealloc
34 | - staticcheck
35 | - structcheck
36 | - stylecheck
37 | - typecheck
38 | - unconvert
39 | - unparam
40 | - unused
41 | - varcheck
42 | - whitespace
43 |
44 | linters-settings:
45 | errcheck:
46 | # report about assignment of errors to blank identifier: `num, _ := strcnv.Atoi(numStr)`;
47 | # default is false: such cases aren't reported by default.
48 | check-blank: true
49 | ignore: fmt:.*,[rR]ead|[wW]rite|[cC]lose,io:Copy
50 | govet:
51 | # report about shadowed variables
52 | check-shadowing: true
53 | gocyclo:
54 | # minimal code complexity to report, 30 by default
55 | min-complexity: 15
56 | maligned:
57 | # print struct with more effective memory layout or not, false by default
58 | suggest-new: true
59 | gofmt:
60 | # simplify code: gofmt with `-s` option, true by default
61 | simplify: true
62 |
--------------------------------------------------------------------------------
/outputs.tf:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------------
2 | # OUTPUT CALCULATED VARIABLES (prefer full objects)
3 | # ------------------------------------------------------------------------------
4 |
5 | # ------------------------------------------------------------------------------
6 | # OUTPUT ALL RESOURCES AS FULL OBJECTS
7 | # ------------------------------------------------------------------------------
8 |
9 | # fix tf13 output diff
10 | locals {
11 | user_pool = try(aws_cognito_user_pool.user_pool[0], {})
12 |
13 | o_user_pool_tags = try(local.user_pool.tags, {})
14 |
15 | o_user_pool = var.module_enabled ? merge(local.user_pool, {
16 | tags = local.o_user_pool_tags != null ? local.user_pool.tags : {}
17 | }) : null
18 | }
19 |
20 |
21 | output "user_pool" {
22 | description = "The full `aws_cognito_user_pool` object."
23 | value = local.o_user_pool
24 | }
25 |
26 | output "domain" {
27 | description = "The full `aws_cognito_user_pool` object."
28 | value = try(aws_cognito_user_pool_domain.domain[0], null)
29 | }
30 |
31 | output "clients" {
32 | description = "All Cognito User Pool Client resources associated with the Cognito User Pool."
33 | value = { for client in aws_cognito_user_pool_client.client : client.name => merge(client, { client_secret = null }) }
34 | }
35 |
36 | output "client_secrets" {
37 | description = "The secrets of all created Cognito User Pool Client resources."
38 | value = { for client in aws_cognito_user_pool_client.client : client.name => client.client_secret }
39 | sensitive = true
40 | }
41 |
42 | # ------------------------------------------------------------------------------
43 | # OUTPUT ALL INPUT VARIABLES
44 | # ------------------------------------------------------------------------------
45 |
46 | # ------------------------------------------------------------------------------
47 | # OUTPUT MODULE CONFIGURATION
48 | # ------------------------------------------------------------------------------
49 |
50 | output "module_enabled" {
51 | description = "Whether the module is enabled"
52 | value = var.module_enabled
53 | }
54 |
--------------------------------------------------------------------------------
/examples/user-pool-with-default-settings/README.md:
--------------------------------------------------------------------------------
1 | [
][homepage]
2 |
3 | [![license][badge-license]][apache20]
4 | [![Terraform Version][badge-terraform]][releases-terraform]
5 | [![Join Slack][badge-slack]][slack]
6 |
7 | # What this example shows
8 |
9 | The code in [main.tf]
10 | shows how to deploy a Cognito User Pool with default settings that are
11 | defined in the [variables.tf] file of this module.
12 |
13 | ```hcl
14 | module "cognito_user_pool" {
15 | source = "mineiros-io/cognito-user-pool/aws"
16 | version = "~> 0.8.0"
17 |
18 | name = "example-userpool"
19 | }
20 | ```
21 |
22 | ## Running the example
23 |
24 | ### Cloning the repository
25 |
26 | ```bash
27 | git clone https://github.com/mineiros-io/terraform-aws-cognito-user-pool.git
28 | cd terraform-aws-cognito-user-pool/examples/user-pool-with-default-settings
29 | ```
30 |
31 | ### Initializing Terraform
32 |
33 | Run `terraform init` to initialize the example and download providers and the module.
34 |
35 | ### Planning the example
36 |
37 | Run `terraform plan` to see a plan of the changes.
38 |
39 | ### Applying the example
40 |
41 | Run `terraform apply` to create the resources.
42 | You will see a plan of the changes and Terraform will prompt you for approval to actually apply the changes.
43 |
44 | ### Destroying the example
45 |
46 | Run `terraform destroy` to destroy all resources again.
47 |
48 |
49 |
50 | [main.tf]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/tree/master/examples/user-pool-with-default-settings/main.tf
51 | [variables.tf]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/tree/master/variables.tf
52 |
53 | [homepage]: https://mineiros.io/?ref=terraform-aws-cognito-user-pool
54 |
55 | [badge-license]: https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg
56 | [badge-terraform]: https://img.shields.io/badge/terraform-1.x%20|%200.15%20|%200.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform
57 | [badge-slack]: https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack
58 |
59 | [releases-terraform]: https://github.com/hashicorp/terraform/releases
60 | [apache20]: https://opensource.org/licenses/Apache-2.0
61 | [slack]: https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg
62 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/mineiros-io/terraform-aws-cognito-user-pool
2 |
3 | go 1.17
4 |
5 | require (
6 | github.com/gruntwork-io/terratest v0.40.0
7 | github.com/stretchr/testify v1.7.0
8 | )
9 |
10 | require (
11 | cloud.google.com/go v0.83.0 // indirect
12 | cloud.google.com/go/storage v1.10.0 // indirect
13 | github.com/agext/levenshtein v1.2.3 // indirect
14 | github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
15 | github.com/aws/aws-sdk-go v1.40.56 // indirect
16 | github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
17 | github.com/davecgh/go-spew v1.1.1 // indirect
18 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
19 | github.com/golang/protobuf v1.5.2 // indirect
20 | github.com/golang/snappy v0.0.3 // indirect
21 | github.com/googleapis/gax-go/v2 v2.0.5 // indirect
22 | github.com/hashicorp/errwrap v1.0.0 // indirect
23 | github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
24 | github.com/hashicorp/go-getter v1.5.9 // indirect
25 | github.com/hashicorp/go-multierror v1.1.0 // indirect
26 | github.com/hashicorp/go-safetemp v1.0.0 // indirect
27 | github.com/hashicorp/go-version v1.3.0 // indirect
28 | github.com/hashicorp/hcl/v2 v2.9.1 // indirect
29 | github.com/hashicorp/terraform-json v0.13.0 // indirect
30 | github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
31 | github.com/jmespath/go-jmespath v0.4.0 // indirect
32 | github.com/jstemmer/go-junit-report v0.9.1 // indirect
33 | github.com/klauspost/compress v1.13.0 // indirect
34 | github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 // indirect
35 | github.com/mitchellh/go-homedir v1.1.0 // indirect
36 | github.com/mitchellh/go-testing-interface v1.0.0 // indirect
37 | github.com/mitchellh/go-wordwrap v1.0.1 // indirect
38 | github.com/pmezard/go-difflib v1.0.0 // indirect
39 | github.com/tmccombs/hcl2json v0.3.3 // indirect
40 | github.com/ulikunitz/xz v0.5.8 // indirect
41 | github.com/zclconf/go-cty v1.9.1 // indirect
42 | go.opencensus.io v0.23.0 // indirect
43 | golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
44 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
45 | golang.org/x/mod v0.4.2 // indirect
46 | golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
47 | golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c // indirect
48 | golang.org/x/sys v0.0.0-20210603125802-9665404d3644 // indirect
49 | golang.org/x/text v0.3.6 // indirect
50 | golang.org/x/tools v0.1.2 // indirect
51 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
52 | google.golang.org/api v0.47.0 // indirect
53 | google.golang.org/appengine v1.6.7 // indirect
54 | google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect
55 | google.golang.org/grpc v1.38.0 // indirect
56 | google.golang.org/protobuf v1.26.0 // indirect
57 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
58 | )
59 |
--------------------------------------------------------------------------------
/test/README.md:
--------------------------------------------------------------------------------
1 | [
][homepage]
2 |
3 | [![license][badge-license]][apache20]
4 | [![Terraform Version][badge-terraform]][releases-terraform]
5 | [![Join Slack][badge-slack]][slack]
6 |
7 | # Tests
8 |
9 | This directory contains a number of automated tests that cover the functionality
10 | of the modules that ship with this repository.
11 |
12 | ## Introduction
13 |
14 | We are using [Terratest] for automated tests that are located in the
15 | [`test/` directory][testdirectory]. Terratest deploys _real_ infrastructure
16 | (e.g., servers) in a _real_ environment (e.g., AWS).
17 |
18 | The basic usage pattern for writing automated tests with Terratest is to:
19 |
20 | 1. Write tests using Go's built-in [package testing]: you create a file ending
21 | in `_test.go` and run tests with the `go test` command.
22 | 2. Use Terratest to execute your _real_ IaC tools (e.g., Terraform, Packer, etc.)
23 | to deploy _real_ infrastructure (e.g., servers) in a _real_ environment (e.g., AWS).
24 | 3. Validate that the infrastructure works correctly in that environment by
25 | making HTTP requests, API calls, SSH connections, etc.
26 | 4. Undeploy everything at the end of the test.
27 |
28 | **Note #1**: Many of these tests create real resources in an AWS account.
29 | That means they cost money to run, especially if you don't clean up after
30 | yourself. Please be considerate of the resources you create and take extra care
31 | to clean everything up when you're done!
32 |
33 | **Note #2**: Never hit `CTRL + C` or cancel a build once tests are running or
34 | the cleanup tasks won't run!
35 |
36 | **Note #3**: We set `-timeout 45m` on all tests not because they necessarily
37 | take 45 minutes, but because Go has a default test timeout of 10 minutes, after
38 | which it does a `SIGQUIT`, preventing the tests from properly cleaning up after
39 | themselves. Therefore, we set a timeout of 45 minutes to make sure all tests
40 | have enough time to finish and cleanup.
41 |
42 | ## How to run the tests
43 |
44 | This repository comes with a [Makefile], that helps you to run the
45 | tests in a convenient way.
46 | Alternatively, you can also run the tests without Docker.
47 |
48 | ### Run the tests with Docker
49 |
50 | 1. Install [Docker]
51 | 2. Set your AWS credentials as environment variables: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`
52 | 3. Run `make docker-run-tests`
53 |
54 | ### Run the tests without Docker
55 |
56 | 1. Install the latest version of [Go].
57 | 2. Install [Terraform].
58 | 3. Set your AWS credentials as environment variables: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`
59 | 4. Install go dependencies: `go mod download`
60 | 5. Run all tests: `go test -v -count 1 -timeout 45m -parallel 128 ./test/...`
61 | or use the convenient `make test/unit-tests` Makefile target.
62 | 6. Run a specific test: `go test -count 1 -v -timeout 45m -parallel 128 test/example_test.go`
63 |
64 |
65 |
66 | [makefile]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/main/Makefile
67 | [testdirectory]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/tree/main/test
68 | [homepage]: https://mineiros.io/?ref=terraform-aws-cognito-user-pool
69 | [terratest]: https://github.com/gruntwork-io/terratest
70 | [package testing]: https://golang.org/pkg/testing/
71 | [docker]: https://docs.docker.com/get-started/
72 | [go]: https://golang.org/
73 | [terraform]: https://www.terraform.io/downloads.html
74 | [badge-license]: https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg
75 | [badge-terraform]: https://img.shields.io/badge/terraform-1.x%20|%200.15%20|%200.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform
76 | [badge-slack]: https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack
77 | [releases-terraform]: https://github.com/hashicorp/terraform/releases
78 | [apache20]: https://opensource.org/licenses/Apache-2.0
79 | [slack]: https://mineiros.io/slack
80 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribution Guidelines
2 |
3 | First and foremost, we’d like to express our gratitude to you for taking the time to contribute.
4 | We welcome and appreciate any and all contributions via
5 | [Pull Requests] along the [GitHub Flow].
6 |
7 | 1. [Open a GitHub issue](#open-a-github-issue)
8 | 2. [Fork the repository on GitHub](#fork-the-repository-on-github)
9 | 3. [Install the pre-commit hooks](#install-the-pre-commit-hooks)
10 | 4. [Update the documentation](#update-the-documentation)
11 | 5. [Update the tests](#update-the-tests)
12 | 6. [Update the code](#update-the-code)
13 | 7. [Create a pull request](#create-a-pull-request)
14 | 8. [Merge and release](#merge-and-release)
15 |
16 | ## Open a GitHub issue
17 |
18 | For bug reports or requests, please submit your issue in the appropriate repository.
19 |
20 | We advise that you open an issue and ask the
21 | [CODEOWNERS] and community prior to starting a contribution.
22 | This is your chance to ask questions and receive feedback before
23 | writing (potentially wrong) code. We value the direct contact with our community
24 | a lot, so don't hesitate to ask any questions.
25 |
26 | ## Fork the repository on GitHub
27 |
28 | [Fork] the repository into your own GitHub account and [create a new branch] as
29 | described in the [GitHub Flow].
30 |
31 | ## Install the pre-commit hooks
32 |
33 | If the repository you're working on ships with a
34 | [`.pre-commit-config.yaml`][pre-commit-file],
35 | make sure the necessary hooks have been installed before you begin working
36 | (e.g. a `pre-commit install`).
37 |
38 | ## Update the documentation
39 |
40 | We encourage you to update the documentation before writing any code (please see
41 | [Readme Driven Development]. This ensures the
42 | documentation stays up to date and allows you to think through the problem fully before you begin implementing any
43 | changes.
44 |
45 | ## Update the tests
46 |
47 | We also recommend updating the automated tests before updating any code
48 | (see [Test Driven Development].
49 |
50 | That means that you should add or update a test case, run all tests and verify
51 | that the new test fails with a clear error message and then start implementing
52 | the code changes to get that test to pass.
53 |
54 | The test folder in every repository will have documentation on how to run the
55 | tests locally.
56 |
57 | ## Update the code
58 |
59 | At this point, make your code changes and constantly test again your new test case to make sure that everything working
60 | properly. Do [commit] early and often and make useful commit messages.
61 |
62 | If a backwards incompatible change cannot be avoided, please make sure to call that out when you submit a pull request,
63 | explaining why the change is absolutely necessary.
64 |
65 | ## Create a pull request
66 |
67 | [Create a pull request] with your changes.
68 | Please make sure to include the following:
69 |
70 | 1. A description of the change, including a link to your GitHub issue.
71 | 1. Any notes on backwards incompatibility or downtime.
72 |
73 | ## Merge and release
74 |
75 | The [CODEOWNERS] of the repository will review your code and provide feedback.
76 | If everything looks good, they will merge the code and release a new version while following the principles of [Semantic Versioning (SemVer)].
77 |
78 |
79 |
80 | [Pull Requests]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/pulls
81 | [pre-commit-file]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/.pre-commit-config.yaml
82 | [Github Flow]: https://guides.github.com/introduction/flow/
83 | [CODEOWNERS]: https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
84 | [Fork]: https://help.github.com/en/github/getting-started-with-github/fork-a-repo
85 | [create a new branch]: https://guides.github.com/introduction/flow/
86 | [Readme Driven Development]: https://tom.preston-werner.com/2010/08/23/readme-driven-development.html
87 | [commit]: https://help.github.com/en/desktop/contributing-to-projects/committing-and-reviewing-changes-to-your-project
88 | [create a pull request]: https://help.github.com/articles/creating-a-pull-request/
89 | [Semantic Versioning (SemVer)]: https://semver.org/
90 | [Test Driven Development]: https://en.wikipedia.org/wiki/Test-driven_development
91 |
--------------------------------------------------------------------------------
/examples/complete/main.tf:
--------------------------------------------------------------------------------
1 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 | # DEPLOY A COGNITO USER POOL
3 | # This example deploys a Cognito User Pool with customized settings.
4 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 |
6 | # ------------------------------------------------------------------------------
7 | # PROVIDER CONFIGURATION
8 | # ------------------------------------------------------------------------------
9 |
10 | provider "aws" {
11 | region = "us-east-1"
12 | }
13 |
14 | # ------------------------------------------------------------------------------
15 | # THE COGNITO USER POOL WITH CUSTOM SETTINGS
16 | # ------------------------------------------------------------------------------
17 |
18 | module "cognito_user_pool" {
19 | source = "mineiros-io/cognito-user-pool/aws"
20 | version = "~> 0.9.0"
21 |
22 | name = "complete-example-userpool"
23 |
24 | # We allow the public to create user profiles
25 | allow_admin_create_user_only = false
26 |
27 | enable_username_case_sensitivity = false
28 | advanced_security_mode = "ENFORCED"
29 |
30 | alias_attributes = [
31 | "email",
32 | "phone_number",
33 | "preferred_username",
34 | ]
35 |
36 | auto_verified_attributes = [
37 | "email"
38 | ]
39 |
40 | account_recovery_mechanisms = [
41 | {
42 | name = "verified_email"
43 | priority = 1
44 | },
45 | {
46 | name = "verified_phone_number"
47 | priority = 2
48 | }
49 | ]
50 |
51 | # If invited by an admin
52 | invite_email_subject = "You've been invited to Mineiros.io"
53 | invite_email_message = "Hi {username}, your temporary password is '{####}'."
54 | invite_sms_message = "Hi {username}, your temporary password is '{####}'."
55 |
56 | domain = "mineiros-dev"
57 | default_email_option = "CONFIRM_WITH_LINK"
58 | email_subject_by_link = "Your Verification Link"
59 | email_message_by_link = "Please click the link below to verify your email address. {##Verify Email##}."
60 | sms_message = "Your verification code is {####}."
61 |
62 | challenge_required_on_new_device = true
63 | user_device_tracking = "USER_OPT_IN"
64 |
65 | # These paramters can be used to configure SES for emails
66 | # email_sending_account = "DEVELOPER"
67 | # email_reply_to_address = "support@mineiros.io"
68 | # email_from_address = "noreply@mineiros.io"
69 | # email_source_arn = "arn:aws:ses:us-east-1:999999999999:identity"
70 |
71 | # Require MFA
72 | mfa_configuration = "ON"
73 | allow_software_mfa_token = true
74 |
75 | password_minimum_length = 40
76 | password_require_lowercase = true
77 | password_require_numbers = true
78 | password_require_uppercase = true
79 | password_require_symbols = true
80 |
81 | temporary_password_validity_days = 3
82 |
83 | schema_attributes = [
84 | {
85 | name = "gender", # overwrites the default attribute 'gender'
86 | type = "String"
87 | required = true
88 | min_length = 1
89 | max_length = 2048
90 | },
91 | {
92 | name = "alternative_name"
93 | type = "String"
94 | developer_only_attribute = false,
95 | mutable = true,
96 | required = false,
97 | min_length = 0,
98 | max_length = 2048
99 | },
100 | {
101 | name = "friends_count"
102 | type = "Number"
103 | min_value = 0,
104 | max_value = 100
105 | },
106 | {
107 | name = "is_active"
108 | type = "Boolean"
109 |
110 | },
111 | {
112 | name = "last_seen"
113 | type = "DateTime"
114 | }
115 | ]
116 |
117 | clients = [
118 | {
119 | name = "android-mobile-client"
120 | read_attributes = ["email", "email_verified", "preferred_username"]
121 | allowed_oauth_scopes = ["email", "openid"]
122 | allowed_oauth_flows = ["implicit"]
123 | callback_urls = ["https://mineiros.io/callback", "https://mineiros.io/anothercallback"]
124 | default_redirect_uri = "https://mineiros.io/callback"
125 | generate_secret = true
126 | }
127 | ]
128 |
129 | tags = {
130 | environment = "Dev"
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/examples/complete/README.md:
--------------------------------------------------------------------------------
1 | [
][homepage]
2 |
3 | [![license][badge-license]][apache20]
4 | [![Terraform Version][badge-terraform]][releases-terraform]
5 | [![Join Slack][badge-slack]][slack]
6 |
7 | # What this example shows
8 |
9 | The code in [main.tf]
10 | shows how to deploy a Cognito User Pool with custom settings.
11 |
12 | ```hcl
13 | module "cognito_user_pool" {
14 | source = "mineiros-io/cognito-user-pool/aws"
15 | version = "~> 0.9.0"
16 |
17 | name = "complete-example-userpool"
18 |
19 | # We allow the public to create user profiles
20 | allow_admin_create_user_only = false
21 |
22 | enable_username_case_sensitivity = false
23 | advanced_security_mode = "ENFORCED"
24 |
25 | alias_attributes = [
26 | "email",
27 | "phone_number",
28 | "preferred_username",
29 | ]
30 |
31 | auto_verified_attributes = [
32 | "email"
33 | ]
34 |
35 | # If invited by an admin
36 | invite_email_subject = "You've been invited to Mineiros.io"
37 | invite_email_message = "Hi {username}, your temporary password is '{####}'."
38 | invite_sms_message = "Hi {username}, your temporary password is '{####}'."
39 |
40 | default_email_option = "CONFIRM_WITH_LINK"
41 | email_subject_by_link = "Your Verification Link"
42 | email_message_by_link = "Please click the link below to verify your email address. {##Verify Email##}."
43 | sms_message = "Your verification code is {####}."
44 |
45 | challenge_required_on_new_device = true
46 | user_device_tracking = "USER_OPT_IN"
47 |
48 | # These paramters can be used to configure SES for emails
49 | # ...
50 |
51 | # Require MFA
52 | mfa_configuration = "ON"
53 | allow_software_mfa_token = true
54 |
55 | password_minimum_length = 40
56 | password_require_lowercase = true
57 | password_require_numbers = true
58 | password_require_uppercase = true
59 | password_require_symbols = true
60 |
61 | temporary_password_validity_days = 3
62 |
63 | schema_attributes = [
64 | {
65 | name = "gender", # overwrites the default attribute 'gender'
66 | type = "String"
67 | required = true
68 | min_length = 1
69 | max_length = 2048
70 | },
71 | {
72 | name = "alternative_name"
73 | type = "String"
74 | developer_only_attribute = false,
75 | mutable = true,
76 | required = false,
77 | min_length = 0,
78 | max_length = 2048
79 | },
80 | {
81 | name = "friends_count"
82 | type = "Number"
83 | min_value = 0,
84 | max_value = 100
85 | },
86 | {
87 | name = "is_active"
88 | type = "Boolean"
89 |
90 | },
91 | {
92 | name = "last_seen"
93 | type = "DateTime"
94 | }
95 | ]
96 |
97 | clients = [
98 | {
99 | name = "android-mobile-client"
100 | read_attributes = ["email", "email_verified", "preferred_username"]
101 | allowed_oauth_scopes = ["email", "openid"]
102 | allowed_oauth_flows = ["implicit"]
103 | callback_urls = ["https://mineiros.io/callback", "https://mineiros.io/anothercallback"]
104 | default_redirect_uri = "https://mineiros.io/callback"
105 | generate_secret = true
106 | }
107 | ]
108 |
109 | tags = {
110 | environment = "Dev"
111 | }
112 | }
113 | ```
114 |
115 | ## Running the example
116 |
117 | ### Cloning the repository
118 |
119 | ```bash
120 | git clone https://github.com/mineiros-io/terraform-aws-cognito-user-pool.git
121 | cd terraform-aws-cognito-user-pool/examples/complete
122 | ```
123 |
124 | ### Initializing Terraform
125 |
126 | Run `terraform init` to initialize the example and download providers and the module.
127 |
128 | ### Planning the example
129 |
130 | Run `terraform plan` to see a plan of the changes.
131 |
132 | ### Applying the example
133 |
134 | Run `terraform apply` to create the resources.
135 | You will see a plan of the changes and Terraform will prompt you for approval to actually apply the changes.
136 |
137 | ### Destroying the example
138 |
139 | Run `terraform destroy` to destroy all resources again.
140 |
141 |
142 |
143 | [main.tf]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/tree/master/examples/complete/main.tf
144 |
145 | [homepage]: https://mineiros.io/?ref=terraform-aws-cognito-user-pool
146 |
147 | [badge-license]: https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg
148 | [badge-terraform]: https://img.shields.io/badge/terraform-1.x%20|%200.15%20|%200.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform
149 | [badge-slack]: https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack
150 |
151 | [releases-terraform]: https://github.com/hashicorp/terraform/releases
152 | [apache20]: https://opensource.org/licenses/Apache-2.0
153 | [slack]: https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg
154 |
--------------------------------------------------------------------------------
/test/unit-complete/main.tf:
--------------------------------------------------------------------------------
1 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 | # COMPLETE FEATURES UNIT TEST
3 | # This module tests a complete set of most/all non-exclusive features
4 | # The purpose is to activate everything the module offers, but trying to keep execution time and costs minimal.
5 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 |
7 | variable "aws_region" {
8 | description = "(Optional) The AWS region in which all resources will be created."
9 | type = string
10 | default = "us-east-1"
11 | }
12 |
13 | terraform {
14 | required_providers {
15 | aws = {
16 | source = "hashicorp/aws"
17 | version = "~> 4.0"
18 | }
19 | }
20 | }
21 |
22 | provider "aws" {
23 | region = var.aws_region
24 | }
25 |
26 | # DO NOT RENAME MODULE NAME
27 | module "test" {
28 | source = "../.."
29 |
30 | module_enabled = true
31 |
32 | # add all required arguments
33 | name = "example-cognito-user-pool"
34 |
35 | # add all optional arguments that create additional resources
36 | clients = [
37 | {
38 | name = "android-mobile-client"
39 | read_attributes = ["email", "email_verified", "preferred_username"]
40 | allowed_oauth_scopes = ["email", "openid"]
41 | allowed_oauth_flows = ["implicit"]
42 | callback_urls = ["https://mineiros.io/callback", "https://mineiros.io/anothercallback"]
43 | default_redirect_uri = "https://mineiros.io/callback"
44 | generate_secret = true
45 | }
46 | ]
47 |
48 | resource_servers = [
49 | {
50 | identifier = "https://api.resourceserver.com"
51 | name = "API"
52 | scopes = [
53 | {
54 | scope_name = "users:read",
55 | scope_description = "Read user data"
56 | },
57 | {
58 | scope_name = "users:write"
59 | scope_description = "Write user data"
60 | }
61 | ]
62 | }
63 | ]
64 |
65 | # add most/all other optional arguments
66 |
67 | enable_username_case_sensitivity = false
68 | advanced_security_mode = "ENFORCED"
69 |
70 | alias_attributes = [
71 | "email",
72 | "phone_number",
73 | "preferred_username",
74 | ]
75 |
76 | auto_verified_attributes = [
77 | "email"
78 | ]
79 |
80 | account_recovery_mechanisms = [
81 | {
82 | name = "verified_email"
83 | priority = 1
84 | },
85 | {
86 | name = "verified_phone_number"
87 | priority = 2
88 | }
89 | ]
90 |
91 | # If invited by an admin
92 | invite_email_subject = "You've been invited to Mineiros.io"
93 | invite_email_message = "Hi {username}, your temporary password is '{####}'."
94 | invite_sms_message = "Hi {username}, your temporary password is '{####}'."
95 |
96 | # domain = "mineiros-dev"
97 | default_email_option = "CONFIRM_WITH_LINK"
98 | email_subject_by_link = "Your Verification Link"
99 | email_message_by_link = "Please click the link below to verify your email address. {##Verify Email##}."
100 | sms_message = "Your verification code is {####}."
101 |
102 | challenge_required_on_new_device = true
103 | user_device_tracking = "USER_OPT_IN"
104 |
105 | # These paramters can be used to configure SES for emails
106 | # email_sending_account = "DEVELOPER"
107 | # email_reply_to_address = "support@mineiros.io"
108 | # email_from_address = "noreply@mineiros.io"
109 | # email_source_arn = "arn:aws:ses:us-east-1:999999999999:identity"
110 |
111 | # Require MFA
112 | mfa_configuration = "ON"
113 | allow_software_mfa_token = true
114 |
115 | password_minimum_length = 40
116 | password_require_lowercase = true
117 | password_require_numbers = true
118 | password_require_uppercase = true
119 | password_require_symbols = true
120 |
121 | temporary_password_validity_days = 3
122 |
123 | schema_attributes = [
124 | {
125 | name = "gender", # overwrites the default attribute 'gender'
126 | type = "String"
127 | required = true
128 | min_length = 1
129 | max_length = 2048
130 | },
131 | {
132 | name = "alternative_name"
133 | type = "String"
134 | developer_only_attribute = false,
135 | mutable = true,
136 | required = false,
137 | min_length = 0,
138 | max_length = 2048
139 | },
140 | {
141 | name = "friends_count"
142 | type = "Number"
143 | min_value = 0,
144 | max_value = 100
145 | },
146 | {
147 | name = "is_active"
148 | type = "Boolean"
149 |
150 | },
151 | {
152 | name = "last_seen"
153 | type = "DateTime"
154 | }
155 | ]
156 |
157 | default_client_token_validity_units = {
158 | refresh_token = "hours"
159 | access_token = "hours"
160 | id_token = "hours"
161 | }
162 |
163 | tags = {
164 | Team = "Unknown"
165 | }
166 |
167 | module_tags = {
168 | Environment = "unknown"
169 | }
170 |
171 | module_depends_on = ["nothing"]
172 | }
173 |
174 | # outputs generate non-idempotent terraform plans so we disable them for now unless we need them.
175 | # output "all" {
176 | # description = "All outputs of the module."
177 | # value = module.test
178 | # }
179 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Set default shell to bash
2 | SHELL := /bin/bash -o pipefail
3 |
4 | BUILD_TOOLS_VERSION ?= v0.14.3
5 | BUILD_TOOLS_DOCKER_REPO ?= mineiros/build-tools
6 | BUILD_TOOLS_DOCKER_IMAGE ?= ${BUILD_TOOLS_DOCKER_REPO}:${BUILD_TOOLS_VERSION}
7 |
8 | # Some CI providers such as GitHub Actions, CircleCI, and TravisCI are setting
9 | # the CI environment variable to a non-empty value by default to indicate that
10 | # the current workflow is running in a Continuous Integration environment.
11 | #
12 | # If TF_IN_AUTOMATION is set to any non-empty value, Terraform adjusts its
13 | # output to avoid suggesting specific commands to run next.
14 | # https://www.terraform.io/docs/commands/environment-variables.html#tf_in_automation
15 | #
16 | # We are using GNU style quiet commands to disable set V to non-empty e.g. V=1
17 | # https://www.gnu.org/software/automake/manual/html_node/Debugging-Make-Rules.html
18 | #
19 | ifdef CI
20 | TF_IN_AUTOMATION ?= yes
21 | export TF_IN_AUTOMATION
22 |
23 | V ?= 1
24 | endif
25 |
26 | ifndef NOCOLOR
27 | GREEN := $(shell tput -Txterm setaf 2)
28 | YELLOW := $(shell tput -Txterm setaf 3)
29 | WHITE := $(shell tput -Txterm setaf 7)
30 | RESET := $(shell tput -Txterm sgr0)
31 | endif
32 |
33 | GIT_TOPLEVEl = $(shell git rev-parse --show-toplevel)
34 |
35 | # Generic docker run flags
36 | DOCKER_RUN_FLAGS += -v ${GIT_TOPLEVEl}:/build
37 | DOCKER_RUN_FLAGS += --rm
38 | DOCKER_RUN_FLAGS += -e TF_IN_AUTOMATION
39 | # If TF_VERSION is defined, TFSwitch will switch to the desired version on
40 | # container startup. If TF_VERSION is omitted, the default version installed
41 | # inside the docker image will be used.
42 | DOCKER_RUN_FLAGS += -e TF_VERSION
43 |
44 | # If SSH_AUTH_SOCK is set, we forward the SSH agent of the host system into
45 | # the docker container. This is useful when working with private repositories
46 | # and dependencies that might need to be cloned inside the container (e.g.
47 | # private Terraform modules).
48 | ifdef SSH_AUTH_SOCK
49 | DOCKER_SSH_FLAGS += -e SSH_AUTH_SOCK=/ssh-agent
50 | DOCKER_SSH_FLAGS += -v ${SSH_AUTH_SOCK}:/ssh-agent
51 | endif
52 |
53 | # If AWS_ACCESS_KEY_ID is defined, we are likely running inside an AWS provider
54 | # module. To enable AWS authentication inside the docker container, we inject
55 | # the relevant environment variables.
56 | ifdef AWS_ACCESS_KEY_ID
57 | DOCKER_AWS_FLAGS += -e AWS_ACCESS_KEY_ID
58 | DOCKER_AWS_FLAGS += -e AWS_SECRET_ACCESS_KEY
59 | DOCKER_AWS_FLAGS += -e AWS_SESSION_TOKEN
60 | endif
61 |
62 | # If GOOGLE_CREDENTIALS is defined, we are likely running inside a GCP provider
63 | # module. To enable GCP authentication inside the docker container, we inject
64 | # the relevant environment variables (service-account key file).
65 | ifdef GOOGLE_CREDENTIALS
66 | DOCKER_GCP_FLAGS += -e GOOGLE_CREDENTIALS
67 | endif
68 |
69 | # If GITHUB_OWNER is defined, we are likely running inside a GitHub provider
70 | # module. To enable GitHub authentication inside the docker container,
71 | # we inject the relevant environment variables.
72 | ifdef GITHUB_OWNER
73 | DOCKER_GITHUB_FLAGS += -e GITHUB_TOKEN
74 | DOCKER_GITHUB_FLAGS += -e GITHUB_OWNER
75 | endif
76 |
77 | .PHONY: default
78 | default: help
79 |
80 | # Not exposed as a callable target by `make help`, since this is a one-time shot to simplify the development of this module.
81 | .PHONY: template/adjust
82 | template/adjust: FILTER = -path ./.git -prune -a -type f -o -type f -not -name Makefile
83 | template/adjust:
84 | @find . $(FILTER) -exec sed -i -e "s,terraform-module-template,$${PWD##*/},g" {} \;
85 |
86 | ## Run pre-commit hooks inside a build-tools docker container.
87 | .PHONY: test/pre-commit
88 | test/pre-commit: DOCKER_FLAGS += ${DOCKER_SSH_FLAGS}
89 | test/pre-commit:
90 | $(call docker-run,pre-commit run -a)
91 |
92 | ## Run all Go tests inside a build-tools docker container. This is complementary to running 'go test ./test/...'.
93 | .PHONY: test/unit-tests
94 | test/unit-tests: DOCKER_FLAGS += ${DOCKER_SSH_FLAGS}
95 | test/unit-tests: DOCKER_FLAGS += ${DOCKER_GITHUB_FLAGS}
96 | test/unit-tests: DOCKER_FLAGS += ${DOCKER_AWS_FLAGS}
97 | test/unit-tests: DOCKER_FLAGS += ${DOCKER_GCP_FLAGS}
98 | test/unit-tests: DOCKER_FLAGS += $(shell env | grep ^TF_VAR_ | cut -d = -f 1 | xargs -i printf ' -e {}')
99 | test/unit-tests: DOCKER_FLAGS += -e TF_DATA_DIR=.terratest
100 | test/unit-tests: TEST ?= "TestUnit"
101 | test/unit-tests:
102 | @echo "${YELLOW}[TEST] ${GREEN}Start Running Go Tests in Docker Container.${RESET}"
103 | $(call go-test,./test -run $(TEST))
104 |
105 | ## Generate README.md with Terradoc
106 | .PHONY: terradoc
107 | terradoc:
108 | $(call quiet-command,terradoc -o README.md README.tfdoc.hcl)
109 |
110 | ## Clean up cache and temporary files
111 | .PHONY: clean
112 | clean:
113 | $(call rm-command,.terraform)
114 | $(call rm-command,.terraform.lock.hcl)
115 | $(call rm-command,*.tfplan)
116 | $(call rm-command,*/*/.terraform)
117 | $(call rm-command,*/*/*.tfplan)
118 | $(call rm-command,*/*/.terraform.lock.hcl)
119 |
120 | ## Display help for all targets
121 | .PHONY: help
122 | help:
123 | @awk '/^.PHONY: / { \
124 | msg = match(lastLine, /^## /); \
125 | if (msg) { \
126 | cmd = substr($$0, 9, 100); \
127 | msg = substr(lastLine, 4, 1000); \
128 | printf " ${GREEN}%-30s${RESET} %s\n", cmd, msg; \
129 | } \
130 | } \
131 | { lastLine = $$0 }' $(MAKEFILE_LIST)
132 |
133 | # Define helper functions
134 | DOCKER_FLAGS += ${DOCKER_RUN_FLAGS}
135 | DOCKER_RUN_CMD = docker run ${DOCKER_FLAGS} ${BUILD_TOOLS_DOCKER_IMAGE}
136 |
137 | quiet-command = $(if ${V},${1},$(if ${2},@echo ${2} && ${1}, @${1}))
138 | docker-run = $(call quiet-command,${DOCKER_RUN_CMD} ${1} | cat,"${YELLOW}[DOCKER RUN] ${GREEN}${1}${RESET}")
139 | go-test = $(call quiet-command,${DOCKER_RUN_CMD} go test -v -count 1 -timeout 45m -parallel 128 ${1} | cat,"${YELLOW}[TEST] ${GREEN}${1}${RESET}")
140 | rm-command = $(call quiet-command,rm -rf ${1},"${YELLOW}[CLEAN] ${GREEN}${1}${RESET}")
141 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [Unreleased]
9 |
10 | ## [0.9.2]
11 |
12 | ### Added
13 |
14 | - Added support for AWS provider `v4.x`
15 |
16 | ## [0.9.1]
17 |
18 | ### Added
19 |
20 | - Add support for `module_tags`
21 | - Implement support for resource servers through the
22 | `aws_cognito_resource_server` resource
23 |
24 | ## [0.9.0]
25 |
26 | ### BREAKING
27 |
28 | - Minimum version of the aws provider has been bumped to `3.50.0` to ensure
29 | support for the `enable_token_revocation` in the `aws_cognito_user_pool_client`
30 | resource.
31 |
32 | ### Fixed
33 |
34 | - Fixed implementation of `token_validity_units` block.
35 |
36 | ## [0.8.0]
37 |
38 | ### BREAKING
39 |
40 | - Minimum version of the aws provider has been bumped to `3.32.0` to enable
41 | support for `token_validity_units`
42 |
43 | ### Added
44 |
45 | - Add support `token_validity_units`
46 |
47 | ## [0.7.0]
48 |
49 | ### Added
50 |
51 | - Add support for Terraform `v1.x`
52 |
53 | ## [0.6.0]
54 |
55 | ### Added
56 |
57 | - Add support for Terraform `v0.15`
58 |
59 | ## [0.5.0]
60 |
61 | ### Added
62 |
63 | - Add support for `account_recovery_mechanisms`
64 |
65 | ### Removed
66 |
67 | - BREAKING CHANGE: Drop support for Terraform AWS Provider version `v2`
68 |
69 | ## [0.4.1] - 2021-02-08
70 |
71 | ### Fixed
72 |
73 | - Fixed examples to use new variable `user_device_tracking` instead of `device_only_remembered_on_user_prompt`
74 |
75 | ## [0.4.0] - 2020-12-09
76 |
77 | ### Changed
78 |
79 | - Add support for Terraform v0.14
80 |
81 | ## [0.3.0] - 2020-11-25
82 |
83 | ### Changes
84 |
85 | - Add argument `user_device_tracking` to set device tracking to `OFF`, `ALWAYS` or `USER_OPT_IN`
86 | - BREAKING CHANGE: Remove argument `device_only_remembered_on_user_prompt`. Replaced by `user_device_tracking`.
87 | Default behavior did not change. How to migrate:
88 | - `device_only_remembered_on_user_prompt=true`: Set `user_device_tracking='USER_OPT_IN'`
89 | - `device_only_remembered_on_user_prompt=false`: Set `user_device_tracking='ALWAYS'`
90 | - `device_only_remembered_on_user_prompt=null`: Set `user_device_tracking='OFF'`
91 |
92 | ### Fixes
93 |
94 | - Allow to cleanly turn off user device tracking by setting new variable `user_device_tracking` to `OFF`. [#23](https://github.com/mineiros-io/terraform-aws-cognito-user-pool/issues/23)
95 | - The type of the clients output is a map of objects instead of a list.
96 |
97 | ## [0.2.0] - 2020-08-13
98 |
99 | ### Changed
100 |
101 | - Add support for Terraform `v0.13`
102 | - Prepared support for Terraform `v0.14`
103 |
104 | ## [0.1.4] - 2020-08-13
105 |
106 | ### Added
107 |
108 | - Add support for `username_attributes` argument.
109 |
110 | ## [0.1.3] - 2020-08-10
111 |
112 | ### Added
113 |
114 | - Add unit test coverage for the `aws_cognito_user_pool_domain` resource.
115 |
116 | ### Changed
117 |
118 | - Enable `markdown-link-check` pre-commit hook.
119 |
120 | ### Fixed
121 |
122 | - Fixes recreation of resources on multiple apply runs.
123 | - Fix non-idempotent number schema attributes.
124 |
125 | ## [0.1.2] - 2020-08-05
126 |
127 | ### Added
128 |
129 | - Add support for `aws_cognito_user_pool_domain`.
130 |
131 | ## [0.1.1] - 2020-08-04
132 |
133 | ### Fixed
134 |
135 | - Fix email subject for admin invites.
136 | - Fix example documentation to point to terraform registry.
137 | - Fix `string_attribute_constraints` default values for string attributes to prevent non-idempotent plan.
138 |
139 | ### Added
140 |
141 | - Add test to validate idempotency after apply.
142 |
143 | ## [0.1.0] - 2020-08-03
144 |
145 | ### Changed
146 |
147 | - Add support for terraform aws provider `v3`
148 | - Update test to test against `v3` aws provider
149 | - Update test dependencies to use `v3` capable module versions
150 |
151 | ## [0.0.1] - 2020-06-27
152 |
153 | ### Added
154 |
155 | - Implement support for `aws_cognito_user_pool` resource.
156 | - Implement support for `aws_cognito_user_pool_client` resource.
157 | - Document the usage of the module in README.md.
158 | - Document the usage of examples.
159 | - Add unit tests for basic use cases.
160 |
161 | [unreleased]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.9.2...HEAD
162 | [0.9.2]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.9.1...v0.9.2
163 | [0.9.1]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.9.0...v0.9.1
164 | [0.9.0]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.8.0...v0.9.0
165 | [0.8.0]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.7.0...v0.8.0
166 | [0.7.0]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.6.0...v0.7.0
167 | [0.6.0]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.5.0...v0.6.0
168 | [0.5.0]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.4.1...v0.5.0
169 | [0.4.1]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.4.0...v0.4.1
170 | [0.4.0]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.3.0...v0.4.0
171 | [0.3.0]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.2.0...v0.3.0
172 | [0.2.0]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.1.4...v0.2.0
173 | [0.1.4]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.1.3...v0.1.4
174 | [0.1.3]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.1.2...v0.1.3
175 | [0.1.2]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.1.1...v0.1.2
176 | [0.1.1]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.1.0...v0.1.1
177 | [0.1.0]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/compare/v0.0.1...v0.1.0
178 | [0.0.1]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/releases/tag/v0.0.1
179 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [2020] [Mineiros]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/main.tf:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------------
2 | # DEPLOY A COGNITO USER POOL
3 | # This module deploys a Amazon Web Servics (AWS) Cognito User Pool Service.
4 | # Cognito user pools are used for authentication and act as identity provider.
5 | # With a user pool, your app users can sign in through the user pool or
6 | # federate through a third-party identity provider (idP). For more information
7 | # please see:
8 | # https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html
9 | # ------------------------------------------------------------------------------
10 |
11 | locals {
12 | alias_attributes = var.alias_attributes == null && var.username_attributes == null ? [
13 | "email",
14 | "preferred_username",
15 | ] : null
16 | }
17 |
18 | resource "aws_cognito_user_pool" "user_pool" {
19 | count = var.module_enabled ? 1 : 0
20 |
21 | name = var.name
22 | alias_attributes = var.alias_attributes != null ? var.alias_attributes : local.alias_attributes
23 | username_attributes = var.username_attributes
24 | auto_verified_attributes = var.auto_verified_attributes
25 |
26 | sms_authentication_message = var.sms_authentication_message
27 |
28 | mfa_configuration = var.mfa_configuration
29 |
30 | password_policy {
31 | minimum_length = var.password_minimum_length
32 | require_lowercase = var.password_require_lowercase
33 | require_numbers = var.password_require_numbers
34 | require_symbols = var.password_require_symbols
35 | require_uppercase = var.password_require_uppercase
36 | temporary_password_validity_days = var.temporary_password_validity_days
37 | }
38 |
39 | dynamic "account_recovery_setting" {
40 | for_each = length(var.account_recovery_mechanisms) > 0 ? [true] : []
41 |
42 | content {
43 | dynamic "recovery_mechanism" {
44 | for_each = var.account_recovery_mechanisms
45 | iterator = recovery
46 |
47 | content {
48 | name = recovery.value.name
49 | priority = recovery.value.priority
50 | }
51 | }
52 | }
53 | }
54 |
55 | dynamic "device_configuration" {
56 | for_each = contains(["ALWAYS", "USER_OPT_IN"], upper(var.user_device_tracking)) ? [true] : []
57 |
58 | content {
59 | device_only_remembered_on_user_prompt = var.user_device_tracking == "USER_OPT_IN"
60 | challenge_required_on_new_device = var.challenge_required_on_new_device
61 | }
62 | }
63 |
64 | dynamic "software_token_mfa_configuration" {
65 | for_each = var.allow_software_mfa_token ? [true] : []
66 |
67 | content {
68 | enabled = true
69 | }
70 | }
71 |
72 | username_configuration {
73 | case_sensitive = var.enable_username_case_sensitivity
74 | }
75 |
76 | email_configuration {
77 | email_sending_account = var.email_sending_account
78 | reply_to_email_address = var.email_reply_to_address
79 | source_arn = var.email_source_arn
80 | from_email_address = var.email_from_address
81 | }
82 |
83 | # The configuration for AdminCreateUser
84 | # https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminCreateUser.html.
85 | admin_create_user_config {
86 | allow_admin_create_user_only = var.allow_admin_create_user_only
87 |
88 | invite_message_template {
89 | email_subject = var.invite_email_subject
90 | email_message = var.invite_email_message
91 | sms_message = var.invite_sms_message
92 | }
93 | }
94 |
95 | dynamic "schema" {
96 | for_each = var.schema_attributes
97 | iterator = attribute
98 |
99 | content {
100 | name = attribute.value.name
101 | required = try(attribute.value.required, false)
102 | attribute_data_type = attribute.value.type
103 | developer_only_attribute = try(attribute.value.developer_only_attribute, false)
104 | mutable = try(attribute.value.mutable, true)
105 |
106 | dynamic "number_attribute_constraints" {
107 | for_each = attribute.value.type == "Number" ? [true] : []
108 |
109 | content {
110 | min_value = lookup(attribute.value, "min_value", null)
111 | max_value = lookup(attribute.value, "max_value", null)
112 | }
113 | }
114 |
115 | dynamic "string_attribute_constraints" {
116 | for_each = attribute.value.type == "String" ? [true] : []
117 |
118 | content {
119 | min_length = lookup(attribute.value, "min_length", 0)
120 | max_length = lookup(attribute.value, "max_length", 2048)
121 | }
122 | }
123 |
124 | }
125 | }
126 |
127 | dynamic "lambda_config" {
128 | for_each = try(coalesce(
129 | var.lambda_create_auth_challenge,
130 | var.lambda_custom_message,
131 | var.lambda_define_auth_challenge,
132 | var.lambda_post_authentication,
133 | var.lambda_post_confirmation,
134 | var.lambda_pre_authentication,
135 | var.lambda_pre_sign_up,
136 | var.lambda_pre_token_generation,
137 | var.lambda_user_migration,
138 | var.lambda_verify_auth_challenge_response
139 | ), null) == null ? [] : [true]
140 |
141 | content {
142 | create_auth_challenge = var.lambda_create_auth_challenge
143 | custom_message = var.lambda_custom_message
144 | define_auth_challenge = var.lambda_define_auth_challenge
145 | post_authentication = var.lambda_post_authentication
146 | post_confirmation = var.lambda_post_confirmation
147 | pre_authentication = var.lambda_pre_authentication
148 | pre_sign_up = var.lambda_pre_sign_up
149 | pre_token_generation = var.lambda_pre_token_generation
150 | user_migration = var.lambda_user_migration
151 | verify_auth_challenge_response = var.lambda_verify_auth_challenge_response
152 | }
153 | }
154 |
155 | # Configuration block for Short Message Service (SMS) settings.
156 | # These settings apply to SMS user verification and SMS Multi-Factor Authentication (MFA).
157 | # Due to Cognito API restrictions, the SMS configuration cannot be removed without recreating the Cognito User Pool.
158 | # For user data safety, this resource will ignore the removal of this configuration by disabling drift detection.
159 | # To force resource recreation after this configuration has been applied, see the taint command.
160 | dynamic "sms_configuration" {
161 | for_each = var.sms_configuration != null ? [var.sms_configuration] : []
162 |
163 | content {
164 | external_id = lookup(var.sms_configuration, "external_id", null)
165 | sns_caller_arn = lookup(var.sms_configuration, "sns_caller_arn", null)
166 | }
167 | }
168 |
169 | # Advanced Security Features
170 | # Note: Additional pricing applies for Amazon Cognito advanced security features. For details please see:
171 | # https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-advanced-security.html
172 | user_pool_add_ons {
173 | advanced_security_mode = var.advanced_security_mode
174 | }
175 |
176 | verification_message_template {
177 | default_email_option = var.default_email_option
178 | email_subject = var.email_subject
179 | email_message = var.email_message
180 | email_subject_by_link = var.email_subject_by_link
181 | email_message_by_link = var.email_message_by_link
182 | sms_message = var.sms_message
183 | }
184 |
185 | tags = merge(var.module_tags, var.tags)
186 | depends_on = [var.module_depends_on]
187 | }
188 |
189 | locals {
190 | clients = {
191 | for client in var.clients : replace(lower(client.name), "/[^a-z0-9]/", "-") => {
192 | allowed_oauth_flows = lookup(client, "allowed_oauth_flows", var.default_client_allowed_oauth_flows)
193 | allowed_oauth_flows_user_pool_client = lookup(client, "allowed_oauth_flows_user_pool_client", var.default_client_allowed_oauth_flows_user_pool_client)
194 | allowed_oauth_scopes = lookup(client, "allowed_oauth_scopes", var.default_client_allowed_oauth_scopes)
195 | callback_urls = lookup(client, "callback_urls", var.default_client_callback_urls)
196 | default_redirect_uri = lookup(client, "default_redirect_uri", var.default_client_default_redirect_uri)
197 | explicit_auth_flows = lookup(client, "explicit_auth_flows", var.default_client_explicit_auth_flows)
198 | generate_secret = lookup(client, "generate_secret", var.default_client_generate_secret)
199 | logout_urls = lookup(client, "logout_urls", var.default_client_logout_urls)
200 | read_attributes = lookup(client, "read_attributes", var.default_client_read_attributes)
201 | refresh_token_validity = lookup(client, "refresh_token_validity", var.default_client_refresh_token_validity)
202 | supported_identity_providers = lookup(client, "supported_identity_providers", var.default_client_supported_identity_providers)
203 | prevent_user_existence_errors = lookup(client, "prevent_user_existence_errors", var.default_client_prevent_user_existence_errors)
204 | write_attributes = lookup(client, "write_attributes", var.default_client_write_attributes)
205 | access_token_validity = lookup(client, "access_token_validity", var.default_client_access_token_validity)
206 | id_token_validity = lookup(client, "id_token_validity", var.default_client_id_token_validity)
207 | token_validity_units = lookup(client, "token_validity_units", var.default_client_token_validity_units)
208 | enable_token_revocation = lookup(client, "enable_token_revocation", var.default_client_enable_token_revocation)
209 | }
210 | }
211 | }
212 |
213 | resource "aws_cognito_user_pool_client" "client" {
214 | for_each = var.module_enabled ? local.clients : {}
215 |
216 | name = each.key
217 |
218 | allowed_oauth_flows = each.value.allowed_oauth_flows
219 | allowed_oauth_flows_user_pool_client = each.value.allowed_oauth_flows_user_pool_client
220 | allowed_oauth_scopes = each.value.allowed_oauth_scopes
221 | callback_urls = each.value.callback_urls
222 | default_redirect_uri = each.value.default_redirect_uri
223 | explicit_auth_flows = each.value.explicit_auth_flows
224 | generate_secret = each.value.generate_secret
225 | logout_urls = each.value.logout_urls
226 | read_attributes = each.value.read_attributes
227 | refresh_token_validity = each.value.refresh_token_validity
228 | supported_identity_providers = each.value.supported_identity_providers
229 | prevent_user_existence_errors = each.value.prevent_user_existence_errors
230 | user_pool_id = aws_cognito_user_pool.user_pool[0].id
231 | write_attributes = each.value.write_attributes
232 | access_token_validity = each.value.access_token_validity
233 | id_token_validity = each.value.id_token_validity
234 |
235 | dynamic "token_validity_units" {
236 | for_each = each.value.token_validity_units != null ? [each.value.token_validity_units] : []
237 |
238 | content {
239 | refresh_token = try(token_validity_units.value.refresh_token, null)
240 | access_token = try(token_validity_units.value.access_token, null)
241 | id_token = try(token_validity_units.value.id_token, null)
242 | }
243 | }
244 |
245 | enable_token_revocation = each.value.enable_token_revocation
246 |
247 | depends_on = [
248 | aws_cognito_resource_server.resource_server
249 | ]
250 | }
251 |
252 | resource "aws_cognito_user_pool_domain" "domain" {
253 | count = var.module_enabled && var.domain != null ? 1 : 0
254 |
255 | domain = var.domain
256 | certificate_arn = var.certificate_arn
257 | user_pool_id = aws_cognito_user_pool.user_pool[0].id
258 | }
259 |
--------------------------------------------------------------------------------
/variables.tf:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------------
2 | # ENVIRONMENT VARIABLES
3 | # Define these secrets as environment variables.
4 | # ------------------------------------------------------------------------------
5 |
6 | # AWS_ACCESS_KEY_ID
7 | # AWS_SECRET_ACCESS_KEY
8 |
9 | # ------------------------------------------------------------------------------
10 | # REQUIRED PARAMETERS
11 | # These variables must be set when using this module.
12 | # ------------------------------------------------------------------------------
13 |
14 | variable "name" {
15 | type = string
16 | description = "(Required) The name of the user pool."
17 | }
18 |
19 | # ------------------------------------------------------------------------------
20 | # OPTIONAL PARAMETERS
21 | # These variables have defaults, but may be overridden.
22 | # ------------------------------------------------------------------------------
23 |
24 | variable "advanced_security_mode" {
25 | type = string
26 | description = "(Optional) The mode for advanced security, must be one of `OFF`, `AUDIT` or `ENFORCED`. Additional pricing applies for Amazon Cognito advanced security features. For details see https://aws.amazon.com/cognito/pricing/"
27 | default = "OFF"
28 | }
29 |
30 | variable "alias_attributes" {
31 | type = set(string)
32 | description = "(Optional) Attributes supported as an alias for this user pool. Possible values: 'phone_number', 'email', or 'preferred_username'. Conflicts with username_attributes."
33 | default = null
34 | }
35 |
36 | variable "username_attributes" {
37 | type = set(string)
38 | description = "(Optional) Specifies whether email addresses or phone numbers can be specified as usernames when a user signs up. Conflicts with alias_attributes."
39 | default = null
40 | }
41 |
42 | variable "allow_admin_create_user_only" {
43 | type = bool
44 | description = "(Optional) Set to True if only the administrator is allowed to create user profiles. Set to False if users can sign themselves up via an app."
45 | default = true
46 | }
47 |
48 | variable "resource_servers" {
49 | description = "(Optional) A list of objects with resource server definitions."
50 | type = any
51 |
52 | # Declare resource servers and associated custom scopes
53 | # For details please see https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_resource_server
54 | #
55 | # Example:
56 | #
57 | # resource_servers = [
58 | # {
59 | # identifier = "https://api.resourceserver.com"
60 | # name = "API"
61 | # scopes = [
62 | # {
63 | # scope_name = "users:read"
64 | # scope_description = "Read user data"
65 | # },
66 | # {
67 | # scope_name = "users:write"
68 | # scope_description = "Write user data"
69 | # }
70 | # ]
71 | # }
72 | # ]
73 |
74 | default = []
75 | }
76 |
77 | variable "clients" {
78 | description = "(Optional) A list of objects with the clients definitions."
79 | type = any
80 |
81 | # A list of clients that follow the normal schema defined by the provider.
82 | # For details please see https://www.terraform.io/docs/providers/aws/r/cognito_user_pool_client.html
83 | #
84 | # Example:
85 | #
86 | # clients = [
87 | # {
88 | # name = "android-mobile-client"
89 | # read_attributes = ["email", "email_verified", "preferred_username"]
90 | # allowed_oauth_scopes = ["email", "openid"]
91 | # allowed_oauth_flows = ["implicit"]
92 | # callback_urls = ["https://mineiros.io/callback", "https://mineiros.io/anothercallback"]
93 | # default_redirect_uri = "https://mineiros.io/callback"
94 | # generate_secret = true
95 | # }
96 | # ]
97 |
98 | default = []
99 | }
100 |
101 | variable "domain" {
102 | description = "(Optional) Type a domain prefix to use for the sign-up and sign-in pages that are hosted by Amazon Cognito, e.g. 'https://{YOUR_PREFIX}.auth.eu-west-1.amazoncognito.com'. The prefix must be unique across the selected AWS Region. Domain names can only contain lower-case letters, numbers, and hyphens."
103 | type = string
104 | default = null
105 | }
106 |
107 | variable "certificate_arn" {
108 | description = "(Optional) The ARN of an ISSUED ACM certificate in us-east-1 for a custom domain."
109 | type = string
110 | default = null
111 | }
112 |
113 | variable "default_client_allowed_oauth_flows" {
114 | description = "(Optional) List of allowed OAuth flows. Possible flows are 'code', 'implicit', and 'client_credentials'."
115 | type = list(string)
116 | default = null
117 | }
118 |
119 | variable "default_client_allowed_oauth_flows_user_pool_client" {
120 | description = "(Optional) Whether the client is allowed to follow the OAuth protocol when interacting with Cognito User Pools."
121 | type = bool
122 | default = null
123 | }
124 |
125 | variable "default_client_allowed_oauth_scopes" {
126 | description = "(Optional) List of allowed OAuth scopes. Possible values are 'phone', 'email', 'openid', 'profile', and 'aws.cognito.signin.user.admin'."
127 | type = list(string)
128 | default = null
129 | }
130 |
131 | variable "default_client_callback_urls" {
132 | description = "(Optional) List of allowed callback URLs for the identity providers."
133 | type = list(string)
134 | default = null
135 | }
136 |
137 | variable "default_client_default_redirect_uri" {
138 | description = "(Optional) The default redirect URI. Must be in the list of callback URLs."
139 | type = string
140 | default = null
141 | }
142 |
143 | variable "default_client_explicit_auth_flows" {
144 | description = "(Optional) List of authentication flows. Possible values are 'ADMIN_NO_SRP_AUTH', 'CUSTOM_AUTH_FLOW_ONLY', 'USER_PASSWORD_AUTH', 'ALLOW_ADMIN_USER_PASSWORD_AUTH', 'ALLOW_CUSTOM_AUTH', 'ALLOW_USER_PASSWORD_AUTH', 'ALLOW_USER_SRP_AUTH', and 'ALLOW_REFRESH_TOKEN_AUTH'."
145 | type = list(string)
146 | default = null
147 | }
148 |
149 | variable "default_client_generate_secret" {
150 | description = "(Optional) Boolean flag for generating an application secret."
151 | type = bool
152 | default = null
153 | }
154 |
155 | variable "default_client_logout_urls" {
156 | description = "(Optional) List of allowed logout URLs for the identity providers."
157 | type = list(string)
158 | default = null
159 | }
160 |
161 |
162 | variable "default_client_read_attributes" {
163 | description = "(Optional) List of Cognito User Pool attributes the application client can read from."
164 | type = list(string)
165 | default = null
166 | }
167 |
168 | variable "default_client_refresh_token_validity" {
169 | description = "(Optional) The time limit in days refresh tokens are valid for."
170 | type = number
171 | default = 30
172 | }
173 |
174 | variable "default_client_prevent_user_existence_errors" {
175 | description = "(Optional) Choose which errors and responses are returned by Cognito APIs during authentication, account confirmation, and password recovery when the user does not exist in the Cognito User Pool. When set to 'ENABLED' and the user does not exist, authentication returns an error indicating either the username or password was incorrect, and account confirmation and password recovery return a response indicating a code was sent to a simulated destination. When set to 'LEGACY', those APIs will return a 'UserNotFoundException' exception if the user does not exist in the Cognito User Pool."
176 | type = string
177 | default = null
178 | }
179 |
180 | variable "default_client_supported_identity_providers" {
181 | description = "(Optional) List of provider names for the identity providers that are supported on this client."
182 | type = list(string)
183 | default = null
184 | }
185 |
186 | variable "default_client_write_attributes" {
187 | description = "(Optional) List of Cognito User Pool attributes the application client can write to."
188 | type = list(string)
189 | default = null
190 | }
191 |
192 | variable "default_client_access_token_validity" {
193 | description = "(Optional) Time limit, between 5 minutes and 1 day, after which the access token is no longer valid and cannot be used. This value will be overridden if you have entered a value in 'default_client_token_validity_units'."
194 | type = number
195 | default = null
196 | }
197 |
198 | variable "default_client_id_token_validity" {
199 | description = "(Optional) Time limit, between 5 minutes and 1 day, after which the ID token is no longer valid and cannot be used. This value will be overridden if you have entered a value in 'default_client_token_validity_units'."
200 | type = number
201 | default = null
202 | }
203 |
204 | variable "default_client_token_validity_units" {
205 | description = "(Optional) Configuration block for units in which the validity times are represented in."
206 | # type = object({
207 | # refresh_token = optional(string)
208 | # access_token = optional(string)
209 | # id_token = optional(string)
210 | # })
211 | type = any
212 | default = null
213 |
214 | # Example:
215 | #
216 | # default_client_token_validity_units = {
217 | # refresh_token = "days"
218 | # access_token = "minutes"
219 | # id_token = "minutes"
220 | # }
221 | }
222 |
223 | variable "default_client_enable_token_revocation" {
224 | description = "(Optional) Enables or disables token revocation."
225 | type = bool
226 | default = null
227 | }
228 |
229 | variable "invite_email_subject" {
230 | type = string
231 | description = "(Optional) The subject for email messages."
232 | default = "Your new account."
233 | }
234 |
235 | variable "invite_email_message" {
236 | type = string
237 | description = "(Optional) The message template for email messages. Must contain {username} and {####} placeholders, for username and temporary password, respectively."
238 | default = "Your username is {username} and your temporary password is '{####}'."
239 | }
240 |
241 | variable "invite_sms_message" {
242 | type = string
243 | description = "(Optional) The message template for SMS messages. Must contain {username} and {####} placeholders, for username and temporary password, respectively."
244 | default = "Your username is {username} and your temporary password is '{####}'."
245 | }
246 |
247 | variable "auto_verified_attributes" {
248 | type = set(string)
249 | description = "(Optional) The attributes to be auto-verified. Possible values: 'email', 'phone_number'."
250 | default = [
251 | "email"
252 | ]
253 | }
254 |
255 | variable "account_recovery_mechanisms" {
256 | type = any
257 | description = "(Optional) A list of recovery_mechanisms which are defined by a `name` and its `priority`. Valid values for `name` are veri fied_email, verified_phone_number, and admin_only."
258 |
259 | # Example:
260 | #
261 | # account_recovery_setting_recovery_mechanisms = [
262 | # {
263 | # name = "verified_email"
264 | # priority = 1
265 | # },
266 | # {
267 | # name = "verified_phone_number"
268 | # priority = 2
269 | # }
270 | # ]
271 |
272 | default = []
273 | }
274 |
275 |
276 | variable "challenge_required_on_new_device" {
277 | type = bool
278 | description = "(Optional) Indicates whether a challenge is required on a new device. Only applicable to a new device."
279 | default = true
280 | }
281 |
282 | variable "user_device_tracking" {
283 | type = string
284 | description = "(Optional) Configure tracking of user devices. Set to 'OFF' to disable tracking, 'ALWAYS' to track all devices or 'USER_OPT_IN' to only track when user opts in."
285 | default = "USER_OPT_IN"
286 | }
287 |
288 | variable "enable_username_case_sensitivity" {
289 | type = bool
290 | description = "(Optional) Specifies whether username case sensitivity will be applied for all users in the user pool through Cognito APIs."
291 | default = false
292 | }
293 |
294 | variable "email_sending_account" {
295 | type = string
296 | description = "(Optional) The email delivery method to use. 'COGNITO_DEFAULT' for the default email functionality built into Cognito or 'DEVELOPER' to use your Amazon SES configuration."
297 | default = "COGNITO_DEFAULT"
298 | }
299 |
300 | variable "email_reply_to_address" {
301 | type = string
302 | description = "(Optional) - The REPLY-TO email address."
303 | default = null
304 | }
305 |
306 | variable "email_source_arn" {
307 | type = string
308 | description = "(Optional) - The ARN of the email source."
309 | default = null
310 | }
311 |
312 | variable "email_from_address" {
313 | type = string
314 | description = "(Optional) - Sender’s email address or sender’s name with their email address (e.g. 'john@smith.com' or 'John Smith ')."
315 | default = null
316 | }
317 |
318 | variable "mfa_configuration" {
319 | type = string
320 | description = "Multi-Factor Authentication (MFA) configuration for the User Pool. Valid values: 'ON', 'OFF' or 'OPTIONAL'. 'ON' and 'OPTIONAL' require at least one of 'sms_configuration' or 'software_token_mfa_configuration' to be configured."
321 | default = "OPTIONAL"
322 | }
323 |
324 | variable "password_minimum_length" {
325 | type = number
326 | description = "(Optional) The minimum length of the password policy that you have set."
327 | default = 20
328 | }
329 |
330 | variable "password_require_lowercase" {
331 | type = bool
332 | description = "(Optional) Whether you have required users to use at least one lowercase letter in their password."
333 | default = true
334 | }
335 |
336 | variable "password_require_numbers" {
337 | type = bool
338 | description = "(Optional) Whether you have required users to use at least one number in their password."
339 | default = true
340 | }
341 |
342 | variable "password_require_symbols" {
343 | type = bool
344 | description = "(Optional) Whether you have required users to use at least one symbol in their password."
345 | default = true
346 | }
347 |
348 | variable "password_require_uppercase" {
349 | type = bool
350 | description = "(Optional) Whether you have required users to use at least one uppercase letter in their password."
351 | default = true
352 | }
353 |
354 | variable "temporary_password_validity_days" {
355 | type = number
356 | description = "(Optional) In the password policy you have set, refers to the number of days a temporary password is valid. If the user does not sign-in during this time, their password will need to be reset by an administrator."
357 | default = 1
358 | }
359 |
360 | variable "allow_software_mfa_token" {
361 | description = "(Optional) Boolean whether to enable software token Multi-Factor (MFA) tokens, such as Time-based One-Time Password (TOTP). To disable software token MFA when 'sms_configuration' is not present, the 'mfa_configuration' argument must be set to OFF and the 'software_token_mfa_configuration' configuration block must be fully removed."
362 | type = bool
363 | default = true
364 | }
365 |
366 | variable "sms_authentication_message" {
367 | type = string
368 | description = "(Optional) A string representing the SMS authentication message. The message must contain the {####} placeholder, which will be replaced with the authentication code."
369 | default = "Your temporary password is {####}."
370 | }
371 |
372 | variable "lambda_create_auth_challenge" {
373 | type = string
374 | description = "(Optional) The ARN of an AWS Lambda creating an authentication challenge."
375 | default = null
376 | }
377 |
378 | variable "lambda_custom_message" {
379 | type = string
380 | description = "(Optional) The ARN of a custom message AWS Lambda trigger."
381 | default = null
382 | }
383 |
384 | variable "lambda_define_auth_challenge" {
385 | type = string
386 | description = "(Optional) The ARN of an AWS Lambda that defines the authentication challenge."
387 | default = null
388 | }
389 |
390 | variable "lambda_post_authentication" {
391 | type = string
392 | description = "(Optional) The ARN of a post-authentication AWS Lambda trigger."
393 | default = null
394 | }
395 |
396 | variable "lambda_post_confirmation" {
397 | type = string
398 | description = "(Optional) The ARN of a post-confirmation AWS Lambda trigger."
399 | default = null
400 | }
401 |
402 | variable "lambda_pre_authentication" {
403 | type = string
404 | description = "(Optional) The ARN of a pre-authentication AWS Lambda trigger."
405 | default = null
406 | }
407 |
408 | variable "lambda_pre_sign_up" {
409 | type = string
410 | description = "(Optional) The ARN of a pre-registration AWS Lambda trigger."
411 | default = null
412 | }
413 |
414 | variable "lambda_pre_token_generation" {
415 | type = string
416 | description = "(Optional) The ARN of an AWS Lambda that allows customization of identity token claims before token generation."
417 | default = null
418 | }
419 |
420 | variable "lambda_user_migration" {
421 | type = string
422 | description = "(Optional) The ARN of the user migration AWS Lambda config type."
423 | default = null
424 | }
425 |
426 | variable "lambda_verify_auth_challenge_response" {
427 | type = string
428 | description = "(Optional) The ARN of an AWS Lambda that verifies the authentication challenge response."
429 | default = null
430 | }
431 |
432 | variable "schema_attributes" {
433 | description = "(Optional) A list of schema attributes of a user pool. You can add a maximum of 25 custom attributes."
434 | type = any
435 |
436 | # Example:
437 | #
438 | # schema_attributes = [
439 | # {
440 | # name = "alternative_name"
441 | # type = "String"
442 | # developer_only_attribute = false,
443 | # mutable = true,
444 | # required = false,
445 | # min_length = 0,
446 | # max_length = 2048
447 | # },
448 | # {
449 | # name = "friends_count"
450 | # type = "Number"
451 | # min_value = 0,
452 | # max_value = 100
453 | #
454 | # },
455 | # {
456 | #
457 | # name = "is_active"
458 | # type = "Boolean"
459 | #
460 | # },
461 | # {
462 | # name = "last_seen"
463 | # type = "DateTime"
464 | #
465 | # }
466 | # ]
467 |
468 | default = []
469 | }
470 |
471 | variable "sms_configuration" {
472 | description = "(Optional) The `sms_configuration` with the `external_id` parameter used in iam role trust relationships and the `sns_caller_arn` parameter to set he arn of the amazon sns caller. this is usually the iam role that you've given cognito permission to assume."
473 | type = object({
474 | # The external ID used in IAM role trust relationships. For more information about using external IDs, see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html
475 | external_id = string
476 | # The ARN of the Amazon SNS caller. This is usually the IAM role that you've given Cognito permission to assume.
477 | sns_caller_arn = string
478 | })
479 | default = null
480 | }
481 |
482 | variable "default_email_option" {
483 | type = string
484 | description = "(Optional) The default email option. Must be either `CONFIRM_WITH_CODE` or `CONFIRM_WITH_LINK`."
485 | default = "CONFIRM_WITH_CODE"
486 | }
487 |
488 | variable "email_message" {
489 | type = string
490 | description = "(Optional) The email message template. Must contain the {####} placeholder."
491 | default = "Your verification code is {####}."
492 | }
493 |
494 | variable "email_message_by_link" {
495 | type = string
496 | description = "(Optional) The email message template for sending a confirmation link to the user, it must contain the {##Any Text##} placeholder."
497 | default = "Please click the link below to verify your email address. {##Verify Email##}."
498 | }
499 |
500 | variable "email_subject" {
501 | type = string
502 | description = "(Optional) The subject line for the email message template."
503 | default = "Your Verification Code"
504 | }
505 |
506 | variable "email_subject_by_link" {
507 | type = string
508 | description = "(Optional) The subject line for the email message template for sending a confirmation link to the user."
509 | default = "Your Verification Link"
510 | }
511 |
512 | variable "sms_message" {
513 | type = string
514 | description = "(Optional) The SMS message template. Must contain the {####} placeholder, which will be replaced with the verification code. Can also contain the {username} placeholder which will be replaced with the username."
515 | default = "Your verification code is {####}."
516 | }
517 |
518 | variable "tags" {
519 | type = map(string)
520 | description = "(Optional) A mapping of tags to assign to the resource."
521 |
522 | #
523 | # Example:
524 | #
525 | # tags = {
526 | # CreatedAt = "2020-02-07",
527 | # Alice = "Bob
528 | # }
529 | #
530 |
531 | default = {}
532 | }
533 |
534 | # ------------------------------------------------------------------------------
535 | # OPTIONAL MODULE CONFIGURATION PARAMETERS
536 | # These variables are used to configure the module.
537 | # ------------------------------------------------------------------------------
538 |
539 | variable "module_enabled" {
540 | type = bool
541 | description = "(Optional) Whether to create resources within the module or not."
542 | default = true
543 | }
544 |
545 | variable "module_tags" {
546 | type = map(string)
547 | description = "(Optional) A map of tags that will be applied to all created resources that accept tags. Tags defined with 'module_tags' can be overwritten by resource-specific tags."
548 | default = {}
549 | }
550 |
551 | variable "module_depends_on" {
552 | type = any
553 | description = "(Optional) A list of external resources the module depends_on."
554 | default = []
555 | }
556 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [
](https://mineiros.io/?ref=terraform-aws-cognito-user-pool)
2 |
3 | [](https://github.com/mineiros-io/terraform-aws-cognito-user-pool/actions)
4 | [](https://github.com/mineiros-io/terraform-aws-cognito-user-pool/releases)
5 | [](https://github.com/hashicorp/terraform/releases)
6 | [](https://github.com/terraform-providers/terraform-provider-aws/releases)
7 | [](https://mineiros.io/slack)
8 |
9 | # terraform-aws-cognito-user-pool
10 |
11 | A [Terraform] module for deploying and managing
12 | [Cognito User Pools]
13 | on [Amazon Web Services (AWS)][AWS].
14 |
15 | *This module supports Terraform v1.x, v0.15, v0.14, v0.13 as well as v0.12.20 and above
16 | and is compatible with the Terraform AWS provider v3.50 and above.
17 |
18 |
19 | - [Module Features](#module-features)
20 | - [Getting Started](#getting-started)
21 | - [Module Argument Reference](#module-argument-reference)
22 | - [Top-level Arguments](#top-level-arguments)
23 | - [Module Configuration](#module-configuration)
24 | - [Cognito User Pool](#cognito-user-pool)
25 | - [Cognito User Pool Domain](#cognito-user-pool-domain)
26 | - [Cognito User Pool Resource Servers](#cognito-user-pool-resource-servers)
27 | - [Cognito User Pool Clients](#cognito-user-pool-clients)
28 | - [Cognito User Pool Clients Default Values](#cognito-user-pool-clients-default-values)
29 | - [Module Outputs](#module-outputs)
30 | - [External Documentation](#external-documentation)
31 | - [AWS Documentation](#aws-documentation)
32 | - [Terraform AWS Provider Documentation](#terraform-aws-provider-documentation)
33 | - [Module Versioning](#module-versioning)
34 | - [Backwards compatibility in `0.0.z` and `0.y.z` version](#backwards-compatibility-in-00z-and-0yz-version)
35 | - [About Mineiros](#about-mineiros)
36 | - [Reporting Issues](#reporting-issues)
37 | - [Contributing](#contributing)
38 | - [Makefile Targets](#makefile-targets)
39 | - [License](#license)
40 |
41 | ## Module Features
42 |
43 | In contrast to the plain [`cognito_user_pool`](https://www.terraform.io/docs/providers/aws/r/cognito_user_pool.html)
44 | resource this module has a more secure level of default settings.
45 |
46 | While all settings can be customized as needed, best practices are
47 | pre-configured.
48 |
49 | - **Default Security Settings**:
50 | Per default, only administrators are allowed to create user profiles by
51 | setting `allow_admin_create_user_only` to `true`. This module comes with a
52 | strong default password policy.
53 |
54 | **Standard Cognito Features**:
55 | Create a Cognito User Pool with pre-configured best practices.
56 | Create Cognito User Pool Clients.
57 | Create a Cognito User Pool Domain.
58 | Create Cognito User Pool Resource Servers as associated scopes.
59 |
60 | - *Features not yet implemented*:
61 | [`cognito_user_group`](https://www.terraform.io/docs/providers/aws/r/cognito_user_group.html)
62 |
63 | ## Getting Started
64 |
65 | Most basic usage just setting required arguments:
66 |
67 | ```hcl
68 | module "terraform-aws-cognito-user-pool" {
69 | source = "mineiros-io/cognito-user-pool/aws"
70 | version = "~> 0.9.0"
71 |
72 | name = "application-userpool"
73 | }
74 | ```
75 |
76 | Advanced usage as found in
77 | [examples/complete/main.tf](https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/examples/complete/main.tf)
78 | setting all required and optional arguments to their default values.
79 |
80 | ## Module Argument Reference
81 |
82 | See
83 | [variables.tf](https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/variables.tf)
84 | and
85 | [examples/](https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/examples)
86 | for details and use-cases.
87 |
88 | ### Top-level Arguments
89 |
90 | #### Module Configuration
91 |
92 | - [**`module_enabled`**](#var-module_enabled): *(Optional `bool`)*
93 |
94 | Specifies whether resources in the module will be created.
95 |
96 | Default is `true`.
97 |
98 | - [**`module_tags`**](#var-module_tags): *(Optional `map(string)`)*
99 |
100 | A map of tags that will be applied to all created resources that accept tags. Tags defined with 'module_tags' can be overwritten by resource-specific tags.
101 |
102 | Default is `{}`.
103 |
104 | Example:
105 |
106 | ```hcl
107 | module_tags = {
108 | environment = "staging"
109 | team = "platform"
110 | }
111 | ```
112 |
113 | - [**`module_depends_on`**](#var-module_depends_on): *(Optional `list(dependency)`)*
114 |
115 | A list of dependencies. Any object can be _assigned_ to this list to define a hidden external dependency.
116 |
117 | Example:
118 |
119 | ```hcl
120 | module_depends_on = [
121 | aws_vpc.vpc
122 | ]
123 | ```
124 |
125 | #### Cognito User Pool
126 |
127 | - [**`name`**](#var-name): *(**Required** `string`)*
128 |
129 | The name of the user pool. Forces new resource.
130 |
131 | - [**`advanced_security_mode`**](#var-advanced_security_mode): *(Optional `string`)*
132 |
133 | The mode for advanced security, must be one of `OFF`, `AUDIT` or `ENFORCED`. Additional pricing applies for Amazon Cognito advanced security features. For details see https://aws.amazon.com/cognito/pricing/.
134 |
135 | Default is `"OFF"`.
136 |
137 | - [**`alias_attributes`**](#var-alias_attributes): *(Optional `set(string)`)*
138 |
139 | Attributes supported as an alias for this user pool. Possible values: `phone_number`, `email`, or `preferred_username`. Conflicts with `username_attributes`. Default applies if `username_attributes` is not set.
140 |
141 | - [**`username_attributes`**](#var-username_attributes): *(Optional `set(string)`)*
142 |
143 | Specifies whether `email` addresse or `phone_number` can be specified as usernames when a user signs up. Conflicts with `alias_attributes`.
144 | Default is to use `alias_attributes`.
145 |
146 | - [**`allow_admin_create_user_only`**](#var-allow_admin_create_user_only): *(Optional `bool`)*
147 |
148 | Set to True if only the administrator is allowed to create user profiles. Set to False if users can sign themselves up via an app.
149 |
150 | Default is `true`.
151 |
152 | - [**`invite_email_subject`**](#var-invite_email_subject): *(Optional `string`)*
153 |
154 | The message template for email messages.
155 |
156 | Default is `"Your new account."`.
157 |
158 | - [**`invite_email_message`**](#var-invite_email_message): *(Optional `string`)*
159 |
160 | The message template for email messages. Must contain `{username}` and `{####}` placeholders, for username and temporary password, respectively.
161 |
162 | Default is `"Your username is {username} and your temporary password is ' {####}'"`.
163 |
164 | - [**`invite_sms_message`**](#var-invite_sms_message): *(Optional `string`)*
165 |
166 | The message template for SMS messages. Must contain `{username}` and `{####}` placeholders, for username and temporary password, respectively.
167 |
168 | Default is `"Your username is {username} and your temporary password is ' {####}'."`.
169 |
170 | - [**`auto_verified_attributes`**](#var-auto_verified_attributes): *(Optional `set(string)`)*
171 |
172 | The attributes to be auto-verified. Possible values: `email`, `phone_number`.
173 |
174 | Default is `["email"]`.
175 |
176 | - [**`user_device_tracking`**](#var-user_device_tracking): *(Optional `string`)*
177 |
178 | Configure tracking of user devices. Set to `OFF` to disable tracking, `ALWAYS` to track all devices or `USER_OPT_IN` to only track when user opts in.
179 |
180 | Default is `"USER_OPT_IN"`.
181 |
182 | - [**`challenge_required_on_new_device`**](#var-challenge_required_on_new_device): *(Optional `bool`)*
183 |
184 | Indicates whether a challenge is required on a new device. Only applicable to a new device. Only applied when `user_device_tracking` is enabled.
185 |
186 | Default is `true`.
187 |
188 | - [**`enable_username_case_sensitivity`**](#var-enable_username_case_sensitivity): *(Optional `bool`)*
189 |
190 | Specifies whether username case sensitivity will be applied to all users in the user pool through Cognito APIs.
191 |
192 | Default is `false`.
193 |
194 | - [**`email_sending_account`**](#var-email_sending_account): *(Optional `string`)*
195 |
196 | The email delivery method to use. `COGNITO_DEFAULT` for the default email functionality built into Cognito or `DEVELOPER` to use your Amazon SES configuration.
197 |
198 | Default is `"COGNITO_DEFAULT"`.
199 |
200 | - [**`email_reply_to_address`**](#var-email_reply_to_address): *(Optional `string`)*
201 |
202 | The REPLY-TO email address.
203 |
204 | - [**`email_source_arn`**](#var-email_source_arn): *(Optional `string`)*
205 |
206 | The ARN of the email source.
207 |
208 | - [**`email_from_address`**](#var-email_from_address): *(Optional `string`)*
209 |
210 | Sender’s email address or sender’s name with their email address (e.g. 'john@smith.com' or 'John Smith ').
211 |
212 | - [**`mfa_configuration`**](#var-mfa_configuration): *(Optional `string`)*
213 |
214 | Multi-Factor Authentication (MFA) configuration for the User Pool. Valid values: `ON`, `OFF` or `OPTIONAL`. `ON` and `OPTIONAL` require at least one of `sms_configuration` or `software_token_mfa_configuration` to be configured.
215 |
216 | Default is `"OPTIONAL"`.
217 |
218 | - [**`password_minimum_length`**](#var-password_minimum_length): *(Optional `number`)*
219 |
220 | The minimum length of the password policy that you have set.
221 |
222 | Default is `20`.
223 |
224 | - [**`password_require_lowercase`**](#var-password_require_lowercase): *(Optional `bool`)*
225 |
226 | Whether you have required users to use at least one lowercase letter in their password.
227 |
228 | Default is `true`.
229 |
230 | - [**`password_require_numbers`**](#var-password_require_numbers): *(Optional `bool`)*
231 |
232 | Whether you have required users to use at least one number in their password.
233 |
234 | Default is `true`.
235 |
236 | - [**`password_require_symbols`**](#var-password_require_symbols): *(Optional `bool`)*
237 |
238 | Whether you have required users to use at least one symbol in their password.
239 |
240 | Default is `true`.
241 |
242 | - [**`password_require_uppercase`**](#var-password_require_uppercase): *(Optional `bool`)*
243 |
244 | Whether you have required users to use at least one uppercase letter in their password.
245 |
246 | Default is `true`.
247 |
248 | - [**`temporary_password_validity_days`**](#var-temporary_password_validity_days): *(Optional `number`)*
249 |
250 | In the password policy you have set, refers to the number of days a temporary password is valid. If the user does not sign in during this time, their password will need to be reset by an administrator.
251 |
252 | Default is `1`.
253 |
254 | - [**`allow_software_mfa_token`**](#var-allow_software_mfa_token): *(Optional `bool`)*
255 |
256 | Boolean whether to enable software token Multi-Factor Authentication (MFA) tokens, such as Time-Based One-Time Password (TOTP). To disable software token MFA when `sms_configuration` is not present, the `mfa_configuration` argument must be set to `OFF` and the `software_token_mfa_configuration` configuration block must be fully removed.
257 |
258 | Default is `true`.
259 |
260 | - [**`sms_authentication_message`**](#var-sms_authentication_message): *(Optional `string`)*
261 |
262 | A string representing the SMS authentication message. The message must contain the `{####}` placeholder, which will be replaced with the authentication code.
263 |
264 | Default is `"Your temporary password is {####}."`.
265 |
266 | - [**`lambda_create_auth_challenge`**](#var-lambda_create_auth_challenge): *(Optional `string`)*
267 |
268 | The ARN of an AWS Lambda creating an authentication challenge.
269 |
270 | - [**`lambda_custom_message`**](#var-lambda_custom_message): *(Optional `string`)*
271 |
272 | The ARN of a custom message AWS Lambda trigger.
273 |
274 | - [**`lambda_define_auth_challenge`**](#var-lambda_define_auth_challenge): *(Optional `string`)*
275 |
276 | The ARN of an AWS Lambda that defines the authentication challenge.
277 |
278 | - [**`lambda_post_authentication`**](#var-lambda_post_authentication): *(Optional `string`)*
279 |
280 | The ARN of an AWS Lambda that defines the authentication challenge.
281 |
282 | - [**`lambda_post_confirmation`**](#var-lambda_post_confirmation): *(Optional `string`)*
283 |
284 | The ARN of a post-confirmation AWS Lambda trigger.
285 |
286 | - [**`lambda_pre_authentication`**](#var-lambda_pre_authentication): *(Optional `string`)*
287 |
288 | The ARN of a pre-authentication AWS Lambda trigger.
289 |
290 | - [**`lambda_pre_sign_up`**](#var-lambda_pre_sign_up): *(Optional `string`)*
291 |
292 | The ARN of a pre-registration AWS Lambda trigger.
293 |
294 | - [**`lambda_pre_token_generation`**](#var-lambda_pre_token_generation): *(Optional `string`)*
295 |
296 | The ARN of an AWS Lambda that allows customization of identity token claims before token generation.
297 |
298 | - [**`lambda_user_migration`**](#var-lambda_user_migration): *(Optional `string`)*
299 |
300 | The ARN of he user migration AWS Lambda config type.
301 |
302 | - [**`lambda_verify_auth_challenge_response`**](#var-lambda_verify_auth_challenge_response): *(Optional `string`)*
303 |
304 | The ARN of an AWS Lambda that verifies the authentication challenge response.
305 |
306 | Default is `"true"`.
307 |
308 | - [**`schema_attributes`**](#var-schema_attributes): *(Optional `list(schema_attribute)`)*
309 |
310 | A list of schema attributes of a user pool. You can add a maximum of 25 custom attributes. Please note that only default attributes can be marked as required.
311 | Also an attribute cannot be switched between required and not required after a user pool has been created.
312 | For details please see the [attributes docs].
313 |
314 | Default is `[]`.
315 |
316 | Example:
317 |
318 | ```hcl
319 | schema_attributes = [
320 | {
321 | name = "gender", # overwrites the default attribute 'gender'
322 | type = "String"
323 | required = true # required can only be set for default attributes
324 | },
325 | {
326 | name = "alternative_name"
327 | type = "String"
328 | min_length = 0,
329 | max_length = 2048
330 | },
331 | {
332 | name = "friends_count"
333 | type = "Number"
334 | min_value = 0,
335 | max_value = 100
336 | },
337 | {
338 | name = "is_active"
339 | type = "Boolean"
340 | },
341 | {
342 | name = "last_seen"
343 | type = "DateTime"
344 | }
345 | ]
346 | ```
347 |
348 | - [**`account_recovery_mechanisms`**](#var-account_recovery_mechanisms): *(Optional `list(account_recovery_mechanism)`)*
349 |
350 | A list of recovery_mechanisms to be inserted inside `account_recovery_setting`.
351 |
352 | Default is `[]`.
353 |
354 | Example:
355 |
356 | ```hcl
357 | account_recovery_mechanisms = [
358 | {
359 | name = "verified_email"
360 | priority = 1
361 | },
362 | {
363 | name = "verified_phone_number"
364 | priority = 2
365 | }
366 | ]
367 | ```
368 |
369 | Each `account_recovery_mechanism` object in the list accepts the following attributes:
370 |
371 | - [**`name`**](#attr-account_recovery_mechanisms-name): *(**Required** `string`)*
372 |
373 | Recovery method for a user. Can be of the following: verified_email, verified_phone_number, and admin_only.
374 |
375 | - [**`priority`**](#attr-account_recovery_mechanisms-priority): *(**Required** `string`)*
376 |
377 | Positive integer specifying priority of a method with 1 being the highest priority.
378 |
379 | - [**`sms_configuration`**](#var-sms_configuration): *(Optional `object(sms_configuration)`)*
380 |
381 | The `sms_configuration` with the `external_id` parameter used in IAM role trust relationships and the `sns_caller_arn` parameter to set the ARN of the Amazon SNS caller. This is usually the IAM role that you have given AWS Cognito permission to assume.
382 |
383 | The `sms_configuration` object accepts the following attributes:
384 |
385 | - [**`external_id`**](#attr-sms_configuration-external_id): *(**Required** `string`)*
386 |
387 | External ID used in IAM role trust relationships.
388 |
389 | - [**`sns_caller_arn`**](#attr-sms_configuration-sns_caller_arn): *(**Required** `string`)*
390 |
391 | ARN of the Amazon SNS caller. This is usually the IAM role that you've given Cognito permission to assume.
392 |
393 | - [**`default_email_option`**](#var-default_email_option): *(Optional `string`)*
394 |
395 | The default email option. Must be either `CONFIRM_WITH_CODE` or `CONFIRM_WITH_LINK`.
396 |
397 | Default is `"CONFIRM_WITH_CODE"`.
398 |
399 | - [**`email_message`**](#var-email_message): *(Optional `string`)*
400 |
401 | The email message template. Must contain the `{####}` placeholder.
402 |
403 | Default is `"Your verification code is {####}."`.
404 |
405 | - [**`email_message_by_link`**](#var-email_message_by_link): *(Optional `string`)*
406 |
407 | The email message template for sending a confirmation link to the user, it must contain the `{##Any Text##}` placeholder.
408 |
409 | Default is `"Please click the link below to verify your email address.{##Verify Email##}."`.
410 |
411 | - [**`email_subject`**](#var-email_subject): *(Optional `string`)*
412 |
413 | The subject line for the email message template.
414 |
415 | Default is `"Your Verification Code"`.
416 |
417 | - [**`email_subject_by_link`**](#var-email_subject_by_link): *(Optional `string`)*
418 |
419 | The subject line for the email message template for sending a confirmation link to the user.
420 |
421 | Default is `"Your Verifiction Link"`.
422 |
423 | - [**`sms_message`**](#var-sms_message): *(Optional `string`)*
424 |
425 | The SMS message template. Must contain the `{####}` placeholder, which will be replaced with the verification code. Can also contain the `{username}` placeholder which will be replaced with the username.
426 |
427 | Default is `"Your verification code is {####}."`.
428 |
429 | - [**`tags`**](#var-tags): *(Optional `map(string)`)*
430 |
431 | A mapping of tags to assign to the resource.
432 |
433 | Default is `{}`.
434 |
435 | Example:
436 |
437 | ```hcl
438 | tags = {
439 | CreatedAt = "2020-02-07",
440 | Alice = "Bob"
441 | }
442 | ```
443 |
444 | #### Cognito User Pool Domain
445 |
446 | - [**`domain`**](#var-domain): *(Optional `string`)*
447 |
448 | The domain name that should be used. Can be set to a FQDN or prefix.
449 | If no FQDN and `certificate_arn` are set, the domain prefix will be used for the sign-up and sign-in pages that are hosted by Amazon Cognito,
450 | e.g. `https://{YOUR_PREFIX}.auth.eu-west-1.amazoncognito.com`.
451 | The prefix must be unique across the selected AWS Region.
452 | Domain names can only contain lower-case letters, numbers, and hyphens.
453 |
454 | - [**`certificate_arn`**](#var-certificate_arn): *(Optional `string`)*
455 |
456 | The ARN of an ISSUED ACM certificate in us-east-1 for a custom domain.
457 |
458 | #### Cognito User Pool Resource Servers
459 |
460 | - [**`resource_servers`**](#var-resource_servers): *(Optional `list(resource_server)`)*
461 |
462 | A list of objects with resource server declarations.
463 |
464 | Default is `[]`.
465 |
466 | Example:
467 |
468 | ```hcl
469 | resource_servers = [
470 | {
471 | identifier = "https://api.resourceserver.com"
472 | name = "API"
473 | scopes = [
474 | {
475 | scope_name = "users:read"
476 | scope_description = "Read user data"
477 | },
478 | {
479 | scope_name = "users:write"
480 | scope_description = "Write user data"
481 | }
482 | ]
483 | }
484 | ]
485 | ```
486 |
487 | Each `resource_server` object in the list accepts the following attributes:
488 |
489 | - [**`identifier`**](#attr-resource_servers-identifier): *(**Required** `string`)*
490 |
491 | An identifier for the resource server.
492 |
493 | - [**`name`**](#attr-resource_servers-name): *(**Required** `string`)*
494 |
495 | A name for the resource server.
496 |
497 | - [**`scope`**](#attr-resource_servers-scope): *(Optional `list(scope)`)*
498 |
499 | A list of Authorization Scope.
500 |
501 | Each `scope` object in the list accepts the following attributes:
502 |
503 | - [**`scope_name`**](#attr-resource_servers-scope-scope_name): *(**Required** `string`)*
504 |
505 | The scope name.
506 |
507 | - [**`scope_description`**](#attr-resource_servers-scope-scope_description): *(**Required** `string`)*
508 |
509 | The scope description.
510 |
511 | #### Cognito User Pool Clients
512 |
513 | - [**`clients`**](#var-clients): *(Optional `list(client)`)*
514 |
515 | A list of objects with the clients definitions.
516 |
517 | Default is `[]`.
518 |
519 | Example:
520 |
521 | ```hcl
522 | clients = [
523 | {
524 | name = "android-mobile-client"
525 | read_attributes = ["email", "email_verified", "preferred_username"]
526 | allowed_oauth_scopes = ["email", "openid"]
527 | allowed_oauth_flows = ["implicit"]
528 | callback_urls = ["https://mineiros.io/callback", "https://mineiros.io/anothercallback"]
529 | default_redirect_uri = "https://mineiros.io/callback"
530 | generate_secret = true
531 | }
532 | ]
533 | ```
534 |
535 | Each `client` object in the list accepts the following attributes:
536 |
537 | - [**`name`**](#attr-clients-name): *(**Required** `string`)*
538 |
539 | Name of the application client.
540 |
541 | - [**`user_pool_id`**](#attr-clients-user_pool_id): *(Optional `string`)*
542 |
543 | Name of the application client.
544 |
545 | - [**`access_token_validity`**](#attr-clients-access_token_validity): *(Optional `number`)*
546 |
547 | Time limit, between 5 minutes and 1 day, after which the access token is no longer valid and cannot be used. This value will be overridden if you have entered a value in token_validity_units.
548 |
549 | - [**`allowed_oauth_flows_user_pool_client`**](#attr-clients-allowed_oauth_flows_user_pool_client): *(Optional `bool`)*
550 |
551 | Whether the client is allowed to follow the OAuth protocol when interacting with Cognito user pools.
552 |
553 | - [**`allowed_oauth_flows`**](#attr-clients-allowed_oauth_flows): *(Optional `set(string)`)*
554 |
555 | List of allowed OAuth flows (code, implicit, client_credentials).
556 |
557 | - [**`allowed_oauth_scopes`**](#attr-clients-allowed_oauth_scopes): *(Optional `set(string)`)*
558 |
559 | List of allowed OAuth scopes (phone, email, openid, profile, and aws.cognito.signin.user.admin).
560 |
561 | - [**`analytics_configuration`**](#attr-clients-analytics_configuration): *(Optional `object(analytics_configuration)`)*
562 |
563 | Configuration block for Amazon Pinpoint analytics for collecting metrics for this user pool.
564 |
565 | The `analytics_configuration` object accepts the following attributes:
566 |
567 | - [**`application_arn`**](#attr-clients-analytics_configuration-application_arn): *(Optional `string`)*
568 |
569 | Application ARN for an Amazon Pinpoint application. Conflicts with external_id and role_arn.
570 |
571 | - [**`application_id`**](#attr-clients-analytics_configuration-application_id): *(Optional `string`)*
572 |
573 | Application ID for an Amazon Pinpoint application.
574 |
575 | - [**`external_id`**](#attr-clients-analytics_configuration-external_id): *(Optional `string`)*
576 |
577 | ID for the Analytics Configuration. Conflicts with application_arn. Application ID for an Amazon Pinpoint application.
578 |
579 | - [**`role_arn`**](#attr-clients-analytics_configuration-role_arn): *(Optional `string`)*
580 |
581 | ARN of an IAM role that authorizes Amazon Cognito to publish events to Amazon Pinpoint analytics. Conflicts with application_arn.
582 |
583 | - [**`user_data_shared`**](#attr-clients-analytics_configuration-user_data_shared): *(Optional `bool`)*
584 |
585 | If set to true, Amazon Cognito will include user data in the events it publishes to Amazon Pinpoint analytics.
586 |
587 | - [**`callback_urls`**](#attr-clients-callback_urls): *(Optional `set(string)`)*
588 |
589 | List of allowed callback URLs for the identity providers.
590 |
591 | - [**`default_redirect_uri`**](#attr-clients-default_redirect_uri): *(Optional `string`)*
592 |
593 | Default redirect URI. Must be in the list of callback URLs.
594 |
595 | - [**`enable_token_revocation`**](#attr-clients-enable_token_revocation): *(Optional `bool`)*
596 |
597 | Enables or disables token revocation.
598 |
599 | - [**`explicit_auth_flows`**](#attr-clients-explicit_auth_flows): *(Optional `set(string)`)*
600 |
601 | List of authentication flows (ADMIN_NO_SRP_AUTH, CUSTOM_AUTH_FLOW_ONLY, USER_PASSWORD_AUTH, ALLOW_ADMIN_USER_PASSWORD_AUTH, ALLOW_CUSTOM_AUTH, ALLOW_USER_PASSWORD_AUTH, ALLOW_USER_SRP_AUTH, ALLOW_REFRESH_TOKEN_AUTH).
602 |
603 | - [**`generate_secret`**](#attr-clients-generate_secret): *(Optional `bool`)*
604 |
605 | Should an application secret be generated.
606 |
607 | - [**`id_token_validity`**](#attr-clients-id_token_validity): *(Optional `number`)*
608 |
609 | Time limit, between 5 minutes and 1 day, after which the ID token is no longer valid and cannot be used. This value will be overridden if you have entered a value in token_validity_units.
610 |
611 | - [**`logout_urls`**](#attr-clients-logout_urls): *(Optional `set(string)`)*
612 |
613 | List of allowed logout URLs for the identity providers.
614 |
615 | - [**`prevent_user_existence_errors`**](#attr-clients-prevent_user_existence_errors): *(Optional `string`)*
616 |
617 | Choose which errors and responses are returned by Cognito APIs during authentication, account confirmation, and password recovery when the user does not exist in the user pool. When set to ENABLED and the user does not exist, authentication returns an error indicating either the username or password was incorrect, and account confirmation and password recovery return a response indicating a code was sent to a simulated destination. When set to LEGACY, those APIs will return a UserNotFoundException exception if the user does not exist in the user pool.
618 |
619 | - [**`read_attributes`**](#attr-clients-read_attributes): *(Optional `set(string)`)*
620 |
621 | List of user pool attributes the application client can read from.
622 |
623 | - [**`refresh_token_validity`**](#attr-clients-refresh_token_validity): *(Optional `number`)*
624 |
625 | Time limit in days refresh tokens are valid for.
626 |
627 | - [**`supported_identity_providers`**](#attr-clients-supported_identity_providers): *(Optional `set(string)`)*
628 |
629 | List of provider names for the identity providers that are supported on this client. Uses the provider_name attribute of aws_cognito_identity_provider resource(s), or the equivalent string(s).
630 |
631 | - [**`token_validity_units`**](#attr-clients-token_validity_units): *(Optional `object(token_validity_units)`)*
632 |
633 | Configuration block for units in which the validity times are represented in.
634 |
635 | The `token_validity_units` object accepts the following attributes:
636 |
637 | - [**`access_token`**](#attr-clients-token_validity_units-access_token): *(Optional `string`)*
638 |
639 | Time unit in for the value in access_token_validity, defaults to hours.
640 |
641 | Default is `"hours"`.
642 |
643 | - [**`id_token`**](#attr-clients-token_validity_units-id_token): *(Optional `string`)*
644 |
645 | Time unit in for the value in id_token_validity, defaults to hours.
646 |
647 | Default is `"hours"`.
648 |
649 | - [**`refresh_token`**](#attr-clients-token_validity_units-refresh_token): *(Optional `string`)*
650 |
651 | Time unit in for the value in refresh_token_validity, defaults to days.
652 |
653 | Default is `"days"`.
654 |
655 | - [**`write_attributes`**](#attr-clients-write_attributes): *(Optional `set(string)`)*
656 |
657 | List of user pool attributes the application client can write to.
658 |
659 | #### Cognito User Pool Clients Default Values
660 |
661 | The following variables can be used for setting default settings among various clients defined through the `clients` variable. This helps you to quickly issue several clients that implement the same settings, e.g. like so:
662 |
663 | ```hcl
664 | clients = [
665 | { name = "ios" },
666 | { name = "android" },
667 | { name = "web" },
668 | ]
669 |
670 | default_client_read_attributes = ["email", "email_verified", "preferred_username"]
671 | default_client_allowed_oauth_scopes = ["email", "openid"]
672 | default_client_allowed_oauth_flows = ["implicit"]
673 | default_client_callback_urls = ["https://mineiros.io/callback", "https://mineiros.io/anothercallback"]
674 | default_client_default_redirect_uri = "https://mineiros.io/callback"
675 | default_client_generate_secret = true
676 | default_client_refresh_token_validity = 45
677 |
678 | default_client_supported_identity_providers = null
679 | default_client_logout_urls = null
680 | default_client_allowed_oauth_flows_user_pool_client = null
681 | default_client_write_attributes = null
682 | default_client_explicit_auth_flows = null
683 | default_client_prevent_user_existence_errors = null
684 | default_client_access_token_validity = null
685 | default_client_id_token_validity = null
686 | default_client_token_validity_units = null
687 | default_client_enable_token_revocation = null
688 | ```
689 |
690 | - [**`default_client_callback_urls`**](#var-default_client_callback_urls): *(Optional `list(string)`)*
691 |
692 | List of allowed callback URLs for the identity providers.
693 |
694 | - [**`default_client_default_redirect_uri`**](#var-default_client_default_redirect_uri): *(Optional `string`)*
695 |
696 | The default redirect URI. Must be in the list of callback URLs.
697 |
698 | - [**`default_client_read_attributes`**](#var-default_client_read_attributes): *(Optional `list(string)`)*
699 |
700 | List of Cognito User Pool attributes the application client can read from.
701 |
702 | - [**`default_client_refresh_token_validity`**](#var-default_client_refresh_token_validity): *(Optional `number`)*
703 |
704 | The time limit in days refresh tokens are valid for.
705 |
706 | Default is `30`.
707 |
708 | - [**`default_client_supported_identity_providers`**](#var-default_client_supported_identity_providers): *(Optional `list(string)`)*
709 |
710 | List of provider names for the identity providers that are supported on this client.
711 |
712 | - [**`default_client_allowed_oauth_scopes`**](#var-default_client_allowed_oauth_scopes): *(Optional `list(string)`)*
713 |
714 | List of allowed OAuth scopes. Possible values are `phone`, `email`, `openid`, `profile`, and `aws.cognito.signin.user.admin`.
715 |
716 | - [**`default_client_logout_urls`**](#var-default_client_logout_urls): *(Optional `list(string)`)*
717 |
718 | List of allowed logout URLs for the identity providers.
719 |
720 | - [**`default_client_allowed_oauth_flows_user_pool_client`**](#var-default_client_allowed_oauth_flows_user_pool_client): *(Optional `bool`)*
721 |
722 | Whether the client is allowed to follow the OAuth protocol when interacting with Cognito User Pools.
723 |
724 | - [**`default_client_generate_secret`**](#var-default_client_generate_secret): *(Optional `bool`)*
725 |
726 | Boolean flag for generating an application secret.
727 |
728 | - [**`default_client_allowed_oauth_flows`**](#var-default_client_allowed_oauth_flows): *(Optional `list(string)`)*
729 |
730 | List of allowed OAuth flows. Possible flows are `code`, `implicit`, and `client_credentials`.
731 |
732 | - [**`default_client_write_attributes`**](#var-default_client_write_attributes): *(Optional `list(string)`)*
733 |
734 | List of Cognito User Pool attributes the application client can write to.
735 |
736 | - [**`default_client_explicit_auth_flows`**](#var-default_client_explicit_auth_flows): *(Optional `list(string)`)*
737 |
738 | List of authentication flows. Possible values are `ADMIN_NO_SRP_AUTH`, `CUSTOM_AUTH_FLOW_ONLY`, `USER_PASSWORD_AUTH`, `ALLOW_ADMIN_USER_PASSWORD_AUTH`, `ALLOW_CUSTOM_AUTH`, `ALLOW_USER_PASSWORD_AUTH`, `ALLOW_USER_SRP_AUTH`, and `ALLOW_REFRESH_TOKEN_AUTH`.
739 |
740 | - [**`default_client_prevent_user_existence_errors`**](#var-default_client_prevent_user_existence_errors): *(Optional `string`)*
741 |
742 | Choose which errors and responses are returned by Cognito APIs during authentication, account confirmation, and password recovery when the user does not exist in the Cognito User Pool. When set to `ENABLED` and the user does not exist, authentication returns an error indicating either the username or password was incorrect, and account confirmation and password recovery return a response indicating a code was sent to a simulated destination. When set to `LEGACY`, those APIs will return a `UserNotFoundException` exception if the user does not exist in the Cognito User Pool.
743 |
744 | - [**`default_client_access_token_validity`**](#var-default_client_access_token_validity): *(Optional `number`)*
745 |
746 | Time limit, between 5 minutes and 1 day, after which the access token is no longer valid and cannot be used.
747 | This value will be overridden if you have entered a value in 'default_client_token_validity_units'.
748 |
749 | - [**`default_client_id_token_validity`**](#var-default_client_id_token_validity): *(Optional `number`)*
750 |
751 | Time limit, between 5 minutes and 1 day, after which the ID token is no longer valid and cannot be used.
752 | This value will be overridden if you have entered a value in 'default_client_token_validity_units'.
753 |
754 | - [**`default_client_token_validity_units`**](#var-default_client_token_validity_units): *(Optional `number`)*
755 |
756 | Configuration block for units in which the validity times are represented in.
757 |
758 | - [**`default_client_enable_token_revocation`**](#var-default_client_enable_token_revocation): *(Optional `bool`)*
759 |
760 | Enables or disables token revocation.
761 |
762 | ## Module Outputs
763 |
764 | The following attributes are exported by the module:
765 |
766 | - [**`user_pool`**](#output-user_pool): *(`object(user_pool)`)*
767 |
768 | The `cognito_user_pool` object.
769 |
770 | - [**`domain`**](#output-domain): *(`object(domain)`)*
771 |
772 | The full `aws_cognito_user_pool` object.
773 |
774 | - [**`clients`**](#output-clients): *(`map(client)`)*
775 |
776 | A map of `cognito_user_pool_client` objects. The map is keyed by the
777 | `name` of the created clients. Client secrets are filtered out of this
778 | map and are available through the `client_secrets` output variable and
779 | flagged as sensitive.
780 |
781 | - [**`client_secrets`**](#output-client_secrets): *(`map(client_secret)`)*
782 |
783 | A sensitive map of client secrets for all created
784 | `cognito_user_pool_client` resources. The map is keyed by the `name` of
785 | the created clients.
786 |
787 | - [**`module_enabled`**](#output-module_enabled): *(`bool`)*
788 |
789 | Whether this module is enabled.
790 |
791 | ## External Documentation
792 |
793 | ### AWS Documentation
794 |
795 | - https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html
796 | - https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html
797 |
798 | ### Terraform AWS Provider Documentation
799 |
800 | - User Pool - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool
801 | - User Pool Client - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool_client
802 | - User Pool Domain - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool_domain
803 | - Resource Server - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_resource_server
804 |
805 | ## Module Versioning
806 |
807 | This Module follows the principles of [Semantic Versioning (SemVer)].
808 |
809 | Given a version number `MAJOR.MINOR.PATCH`, we increment the:
810 |
811 | 1. `MAJOR` version when we make incompatible changes,
812 | 2. `MINOR` version when we add functionality in a backwards compatible manner, and
813 | 3. `PATCH` version when we make backwards compatible bug fixes.
814 |
815 | ### Backwards compatibility in `0.0.z` and `0.y.z` version
816 |
817 | - Backwards compatibility in versions `0.0.z` is **not guaranteed** when `z` is increased. (Initial development)
818 | - Backwards compatibility in versions `0.y.z` is **not guaranteed** when `y` is increased. (Pre-release)
819 |
820 | ## About Mineiros
821 |
822 | [Mineiros][homepage] is a remote-first company headquartered in Berlin, Germany
823 | that solves development, automation and security challenges in cloud infrastructure.
824 |
825 | Our vision is to massively reduce time and overhead for teams to manage and
826 | deploy production-grade and secure cloud infrastructure.
827 |
828 | We offer commercial support for all of our modules and encourage you to reach out
829 | if you have any questions or need help. Feel free to email us at [hello@mineiros.io] or join our
830 | [Community Slack channel][slack].
831 |
832 | ## Reporting Issues
833 |
834 | We use GitHub [Issues] to track community reported issues and missing features.
835 |
836 | ## Contributing
837 |
838 | Contributions are always encouraged and welcome! For the process of accepting changes, we use
839 | [Pull Requests]. If you'd like more information, please see our [Contribution Guidelines].
840 |
841 | ## Makefile Targets
842 |
843 | This repository comes with a handy [Makefile].
844 | Run `make help` to see details on each available target.
845 |
846 | ## License
847 |
848 | [![license][badge-license]][apache20]
849 |
850 | This module is licensed under the Apache License Version 2.0, January 2004.
851 | Please see [LICENSE] for full details.
852 |
853 | Copyright © 2020-2022 [Mineiros GmbH][homepage]
854 |
855 |
856 |
857 |
858 | [homepage]: https://mineiros.io/?ref=terraform-aws-cognito-user-pool
859 | [mineiros-library]: https://www.mineiros.io/solutions/terraform-library
860 | [mineiros-pricing]: https://www.mineiros.io/solutions/terraform-library#pricing
861 | [hello@mineiros.io]: mailto:hello@mineiros.io
862 | [badge-build]: https://github.com/mineiros-io/terraform-aws-lambda-function/workflows/CI/CD%20Pipeline/badge.svg
863 | [badge-semver]: https://img.shields.io/github/v/tag/mineiros-io/terraform-aws-cognito-user-pool.svg?label=latest&sort=semver
864 | [badge-license]: https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg
865 | [badge-terraform]: https://img.shields.io/badge/terraform-1.x%20|%200.15%20|%200.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform
866 | [badge-slack]: https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack
867 | [build-status]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/actions
868 | [badge-tf-aws]: https://img.shields.io/badge/AWS-3.19+-F8991D.svg?logo=terraform
869 | [releases-aws-provider]: https://github.com/terraform-providers/terraform-provider-aws/releases
870 | [releases-github]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/releases
871 | [releases-terraform]: https://github.com/hashicorp/terraform/releases
872 | [apache20]: https://opensource.org/licenses/Apache-2.0
873 | [slack]: https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg
874 | [Terraform]: https://www.terraform.io
875 | [AWS]: https://aws.amazon.com/
876 | [Semantic Versioning (SemVer)]: https://semver.org/
877 | [examples/example/main.tf]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/examples/example/main.tf
878 | [variables.tf]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/variables.tf
879 | [examples/]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/examples
880 | [Issues]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/issues
881 | [LICENSE]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/LICENSE
882 | [Makefile]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/Makefile
883 | [Pull Requests]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/pulls
884 | [Contribution Guidelines]: https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/CONTRIBUTING.md
885 | [Cognito User Pools]: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html
886 | [attributes docs]: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html
887 | [Terraform AWS Cognito User Pool Client Docs]: https://www.terraform.io/docs/providers/aws/r/cognito_user_pool_client.html
888 | [Terraform AWS Cognito Resource Server Docs]: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_resource_server
889 |
--------------------------------------------------------------------------------
/README.tfdoc.hcl:
--------------------------------------------------------------------------------
1 | header {
2 | image = "https://raw.githubusercontent.com/mineiros-io/brand/3bffd30e8bdbbde32c143e2650b2faa55f1df3ea/mineiros-primary-logo.svg"
3 | url = "https://mineiros.io/?ref=terraform-aws-cognito-user-pool"
4 |
5 | badge "build" {
6 | image = "https://github.com/mineiros-io/terraform-aws-cognito-user-pool/workflows/CI/CD%20Pipeline/badge.svg"
7 | url = "https://github.com/mineiros-io/terraform-aws-cognito-user-pool/actions"
8 | text = "Build Status"
9 | }
10 |
11 | badge "semver" {
12 | image = "https://img.shields.io/github/v/tag/mineiros-io/terraform-aws-cognito-user-pool.svg?label=latest&sort=semver"
13 | url = "https://github.com/mineiros-io/terraform-aws-cognito-user-pool/releases"
14 | text = "GitHub tag (latest SemVer)"
15 | }
16 |
17 | badge "terraform" {
18 | image = "https://img.shields.io/badge/terraform-1.x%20|%200.15%20|%200.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform"
19 | url = "https://github.com/hashicorp/terraform/releases"
20 | text = "Terraform Version"
21 | }
22 |
23 | badge "tf-aws-provider" {
24 | image = "https://img.shields.io/badge/AWS-3.50+-F8991D.svg?logo=terraform"
25 | url = "https://github.com/terraform-providers/terraform-provider-aws/releases"
26 | text = "AWS Provider Version"
27 | }
28 |
29 | badge "slack" {
30 | image = "https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack"
31 | url = "https://mineiros.io/slack"
32 | text = "Join Slack"
33 | }
34 | }
35 |
36 | section {
37 | title = "terraform-aws-cognito-user-pool"
38 | toc = true
39 | content = <<-END
40 | A [Terraform] module for deploying and managing
41 | [Cognito User Pools]
42 | on [Amazon Web Services (AWS)][AWS].
43 |
44 | *This module supports Terraform v1.x, v0.15, v0.14, v0.13 as well as v0.12.20 and above
45 | and is compatible with the Terraform AWS provider v3.50 and above.
46 | END
47 |
48 | section {
49 | title = "Module Features"
50 | content = <<-END
51 | In contrast to the plain [`cognito_user_pool`](https://www.terraform.io/docs/providers/aws/r/cognito_user_pool.html)
52 | resource this module has a more secure level of default settings.
53 |
54 | While all settings can be customized as needed, best practices are
55 | pre-configured.
56 |
57 | - **Default Security Settings**:
58 | Per default, only administrators are allowed to create user profiles by
59 | setting `allow_admin_create_user_only` to `true`. This module comes with a
60 | strong default password policy.
61 |
62 | **Standard Cognito Features**:
63 | Create a Cognito User Pool with pre-configured best practices.
64 | Create Cognito User Pool Clients.
65 | Create a Cognito User Pool Domain.
66 | Create Cognito User Pool Resource Servers as associated scopes.
67 |
68 | - *Features not yet implemented*:
69 | [`cognito_user_group`](https://www.terraform.io/docs/providers/aws/r/cognito_user_group.html)
70 | END
71 | }
72 |
73 | section {
74 | title = "Getting Started"
75 | content = <<-END
76 | Most basic usage just setting required arguments:
77 |
78 | ```hcl
79 | module "terraform-aws-cognito-user-pool" {
80 | source = "mineiros-io/cognito-user-pool/aws"
81 | version = "~> 0.9.0"
82 |
83 | name = "application-userpool"
84 | }
85 | ```
86 |
87 | Advanced usage as found in
88 | [examples/complete/main.tf](https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/examples/complete/main.tf)
89 | setting all required and optional arguments to their default values.
90 | END
91 | }
92 |
93 | section {
94 | title = "Module Argument Reference"
95 | content = <<-END
96 | See
97 | [variables.tf](https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/variables.tf)
98 | and
99 | [examples/](https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/examples)
100 | for details and use-cases.
101 | END
102 |
103 | section {
104 | title = "Top-level Arguments"
105 |
106 | section {
107 | title = "Module Configuration"
108 |
109 | variable "module_enabled" {
110 | type = bool
111 | default = true
112 | description = <<-END
113 | Specifies whether resources in the module will be created.
114 | END
115 | }
116 |
117 | variable "module_tags" {
118 | type = map(string)
119 | default = {}
120 | description = <<-END
121 | A map of tags that will be applied to all created resources that accept tags. Tags defined with 'module_tags' can be overwritten by resource-specific tags.
122 | END
123 | readme_example = <<-END
124 | module_tags = {
125 | environment = "staging"
126 | team = "platform"
127 | }
128 | END
129 | }
130 |
131 | variable "module_depends_on" {
132 | type = list(dependency)
133 | description = <<-END
134 | A list of dependencies. Any object can be _assigned_ to this list to define a hidden external dependency.
135 | END
136 | readme_example = <<-END
137 | module_depends_on = [
138 | aws_vpc.vpc
139 | ]
140 | END
141 | }
142 | }
143 |
144 | section {
145 | title = "Cognito User Pool"
146 |
147 | variable "name" {
148 | required = true
149 | type = string
150 | description = <<-END
151 | The name of the user pool. Forces new resource.
152 | END
153 | }
154 |
155 | variable "advanced_security_mode" {
156 | type = string
157 | default = "OFF"
158 | description = <<-END
159 | The mode for advanced security, must be one of `OFF`, `AUDIT` or `ENFORCED`. Additional pricing applies for Amazon Cognito advanced security features. For details see https://aws.amazon.com/cognito/pricing/.
160 | END
161 | }
162 |
163 | variable "alias_attributes" {
164 | type = set(string)
165 | description = <<-END
166 | Attributes supported as an alias for this user pool. Possible values: `phone_number`, `email`, or `preferred_username`. Conflicts with `username_attributes`. Default applies if `username_attributes` is not set.
167 | END
168 | }
169 |
170 | variable "username_attributes" {
171 | type = set(string)
172 | description = <<-END
173 | Specifies whether `email` addresse or `phone_number` can be specified as usernames when a user signs up. Conflicts with `alias_attributes`.
174 | Default is to use `alias_attributes`.
175 | END
176 | }
177 |
178 | variable "allow_admin_create_user_only" {
179 | type = bool
180 | default = true
181 | description = <<-END
182 | Set to True if only the administrator is allowed to create user profiles. Set to False if users can sign themselves up via an app.
183 | END
184 | }
185 |
186 | variable "invite_email_subject" {
187 | type = string
188 | default = "Your new account."
189 | description = <<-END
190 | The message template for email messages.
191 | END
192 | }
193 |
194 | variable "invite_email_message" {
195 | type = string
196 | default = "Your username is {username} and your temporary password is ' {####}'"
197 | description = <<-END
198 | The message template for email messages. Must contain `{username}` and `{####}` placeholders, for username and temporary password, respectively.
199 | END
200 | }
201 |
202 | variable "invite_sms_message" {
203 | type = string
204 | default = "Your username is {username} and your temporary password is ' {####}'."
205 | description = <<-END
206 | The message template for SMS messages. Must contain `{username}` and `{####}` placeholders, for username and temporary password, respectively.
207 | END
208 | }
209 |
210 | variable "auto_verified_attributes" {
211 | type = set(string)
212 | default = ["email"]
213 | description = <<-END
214 | The attributes to be auto-verified. Possible values: `email`, `phone_number`.
215 | END
216 | }
217 |
218 | variable "user_device_tracking" {
219 | type = string
220 | default = "USER_OPT_IN"
221 | description = <<-END
222 | Configure tracking of user devices. Set to `OFF` to disable tracking, `ALWAYS` to track all devices or `USER_OPT_IN` to only track when user opts in.
223 | END
224 | }
225 |
226 | variable "challenge_required_on_new_device" {
227 | type = bool
228 | default = true
229 | description = <<-END
230 | Indicates whether a challenge is required on a new device. Only applicable to a new device. Only applied when `user_device_tracking` is enabled.
231 | END
232 | }
233 |
234 | variable "enable_username_case_sensitivity" {
235 | type = bool
236 | default = false
237 | description = <<-END
238 | Specifies whether username case sensitivity will be applied to all users in the user pool through Cognito APIs.
239 | END
240 | }
241 |
242 | variable "email_sending_account" {
243 | type = string
244 | default = "COGNITO_DEFAULT"
245 | description = <<-END
246 | The email delivery method to use. `COGNITO_DEFAULT` for the default email functionality built into Cognito or `DEVELOPER` to use your Amazon SES configuration.
247 | END
248 | }
249 |
250 | variable "email_reply_to_address" {
251 | type = string
252 | description = <<-END
253 | The REPLY-TO email address.
254 | END
255 | }
256 |
257 | variable "email_source_arn" {
258 | type = string
259 | description = <<-END
260 | The ARN of the email source.
261 | END
262 | }
263 |
264 | variable "email_from_address" {
265 | type = string
266 | description = <<-END
267 | Sender’s email address or sender’s name with their email address (e.g. 'john@smith.com' or 'John Smith ').
268 | END
269 | }
270 |
271 | variable "mfa_configuration" {
272 | type = string
273 | default = "OPTIONAL"
274 | description = <<-END
275 | Multi-Factor Authentication (MFA) configuration for the User Pool. Valid values: `ON`, `OFF` or `OPTIONAL`. `ON` and `OPTIONAL` require at least one of `sms_configuration` or `software_token_mfa_configuration` to be configured.
276 | END
277 | }
278 |
279 | variable "password_minimum_length" {
280 | type = number
281 | default = 20
282 | description = <<-END
283 | The minimum length of the password policy that you have set.
284 | END
285 | }
286 |
287 | variable "password_require_lowercase" {
288 | type = bool
289 | default = true
290 | description = <<-END
291 | Whether you have required users to use at least one lowercase letter in their password.
292 | END
293 | }
294 |
295 | variable "password_require_numbers" {
296 | type = bool
297 | default = true
298 | description = <<-END
299 | Whether you have required users to use at least one number in their password.
300 | END
301 | }
302 |
303 | variable "password_require_symbols" {
304 | type = bool
305 | default = true
306 | description = <<-END
307 | Whether you have required users to use at least one symbol in their password.
308 | END
309 | }
310 |
311 | variable "password_require_uppercase" {
312 | type = bool
313 | default = true
314 | description = <<-END
315 | Whether you have required users to use at least one uppercase letter in their password.
316 | END
317 | }
318 |
319 | variable "temporary_password_validity_days" {
320 | type = number
321 | default = 1
322 | description = <<-END
323 | In the password policy you have set, refers to the number of days a temporary password is valid. If the user does not sign in during this time, their password will need to be reset by an administrator.
324 | END
325 | }
326 |
327 | variable "allow_software_mfa_token" {
328 | type = bool
329 | default = true
330 | description = <<-END
331 | Boolean whether to enable software token Multi-Factor Authentication (MFA) tokens, such as Time-Based One-Time Password (TOTP). To disable software token MFA when `sms_configuration` is not present, the `mfa_configuration` argument must be set to `OFF` and the `software_token_mfa_configuration` configuration block must be fully removed.
332 | END
333 | }
334 |
335 | variable "sms_authentication_message" {
336 | type = string
337 | default = "Your temporary password is {####}."
338 | description = <<-END
339 | A string representing the SMS authentication message. The message must contain the `{####}` placeholder, which will be replaced with the authentication code.
340 | END
341 | }
342 |
343 | variable "lambda_create_auth_challenge" {
344 | type = string
345 | description = <<-END
346 | The ARN of an AWS Lambda creating an authentication challenge.
347 | END
348 | }
349 |
350 | variable "lambda_custom_message" {
351 | type = string
352 | description = <<-END
353 | The ARN of a custom message AWS Lambda trigger.
354 | END
355 | }
356 |
357 | variable "lambda_define_auth_challenge" {
358 | type = string
359 | description = <<-END
360 | The ARN of an AWS Lambda that defines the authentication challenge.
361 | END
362 | }
363 |
364 | variable "lambda_post_authentication" {
365 | type = string
366 | description = <<-END
367 | The ARN of an AWS Lambda that defines the authentication challenge.
368 | END
369 | }
370 |
371 | variable "lambda_post_confirmation" {
372 | type = string
373 | description = <<-END
374 | The ARN of a post-confirmation AWS Lambda trigger.
375 | END
376 | }
377 |
378 | variable "lambda_pre_authentication" {
379 | type = string
380 | description = <<-END
381 | The ARN of a pre-authentication AWS Lambda trigger.
382 | END
383 | }
384 |
385 | variable "lambda_pre_sign_up" {
386 | type = string
387 | description = <<-END
388 | The ARN of a pre-registration AWS Lambda trigger.
389 | END
390 | }
391 |
392 | variable "lambda_pre_token_generation" {
393 | type = string
394 | description = <<-END
395 | The ARN of an AWS Lambda that allows customization of identity token claims before token generation.
396 | END
397 | }
398 |
399 | variable "lambda_user_migration" {
400 | type = string
401 | description = <<-END
402 | The ARN of he user migration AWS Lambda config type.
403 | END
404 | }
405 |
406 | variable "lambda_verify_auth_challenge_response" {
407 | type = string
408 | default = "true"
409 | description = <<-END
410 | The ARN of an AWS Lambda that verifies the authentication challenge response.
411 | END
412 | }
413 |
414 | variable "schema_attributes" {
415 | type = list(schema_attribute)
416 | default = []
417 | description = <<-END
418 | A list of schema attributes of a user pool. You can add a maximum of 25 custom attributes. Please note that only default attributes can be marked as required.
419 | Also an attribute cannot be switched between required and not required after a user pool has been created.
420 | For details please see the [attributes docs].
421 | END
422 | readme_example = <<-END
423 | schema_attributes = [
424 | {
425 | name = "gender", # overwrites the default attribute 'gender'
426 | type = "String"
427 | required = true # required can only be set for default attributes
428 | },
429 | {
430 | name = "alternative_name"
431 | type = "String"
432 | min_length = 0,
433 | max_length = 2048
434 | },
435 | {
436 | name = "friends_count"
437 | type = "Number"
438 | min_value = 0,
439 | max_value = 100
440 | },
441 | {
442 | name = "is_active"
443 | type = "Boolean"
444 | },
445 | {
446 | name = "last_seen"
447 | type = "DateTime"
448 | }
449 | ]
450 | END
451 | }
452 |
453 | variable "account_recovery_mechanisms" {
454 | type = list(account_recovery_mechanism)
455 | default = []
456 | description = <<-END
457 | A list of recovery_mechanisms to be inserted inside `account_recovery_setting`.
458 | END
459 | readme_example = <<-END
460 | account_recovery_mechanisms = [
461 | {
462 | name = "verified_email"
463 | priority = 1
464 | },
465 | {
466 | name = "verified_phone_number"
467 | priority = 2
468 | }
469 | ]
470 | END
471 |
472 | attribute "name" {
473 | required = true
474 | type = string
475 | description = <<-END
476 | Recovery method for a user. Can be of the following: verified_email, verified_phone_number, and admin_only.
477 | END
478 | }
479 |
480 | attribute "priority" {
481 | required = true
482 | type = string
483 | description = <<-END
484 | Positive integer specifying priority of a method with 1 being the highest priority.
485 | END
486 | }
487 | }
488 |
489 | variable "sms_configuration" {
490 | type = object(sms_configuration)
491 | description = <<-END
492 | The `sms_configuration` with the `external_id` parameter used in IAM role trust relationships and the `sns_caller_arn` parameter to set the ARN of the Amazon SNS caller. This is usually the IAM role that you have given AWS Cognito permission to assume.
493 | END
494 |
495 | attribute "external_id" {
496 | required = true
497 | type = string
498 | description = <<-END
499 | External ID used in IAM role trust relationships.
500 | END
501 | }
502 |
503 | attribute "sns_caller_arn" {
504 | required = true
505 | type = string
506 | description = <<-END
507 | ARN of the Amazon SNS caller. This is usually the IAM role that you've given Cognito permission to assume.
508 | END
509 | }
510 | }
511 |
512 | variable "default_email_option" {
513 | type = string
514 | default = "CONFIRM_WITH_CODE"
515 | description = <<-END
516 | The default email option. Must be either `CONFIRM_WITH_CODE` or `CONFIRM_WITH_LINK`.
517 | END
518 | }
519 |
520 | variable "email_message" {
521 | type = string
522 | default = "Your verification code is {####}."
523 | description = <<-END
524 | The email message template. Must contain the `{####}` placeholder.
525 | END
526 | }
527 |
528 | variable "email_message_by_link" {
529 | type = string
530 | default = "Please click the link below to verify your email address.{##Verify Email##}."
531 | description = <<-END
532 | The email message template for sending a confirmation link to the user, it must contain the `{##Any Text##}` placeholder.
533 | END
534 | }
535 |
536 | variable "email_subject" {
537 | type = string
538 | default = "Your Verification Code"
539 | description = <<-END
540 | The subject line for the email message template.
541 | END
542 | }
543 |
544 | variable "email_subject_by_link" {
545 | type = string
546 | default = "Your Verifiction Link"
547 | description = <<-END
548 | The subject line for the email message template for sending a confirmation link to the user.
549 | END
550 | }
551 |
552 | variable "sms_message" {
553 | type = string
554 | default = "Your verification code is {####}."
555 | description = <<-END
556 | The SMS message template. Must contain the `{####}` placeholder, which will be replaced with the verification code. Can also contain the `{username}` placeholder which will be replaced with the username.
557 | END
558 | }
559 |
560 | variable "tags" {
561 | type = map(string)
562 | default = {}
563 | description = <<-END
564 | A mapping of tags to assign to the resource.
565 | END
566 | readme_example = <<-END
567 | tags = {
568 | CreatedAt = "2020-02-07",
569 | Alice = "Bob"
570 | }
571 | END
572 | }
573 | }
574 |
575 | section {
576 | title = "Cognito User Pool Domain"
577 |
578 | variable "domain" {
579 | type = string
580 | description = <<-END
581 | The domain name that should be used. Can be set to a FQDN or prefix.
582 | If no FQDN and `certificate_arn` are set, the domain prefix will be used for the sign-up and sign-in pages that are hosted by Amazon Cognito,
583 | e.g. `https://{YOUR_PREFIX}.auth.eu-west-1.amazoncognito.com`.
584 | The prefix must be unique across the selected AWS Region.
585 | Domain names can only contain lower-case letters, numbers, and hyphens.
586 | END
587 | }
588 |
589 | variable "certificate_arn" {
590 | type = string
591 | description = <<-END
592 | The ARN of an ISSUED ACM certificate in us-east-1 for a custom domain.
593 | END
594 | }
595 | }
596 |
597 | section {
598 | title = "Cognito User Pool Resource Servers"
599 |
600 | variable "resource_servers" {
601 | type = list(resource_server)
602 | default = []
603 | description = <<-END
604 | A list of objects with resource server declarations.
605 | END
606 | readme_example = <<-END
607 | resource_servers = [
608 | {
609 | identifier = "https://api.resourceserver.com"
610 | name = "API"
611 | scopes = [
612 | {
613 | scope_name = "users:read"
614 | scope_description = "Read user data"
615 | },
616 | {
617 | scope_name = "users:write"
618 | scope_description = "Write user data"
619 | }
620 | ]
621 | }
622 | ]
623 | END
624 |
625 | attribute "identifier" {
626 | required = true
627 | type = string
628 | description = <<-END
629 | An identifier for the resource server.
630 | END
631 | }
632 |
633 | attribute "name" {
634 | required = true
635 | type = string
636 | description = <<-END
637 | A name for the resource server.
638 | END
639 | }
640 |
641 | attribute "scope" {
642 | type = list(scope)
643 | description = <<-END
644 | A list of Authorization Scope.
645 | END
646 |
647 | attribute "scope_name" {
648 | required = true
649 | type = string
650 | description = <<-END
651 | The scope name.
652 | END
653 | }
654 |
655 | attribute "scope_description" {
656 | required = true
657 | type = string
658 | description = <<-END
659 | The scope description.
660 | END
661 | }
662 | }
663 | }
664 | }
665 |
666 | section {
667 | title = "Cognito User Pool Clients"
668 |
669 | variable "clients" {
670 | type = list(client)
671 | default = []
672 | description = <<-END
673 | A list of objects with the clients definitions.
674 | END
675 | readme_example = <<-END
676 | clients = [
677 | {
678 | name = "android-mobile-client"
679 | read_attributes = ["email", "email_verified", "preferred_username"]
680 | allowed_oauth_scopes = ["email", "openid"]
681 | allowed_oauth_flows = ["implicit"]
682 | callback_urls = ["https://mineiros.io/callback", "https://mineiros.io/anothercallback"]
683 | default_redirect_uri = "https://mineiros.io/callback"
684 | generate_secret = true
685 | }
686 | ]
687 | END
688 |
689 | attribute "name" {
690 | required = true
691 | type = string
692 | description = <<-END
693 | Name of the application client.
694 | END
695 | }
696 |
697 | attribute "user_pool_id" {
698 | type = string
699 | description = <<-END
700 | Name of the application client.
701 | END
702 | }
703 |
704 | attribute "access_token_validity" {
705 | type = number
706 | description = <<-END
707 | Time limit, between 5 minutes and 1 day, after which the access token is no longer valid and cannot be used. This value will be overridden if you have entered a value in token_validity_units.
708 | END
709 | }
710 |
711 | attribute "allowed_oauth_flows_user_pool_client" {
712 | type = bool
713 | description = <<-END
714 | Whether the client is allowed to follow the OAuth protocol when interacting with Cognito user pools.
715 | END
716 | }
717 |
718 | attribute "allowed_oauth_flows" {
719 | type = set(string)
720 | description = <<-END
721 | List of allowed OAuth flows (code, implicit, client_credentials).
722 | END
723 | }
724 |
725 | attribute "allowed_oauth_scopes" {
726 | type = set(string)
727 | description = <<-END
728 | List of allowed OAuth scopes (phone, email, openid, profile, and aws.cognito.signin.user.admin).
729 | END
730 | }
731 |
732 | attribute "analytics_configuration" {
733 | type = object(analytics_configuration)
734 | description = <<-END
735 | Configuration block for Amazon Pinpoint analytics for collecting metrics for this user pool.
736 | END
737 |
738 | attribute "application_arn" {
739 | type = string
740 | description = <<-END
741 | Application ARN for an Amazon Pinpoint application. Conflicts with external_id and role_arn.
742 | END
743 | }
744 |
745 | attribute "application_id" {
746 | type = string
747 | description = <<-END
748 | Application ID for an Amazon Pinpoint application.
749 | END
750 | }
751 |
752 | attribute "external_id" {
753 | type = string
754 | description = <<-END
755 | ID for the Analytics Configuration. Conflicts with application_arn. Application ID for an Amazon Pinpoint application.
756 | END
757 | }
758 |
759 | attribute "role_arn" {
760 | type = string
761 | description = <<-END
762 | ARN of an IAM role that authorizes Amazon Cognito to publish events to Amazon Pinpoint analytics. Conflicts with application_arn.
763 | END
764 | }
765 |
766 | attribute "user_data_shared" {
767 | type = bool
768 | description = <<-END
769 | If set to true, Amazon Cognito will include user data in the events it publishes to Amazon Pinpoint analytics.
770 | END
771 | }
772 | }
773 |
774 | attribute "callback_urls" {
775 | type = set(string)
776 | description = <<-END
777 | List of allowed callback URLs for the identity providers.
778 | END
779 | }
780 |
781 | attribute "default_redirect_uri" {
782 | type = string
783 | description = <<-END
784 | Default redirect URI. Must be in the list of callback URLs.
785 | END
786 | }
787 |
788 | attribute "enable_token_revocation" {
789 | type = bool
790 | description = <<-END
791 | Enables or disables token revocation.
792 | END
793 | }
794 |
795 | attribute "explicit_auth_flows" {
796 | type = set(string)
797 | description = <<-END
798 | List of authentication flows (ADMIN_NO_SRP_AUTH, CUSTOM_AUTH_FLOW_ONLY, USER_PASSWORD_AUTH, ALLOW_ADMIN_USER_PASSWORD_AUTH, ALLOW_CUSTOM_AUTH, ALLOW_USER_PASSWORD_AUTH, ALLOW_USER_SRP_AUTH, ALLOW_REFRESH_TOKEN_AUTH).
799 | END
800 | }
801 |
802 | attribute "generate_secret" {
803 | type = bool
804 | description = <<-END
805 | Should an application secret be generated.
806 | END
807 | }
808 |
809 | attribute "id_token_validity" {
810 | type = number
811 | description = <<-END
812 | Time limit, between 5 minutes and 1 day, after which the ID token is no longer valid and cannot be used. This value will be overridden if you have entered a value in token_validity_units.
813 | END
814 | }
815 |
816 | attribute "logout_urls" {
817 | type = set(string)
818 | description = <<-END
819 | List of allowed logout URLs for the identity providers.
820 | END
821 | }
822 |
823 | attribute "prevent_user_existence_errors" {
824 | type = string
825 | description = <<-END
826 | Choose which errors and responses are returned by Cognito APIs during authentication, account confirmation, and password recovery when the user does not exist in the user pool. When set to ENABLED and the user does not exist, authentication returns an error indicating either the username or password was incorrect, and account confirmation and password recovery return a response indicating a code was sent to a simulated destination. When set to LEGACY, those APIs will return a UserNotFoundException exception if the user does not exist in the user pool.
827 | END
828 | }
829 |
830 | attribute "read_attributes" {
831 | type = set(string)
832 | description = <<-END
833 | List of user pool attributes the application client can read from.
834 | END
835 | }
836 |
837 | attribute "refresh_token_validity" {
838 | type = number
839 | description = <<-END
840 | Time limit in days refresh tokens are valid for.
841 | END
842 | }
843 |
844 | attribute "supported_identity_providers" {
845 | type = set(string)
846 | description = <<-END
847 | List of provider names for the identity providers that are supported on this client. Uses the provider_name attribute of aws_cognito_identity_provider resource(s), or the equivalent string(s).
848 | END
849 | }
850 |
851 | attribute "token_validity_units" {
852 | type = object(token_validity_units)
853 | description = <<-END
854 | Configuration block for units in which the validity times are represented in.
855 | END
856 |
857 | attribute "access_token" {
858 | type = string
859 | default = "hours"
860 | description = <<-END
861 | Time unit in for the value in access_token_validity, defaults to hours.
862 | END
863 | }
864 |
865 | attribute "id_token" {
866 | type = string
867 | default = "hours"
868 | description = <<-END
869 | Time unit in for the value in id_token_validity, defaults to hours.
870 | END
871 | }
872 |
873 | attribute "refresh_token" {
874 | type = string
875 | default = "days"
876 | description = <<-END
877 | Time unit in for the value in refresh_token_validity, defaults to days.
878 | END
879 | }
880 | }
881 |
882 | attribute "write_attributes" {
883 | type = set(string)
884 | description = <<-END
885 | List of user pool attributes the application client can write to.
886 | END
887 | }
888 | }
889 | }
890 |
891 | section {
892 | title = "Cognito User Pool Clients Default Values"
893 | content = <<-END
894 | The following variables can be used for setting default settings among various clients defined through the `clients` variable. This helps you to quickly issue several clients that implement the same settings, e.g. like so:
895 |
896 | ```hcl
897 | clients = [
898 | { name = "ios" },
899 | { name = "android" },
900 | { name = "web" },
901 | ]
902 |
903 | default_client_read_attributes = ["email", "email_verified", "preferred_username"]
904 | default_client_allowed_oauth_scopes = ["email", "openid"]
905 | default_client_allowed_oauth_flows = ["implicit"]
906 | default_client_callback_urls = ["https://mineiros.io/callback", "https://mineiros.io/anothercallback"]
907 | default_client_default_redirect_uri = "https://mineiros.io/callback"
908 | default_client_generate_secret = true
909 | default_client_refresh_token_validity = 45
910 |
911 | default_client_supported_identity_providers = null
912 | default_client_logout_urls = null
913 | default_client_allowed_oauth_flows_user_pool_client = null
914 | default_client_write_attributes = null
915 | default_client_explicit_auth_flows = null
916 | default_client_prevent_user_existence_errors = null
917 | default_client_access_token_validity = null
918 | default_client_id_token_validity = null
919 | default_client_token_validity_units = null
920 | default_client_enable_token_revocation = null
921 | ```
922 | END
923 |
924 | variable "default_client_callback_urls" {
925 | type = list(string)
926 | description = <<-END
927 | List of allowed callback URLs for the identity providers.
928 | END
929 | }
930 |
931 | variable "default_client_default_redirect_uri" {
932 | type = string
933 | description = <<-END
934 | The default redirect URI. Must be in the list of callback URLs.
935 | END
936 | }
937 |
938 | variable "default_client_read_attributes" {
939 | type = list(string)
940 | description = <<-END
941 | List of Cognito User Pool attributes the application client can read from.
942 | END
943 | }
944 |
945 | variable "default_client_refresh_token_validity" {
946 | type = number
947 | description = <<-END
948 | The time limit in days refresh tokens are valid for.
949 | END
950 | default = 30
951 | }
952 |
953 | variable "default_client_supported_identity_providers" {
954 | type = list(string)
955 | description = <<-END
956 | List of provider names for the identity providers that are supported on this client.
957 | END
958 | }
959 |
960 | variable "default_client_allowed_oauth_scopes" {
961 | type = list(string)
962 | description = <<-END
963 | List of allowed OAuth scopes. Possible values are `phone`, `email`, `openid`, `profile`, and `aws.cognito.signin.user.admin`.
964 | END
965 | }
966 |
967 | variable "default_client_logout_urls" {
968 | type = list(string)
969 | description = <<-END
970 | List of allowed logout URLs for the identity providers.
971 | END
972 | }
973 |
974 | variable "default_client_allowed_oauth_flows_user_pool_client" {
975 | type = bool
976 | description = <<-END
977 | Whether the client is allowed to follow the OAuth protocol when interacting with Cognito User Pools.
978 | END
979 | }
980 |
981 | variable "default_client_generate_secret" {
982 | type = bool
983 | description = <<-END
984 | Boolean flag for generating an application secret.
985 | END
986 | }
987 |
988 | variable "default_client_allowed_oauth_flows" {
989 | type = list(string)
990 | description = <<-END
991 | List of allowed OAuth flows. Possible flows are `code`, `implicit`, and `client_credentials`.
992 | END
993 | }
994 |
995 | variable "default_client_write_attributes" {
996 | type = list(string)
997 | description = <<-END
998 | List of Cognito User Pool attributes the application client can write to.
999 | END
1000 | }
1001 |
1002 | variable "default_client_explicit_auth_flows" {
1003 | type = list(string)
1004 | description = <<-END
1005 | List of authentication flows. Possible values are `ADMIN_NO_SRP_AUTH`, `CUSTOM_AUTH_FLOW_ONLY`, `USER_PASSWORD_AUTH`, `ALLOW_ADMIN_USER_PASSWORD_AUTH`, `ALLOW_CUSTOM_AUTH`, `ALLOW_USER_PASSWORD_AUTH`, `ALLOW_USER_SRP_AUTH`, and `ALLOW_REFRESH_TOKEN_AUTH`.
1006 | END
1007 | }
1008 |
1009 | variable "default_client_prevent_user_existence_errors" {
1010 | type = string
1011 | description = <<-END
1012 | Choose which errors and responses are returned by Cognito APIs during authentication, account confirmation, and password recovery when the user does not exist in the Cognito User Pool. When set to `ENABLED` and the user does not exist, authentication returns an error indicating either the username or password was incorrect, and account confirmation and password recovery return a response indicating a code was sent to a simulated destination. When set to `LEGACY`, those APIs will return a `UserNotFoundException` exception if the user does not exist in the Cognito User Pool.
1013 | END
1014 | }
1015 |
1016 | variable "default_client_access_token_validity" {
1017 | type = number
1018 | description = <<-END
1019 | Time limit, between 5 minutes and 1 day, after which the access token is no longer valid and cannot be used.
1020 | This value will be overridden if you have entered a value in 'default_client_token_validity_units'.
1021 | END
1022 | }
1023 |
1024 | variable "default_client_id_token_validity" {
1025 | type = number
1026 | description = <<-END
1027 | Time limit, between 5 minutes and 1 day, after which the ID token is no longer valid and cannot be used.
1028 | This value will be overridden if you have entered a value in 'default_client_token_validity_units'.
1029 | END
1030 | }
1031 |
1032 | variable "default_client_token_validity_units" {
1033 | type = number
1034 | description = <<-END
1035 | Configuration block for units in which the validity times are represented in.
1036 | END
1037 | }
1038 |
1039 | variable "default_client_enable_token_revocation" {
1040 | type = bool
1041 | description = <<-END
1042 | Enables or disables token revocation.
1043 | END
1044 | }
1045 | }
1046 | }
1047 | }
1048 |
1049 | section {
1050 | title = "Module Outputs"
1051 | content = <<-END
1052 | The following attributes are exported by the module:
1053 | END
1054 |
1055 | output "user_pool" {
1056 | type = object(user_pool)
1057 | description = <<-END
1058 | The `cognito_user_pool` object.
1059 | END
1060 | }
1061 |
1062 | output "domain" {
1063 | type = object(domain)
1064 | description = <<-END
1065 | The full `aws_cognito_user_pool` object.
1066 | END
1067 | }
1068 |
1069 | output "clients" {
1070 | type = map(client)
1071 | description = <<-END
1072 | A map of `cognito_user_pool_client` objects. The map is keyed by the
1073 | `name` of the created clients. Client secrets are filtered out of this
1074 | map and are available through the `client_secrets` output variable and
1075 | flagged as sensitive.
1076 | END
1077 | }
1078 |
1079 | output "client_secrets" {
1080 | type = map(client_secret)
1081 | description = <<-END
1082 | A sensitive map of client secrets for all created
1083 | `cognito_user_pool_client` resources. The map is keyed by the `name` of
1084 | the created clients.
1085 | END
1086 | }
1087 |
1088 | output "module_enabled" {
1089 | type = bool
1090 | description = <<-END
1091 | Whether this module is enabled.
1092 | END
1093 | }
1094 | }
1095 |
1096 | section {
1097 | title = "External Documentation"
1098 |
1099 | section {
1100 | title = "AWS Documentation"
1101 |
1102 | content = <<-END
1103 | - https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html
1104 | - https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html
1105 | END
1106 | }
1107 |
1108 | section {
1109 | title = "Terraform AWS Provider Documentation"
1110 |
1111 | content = <<-END
1112 | - User Pool - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool
1113 | - User Pool Client - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool_client
1114 | - User Pool Domain - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool_domain
1115 | - Resource Server - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_resource_server
1116 | END
1117 | }
1118 | }
1119 |
1120 | section {
1121 | title = "Module Versioning"
1122 | content = <<-END
1123 | This Module follows the principles of [Semantic Versioning (SemVer)].
1124 |
1125 | Given a version number `MAJOR.MINOR.PATCH`, we increment the:
1126 |
1127 | 1. `MAJOR` version when we make incompatible changes,
1128 | 2. `MINOR` version when we add functionality in a backwards compatible manner, and
1129 | 3. `PATCH` version when we make backwards compatible bug fixes.
1130 | END
1131 |
1132 | section {
1133 | title = "Backwards compatibility in `0.0.z` and `0.y.z` version"
1134 | content = <<-END
1135 | - Backwards compatibility in versions `0.0.z` is **not guaranteed** when `z` is increased. (Initial development)
1136 | - Backwards compatibility in versions `0.y.z` is **not guaranteed** when `y` is increased. (Pre-release)
1137 | END
1138 | }
1139 | }
1140 |
1141 | section {
1142 | title = "About Mineiros"
1143 | content = <<-END
1144 | [Mineiros][homepage] is a remote-first company headquartered in Berlin, Germany
1145 | that solves development, automation and security challenges in cloud infrastructure.
1146 |
1147 | Our vision is to massively reduce time and overhead for teams to manage and
1148 | deploy production-grade and secure cloud infrastructure.
1149 |
1150 | We offer commercial support for all of our modules and encourage you to reach out
1151 | if you have any questions or need help. Feel free to email us at [hello@mineiros.io] or join our
1152 | [Community Slack channel][slack].
1153 | END
1154 | }
1155 |
1156 | section {
1157 | title = "Reporting Issues"
1158 | content = <<-END
1159 | We use GitHub [Issues] to track community reported issues and missing features.
1160 | END
1161 | }
1162 |
1163 | section {
1164 | title = "Contributing"
1165 | content = <<-END
1166 | Contributions are always encouraged and welcome! For the process of accepting changes, we use
1167 | [Pull Requests]. If you'd like more information, please see our [Contribution Guidelines].
1168 | END
1169 | }
1170 |
1171 | section {
1172 | title = "Makefile Targets"
1173 | content = <<-END
1174 | This repository comes with a handy [Makefile].
1175 | Run `make help` to see details on each available target.
1176 | END
1177 | }
1178 |
1179 | section {
1180 | title = "License"
1181 | content = <<-END
1182 | [![license][badge-license]][apache20]
1183 |
1184 | This module is licensed under the Apache License Version 2.0, January 2004.
1185 | Please see [LICENSE] for full details.
1186 |
1187 | Copyright © 2020-2022 [Mineiros GmbH][homepage]
1188 | END
1189 | }
1190 | }
1191 |
1192 | references {
1193 | ref "homepage" {
1194 | value = "https://mineiros.io/?ref=terraform-aws-cognito-user-pool"
1195 | }
1196 | ref "mineiros-library" {
1197 | value = "https://www.mineiros.io/solutions/terraform-library"
1198 | }
1199 | ref "mineiros-pricing" {
1200 | value = "https://www.mineiros.io/solutions/terraform-library#pricing"
1201 | }
1202 | ref "hello@mineiros.io" {
1203 | value = "mailto:hello@mineiros.io"
1204 | }
1205 | ref "badge-build" {
1206 | value = "https://github.com/mineiros-io/terraform-aws-lambda-function/workflows/CI/CD%20Pipeline/badge.svg"
1207 | }
1208 | ref "badge-semver" {
1209 | value = "https://img.shields.io/github/v/tag/mineiros-io/terraform-aws-cognito-user-pool.svg?label=latest&sort=semver"
1210 | }
1211 | ref "badge-license" {
1212 | value = "https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg"
1213 | }
1214 | ref "badge-terraform" {
1215 | value = "https://img.shields.io/badge/terraform-1.x%20|%200.15%20|%200.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform"
1216 | }
1217 | ref "badge-slack" {
1218 | value = "https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack"
1219 | }
1220 | ref "build-status" {
1221 | value = "https://github.com/mineiros-io/terraform-aws-cognito-user-pool/actions"
1222 | }
1223 | ref "badge-tf-aws" {
1224 | value = "https://img.shields.io/badge/AWS-3.19+-F8991D.svg?logo=terraform"
1225 | }
1226 | ref "releases-aws-provider" {
1227 | value = "https://github.com/terraform-providers/terraform-provider-aws/releases"
1228 | }
1229 | ref "releases-github" {
1230 | value = "https://github.com/mineiros-io/terraform-aws-cognito-user-pool/releases"
1231 | }
1232 | ref "releases-terraform" {
1233 | value = "https://github.com/hashicorp/terraform/releases"
1234 | }
1235 | ref "apache20" {
1236 | value = "https://opensource.org/licenses/Apache-2.0"
1237 | }
1238 | ref "slack" {
1239 | value = "https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg"
1240 | }
1241 | ref "Terraform" {
1242 | value = "https://www.terraform.io"
1243 | }
1244 | ref "AWS" {
1245 | value = "https://aws.amazon.com/"
1246 | }
1247 | ref "Semantic Versioning (SemVer)" {
1248 | value = "https://semver.org/"
1249 | }
1250 | ref "examples/example/main.tf" {
1251 | value = "https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/examples/example/main.tf"
1252 | }
1253 | ref "variables.tf" {
1254 | value = "https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/variables.tf"
1255 | }
1256 | ref "examples/" {
1257 | value = "https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/examples"
1258 | }
1259 | ref "Issues" {
1260 | value = "https://github.com/mineiros-io/terraform-aws-cognito-user-pool/issues"
1261 | }
1262 | ref "LICENSE" {
1263 | value = "https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/LICENSE"
1264 | }
1265 | ref "Makefile" {
1266 | value = "https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/Makefile"
1267 | }
1268 | ref "Pull Requests" {
1269 | value = "https://github.com/mineiros-io/terraform-aws-cognito-user-pool/pulls"
1270 | }
1271 | ref "Contribution Guidelines" {
1272 | value = "https://github.com/mineiros-io/terraform-aws-cognito-user-pool/blob/master/CONTRIBUTING.md"
1273 | }
1274 | ref "Cognito User Pools" {
1275 | value = "https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html"
1276 | }
1277 | ref "attributes docs" {
1278 | value = "https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html"
1279 | }
1280 | ref "Terraform AWS Cognito User Pool Client Docs" {
1281 | value = "https://www.terraform.io/docs/providers/aws/r/cognito_user_pool_client.html"
1282 | }
1283 | ref "Terraform AWS Cognito Resource Server Docs" {
1284 | value = "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_resource_server"
1285 | }
1286 | }
1287 |
--------------------------------------------------------------------------------