Skip to content

Commit

Permalink
v2.0.1 - Updated examples/generics
Browse files Browse the repository at this point in the history
  • Loading branch information
Zordrak committed Feb 12, 2025
1 parent 4d496e7 commit 7622c46
Show file tree
Hide file tree
Showing 171 changed files with 57,331 additions and 10 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.0.1 (12/02/2025)

* Updated included modules to follow new standard and include other generics

## 2.0.0 (02/12/2024)

BREAKING CHANGES:
Expand Down
2 changes: 2 additions & 0 deletions components/example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

| Name | Source | Version |
|------|--------|---------|
| <a name="module_kms_s3"></a> [kms\_s3](#module\_kms\_s3) | ../../modules/generic/kms | n/a |
| <a name="module_s3bucket_bestpractice"></a> [s3bucket\_bestpractice](#module\_s3bucket\_bestpractice) | ../../modules/generic/s3bucket | n/a |
| <a name="module_sns_something"></a> [sns\_something](#module\_sns\_something) | ../../modules/generic/sns | n/a |

## Resources
Expand Down
14 changes: 14 additions & 0 deletions components/example/module.kms_s3.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module "kms_s3" {
source = "../../modules/generic/kms"

aws = local.aws

unique_ids = {
local = "${local.unique_id}-kms-s3"
account = "${local.unique_id_account}-kms-s3"
}

alias = "alias/s3/${local.unique_id}"
create_policies = false
deletion_window = 30
}
13 changes: 13 additions & 0 deletions components/example/module.s3bucket_other.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module "s3bucket_bestpractice" {
source = "../../modules/generic/s3bucket"

aws = local.aws

unique_ids = {
global = "${local.unique_id_global}-bestpractice"
}

force_destroy = false

kms_key_arn = module.kms_s3.key_arn
}
61 changes: 61 additions & 0 deletions modules/generic/cognito/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<!-- BEGIN_TF_DOCS -->
## Requirements

No requirements.

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.85.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [aws_cognito_identity_provider.saml](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_identity_provider) | resource |
| [aws_cognito_user_pool.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool) | resource |
| [aws_cognito_user_pool_client.cognito](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool_client) | resource |
| [aws_cognito_user_pool_client.saml](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool_client) | resource |
| [aws_cognito_user_pool_domain.custom](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool_domain) | resource |
| [aws_cognito_user_pool_domain.prefix](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool_domain) | resource |
| [aws_cognito_user_pool_ui_customization.saml](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool_ui_customization) | resource |
| [aws_iam_role.cognito_user_pool_sms](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy.cognito_user_pool_sms](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_route53_record.alias_cognito_user_pool_domain_custom](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
| [aws_iam_policy_document.cognito_user_pool_admin_get_user](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.cognito_user_pool_assumerole](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.cognito_user_pool_manage](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.cognito_user_pool_read_create_entities](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.sns_publish_any](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_access_token_validity"></a> [access\_token\_validity](#input\_access\_token\_validity) | Access Token Validity | <pre>object({<br/> value = optional(number, 480)<br/> units = optional(string, "minutes")<br/> })</pre> | <pre>{<br/> "units": "minutes",<br/> "validity": 480<br/>}</pre> | no |
| <a name="input_allowed_oauth_scopes"></a> [allowed\_oauth\_scopes](#input\_allowed\_oauth\_scopes) | Allowed OAuth Scopes for Cognito | `list(string)` | <pre>[<br/> "openid",<br/> "email",<br/> "profile"<br/>]</pre> | no |
| <a name="input_app_fqdn"></a> [app\_fqdn](#input\_app\_fqdn) | Fully Qualified Domain Name for the App protected by Cognito | `string` | n/a | yes |
| <a name="input_aws"></a> [aws](#input\_aws) | n/a | <pre>object({<br/> account_id = string<br/> default_tags = optional(map(string), {})<br/> partition = optional(string, "aws")<br/> region = string<br/> url_suffix = optional(string, "amazonaws.com")<br/> })</pre> | n/a | yes |
| <a name="input_callback_urls"></a> [callback\_urls](#input\_callback\_urls) | Callback URLs for Cognito | `list(string)` | `[]` | no |
| <a name="input_custom_domain"></a> [custom\_domain](#input\_custom\_domain) | Optional FQDN & Route53 Public Hosted Zone ID for a custom Cognito User Pool Domain | <pre>object({<br/> cloudfront_acm_certificate_arn = string<br/> fqdn = string<br/> route53_public_hosted_zone_id = string<br/> })</pre> | `null` | no |
| <a name="input_explicit_auth_flows"></a> [explicit\_auth\_flows](#input\_explicit\_auth\_flows) | Explicit Auth Flows for Cognito | `list(string)` | <pre>[<br/> "ALLOW_USER_PASSWORD_AUTH",<br/> "ALLOW_USER_SRP_AUTH",<br/> "ALLOW_REFRESH_TOKEN_AUTH"<br/>]</pre> | no |
| <a name="input_logout_urls"></a> [logout\_urls](#input\_logout\_urls) | Logout URLs for Cognito if logout\_urls\_are\_callback\_urls is false | `list(string)` | `[]` | no |
| <a name="input_logout_urls_are_callback_urls"></a> [logout\_urls\_are\_callback\_urls](#input\_logout\_urls\_are\_callback\_urls) | Whether the Logout URLs are the same as the Callback URLs | `bool` | `true` | no |
| <a name="input_module_parents"></a> [module\_parents](#input\_module\_parents) | List of parent module names | `list(string)` | `[]` | no |
| <a name="input_saml_idp"></a> [saml\_idp](#input\_saml\_idp) | n/a | <pre>object({<br/> sso_metadata = object({<br/> url = optional(string, null) # "https://login.microsoftonline.com/<tenant_id>/federationmetadata/2007-06/federationmetadata.xml?appid=<app_id>"<br/> content = optional(string, null) # "<xml>...</xml>"<br/> })<br/><br/> ui_customisation = object({<br/> css = optional(string, ".label-customizable {font-weight: 400;}")<br/><br/> image = optional(object({<br/> base64 = optional(string, null)<br/> file = optional(string, null)<br/> }), null)<br/><br/> name = optional(string, null)<br/> })<br/> })</pre> | `null` | no |
| <a name="input_unique_ids"></a> [unique\_ids](#input\_unique\_ids) | n/a | <pre>object({<br/> # All marked as optional for consistency of code.<br/> # Whether each is optional depends on the module implementation.<br/> local = optional(string, null)<br/> account = optional(string, null)<br/> global = optional(string, null)<br/> })</pre> | n/a | yes |
| <a name="input_user_pool_domain_prefix"></a> [user\_pool\_domain\_prefix](#input\_user\_pool\_domain\_prefix) | Cognito User Pool Domain Prefix if not using a custom domain. Defaults to local.unique\_id | `string` | `null` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_saml_parameters"></a> [saml\_parameters](#output\_saml\_parameters) | SAML Parameters |
| <a name="output_user_pool"></a> [user\_pool](#output\_user\_pool) | n/a |
| <a name="output_user_pool_client"></a> [user\_pool\_client](#output\_user\_pool\_client) | Client User Pool Client Secret |
<!-- END_TF_DOCS -->
27 changes: 27 additions & 0 deletions modules/generic/cognito/aws_cognito_identity_provider.saml.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
resource "aws_cognito_identity_provider" "saml" {
count = local.saml_idp ? 1 : 0

user_pool_id = aws_cognito_user_pool.main.id

provider_name = local.identity_provider_name
provider_type = "SAML"

attribute_mapping = {
email = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
name = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
}

provider_details = {
MetadataFile = var.saml_idp["sso_metadata"]["content"]
MetadataURL = var.saml_idp["sso_metadata"]["url"]
}

# ActiveEncryptionCertificate, SLORedirectBindingURI and SSORedirectBindingURI are only populated from MetadataURL
lifecycle {
ignore_changes = [
provider_details["ActiveEncryptionCertificate"],
provider_details["SLORedirectBindingURI"],
provider_details["SSORedirectBindingURI"],
]
}
}
59 changes: 59 additions & 0 deletions modules/generic/cognito/aws_cognito_user_pool.main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
resource "aws_cognito_user_pool" "main" {
name = local.unique_id

account_recovery_setting {
recovery_mechanism {
name = "verified_phone_number"
priority = 1
}

recovery_mechanism {
name = "verified_email"
priority = 2
}
}

admin_create_user_config {
allow_admin_create_user_only = true
}

auto_verified_attributes = [
"email",
]

mfa_configuration = "OPTIONAL"

schema {
attribute_data_type = "String"
mutable = true
name = "email"
required = true

string_attribute_constraints {
min_length = 0
max_length = 2048
}
}

sms_configuration {
external_id = "${local.unique_id}-user-pool"
sns_caller_arn = aws_iam_role.cognito_user_pool_sms.arn
}

username_attributes = [
"email",
]

user_pool_add_ons {
advanced_security_mode = "ENFORCED"
}

verification_message_template {
default_email_option = "CONFIRM_WITH_CODE"
email_message = "The verification code to your new account is {####}"
email_subject = "Verify your new account"
sms_message = "The verification code to your new account is {####}"
}

tags = local.default_tags
}
28 changes: 28 additions & 0 deletions modules/generic/cognito/aws_cognito_user_pool_client.cognito.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
resource "aws_cognito_user_pool_client" "cognito" {
count = local.saml_idp ? 0 : 1

name = "${local.unique_id}-cognito"

user_pool_id = aws_cognito_user_pool.main.id

access_token_validity = var.access_token_validity["value"]

token_validity_units {
access_token = var.access_token_validity["units"]
}

allowed_oauth_flows = [
"code",
]

allowed_oauth_flows_user_pool_client = true
allowed_oauth_scopes = var.allowed_oauth_scopes
callback_urls = local.user_pool_client_callback_urls
explicit_auth_flows = var.explicit_auth_flows
generate_secret = true
logout_urls = local.user_pool_client_logout_urls

supported_identity_providers = [
"COGNITO",
]
}
29 changes: 29 additions & 0 deletions modules/generic/cognito/aws_cognito_user_pool_client.saml.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
resource "aws_cognito_user_pool_client" "saml" {
count = local.saml_idp ? 1 : 0

name = "${local.unique_id}-saml"

user_pool_id = aws_cognito_user_pool.main.id

access_token_validity = var.access_token_validity["value"]

token_validity_units {
access_token = var.access_token_validity["units"]
}

allowed_oauth_flows = [
"code",
"implicit",
]

allowed_oauth_flows_user_pool_client = true
allowed_oauth_scopes = var.allowed_oauth_scopes
callback_urls = local.user_pool_client_callback_urls
explicit_auth_flows = var.explicit_auth_flows
generate_secret = true
logout_urls = local.user_pool_client_logout_urls

supported_identity_providers = [
aws_cognito_identity_provider.saml[0].provider_name,
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
resource "aws_cognito_user_pool_domain" "custom" {
count = local.custom_domain ? 1 : 0

certificate_arn = var.custom_domain["cloudfront_acm_certificate_arn"]
domain = local.user_pool_domain
user_pool_id = aws_cognito_user_pool.main.id
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
resource "aws_cognito_user_pool_domain" "prefix" {
count = local.custom_domain ? 0 : 1

domain = local.user_pool_domain_prefix
user_pool_id = aws_cognito_user_pool.main.id
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
resource "aws_cognito_user_pool_ui_customization" "saml" {
count = local.saml_idp && var.saml_idp["ui_customisation"] != null ? 1 : 0

client_id = aws_cognito_user_pool_client.saml[0].id

css = var.saml_idp["ui_customisation"]["css"]

image_file = (
var.saml_idp["ui_customisation"]["image"] == null ? null :
var.saml_idp["ui_customisation"]["image"]["base64"] != null ? var.saml_idp["ui_customisation"]["image"]["base64"] :
filebase64(var.saml_idp["ui_customisation"]["image"]["file"])
)

# Refer to the aws_cognito_user_pool_domain resource's
# user_pool_id attribute to ensure it is in an 'Active' state
user_pool_id = local.custom_domain ? aws_cognito_user_pool_domain.custom[0].user_pool_id : aws_cognito_user_pool_domain.prefix[0].user_pool_id

depends_on = [
aws_cognito_user_pool.main,
aws_cognito_user_pool_domain.prefix,
aws_cognito_user_pool_domain.custom,
]
}
15 changes: 15 additions & 0 deletions modules/generic/cognito/aws_iam_role.cognito_user_pool_sms.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
resource "aws_iam_role" "cognito_user_pool_sms" {
name = "${local.unique_id}-user-pool-sms"
assume_role_policy = data.aws_iam_policy_document.cognito_user_pool_assumerole.json

tags = merge(
local.default_tags,
{
Name = "${local.unique_id}-user-pool-sms"
}
)

provisioner "local-exec" {
command = "sleep 10"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
resource "aws_iam_role_policy" "cognito_user_pool_sms" {
name = "${local.unique_id}-user-pool-sms"
role = aws_iam_role.cognito_user_pool_sms.id

# TODO: Scope this down!
policy = data.aws_iam_policy_document.sns_publish_any.json
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
resource "aws_route53_record" "alias_cognito_user_pool_domain_custom" {
count = local.custom_domain ? 1 : 0

name = "${local.user_pool_domain}."
type = "A"
zone_id = var.custom_domain["route53_public_hosted_zone_id"]

alias {
evaluate_target_health = false
name = aws_cognito_user_pool_domain.custom[0].cloudfront_distribution_arn

# Well-known Hosted Zone ID of CloudFront
zone_id = "Z2FDTNDATAQYW2"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
data "aws_iam_policy_document" "cognito_user_pool_admin_get_user" {
statement {
sid = "AllowGetCognitoAdminUser"
effect = "Allow"

actions = [
"cognito-idp:AdminGetUser",
]

resources = [
aws_cognito_user_pool.main.arn,
]
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
data "aws_iam_policy_document" "cognito_user_pool_assumerole" {
statement {
sid = "WebCognitoUserPoolAssumeRole"
effect = "Allow"

actions = [
"sts:AssumeRole",
]

principals {
type = "Service"

identifiers = [
"cognito-idp.${var.aws["url_suffix"]}",
]
}

condition {
test = "StringEquals"
variable = "sts:ExternalId"

values = [
"${local.unique_id}-user-pool",
]
}
}
}
Loading

0 comments on commit 7622c46

Please sign in to comment.