Skip to content

Adopt the shared Cognito user pool - #246

Merged
ale210 merged 3 commits into
mainfrom
17-shared-cognito-pool
Sep 30, 2026
Merged

ale210 merged 3 commits into
mainfrom
17-shared-cognito-pool

Conversation

@ale210

@ale210 ale210 commented Sep 27, 2026

Copy link
Copy Markdown
Member

Part of #17 (the shared-pool half). The Lambda half is #245.

Adopts the hand-made vrms-dev Cognito pool as the org's shared user pool, and adds modules/shared-user-pool-access for projects to get clients and, optionally, admin rights on it.

  • terraform/cognito.tf: the pool and its domain, matched to live AWS. user_pool_tier = "LITE", prevent_destroy.
    • No project tag, deliberately. The container module grants Cognito admin on pools tagged with a project's name, so a tag would give one project admin over every project's users.
    • The name stays vrms-dev, because renaming a pool replaces it.
  • modules/shared-user-pool-access: takes a clients map and an optional task_role_name. The role option adds an inline policy with the same four admin actions the container module grants, scoped to this pool only. Clients ignore generate_secret (it isn't readable on import and would plan a replacement) and have prevent_destroy.
  • people-depot: its three existing clients, plus the admin grant to its dev backend task role. That grant is a real IAM change: the role has no rights on this pool today.
  • vrms: its one existing client, no grant. This is the vrms-dev test the issue asks for.
  • people-depot's COGNITO_USER_POOL now comes from the pool resource instead of a literal. It resolves to the same value, so no task definition change is expected.

Expected plan: 6 to import, 1 to add (the inline policy), 0 to destroy, no replacements, and otherwise tags only.

Merge note: this PR and #245 both append to the end of import.tf, so whichever merges second needs a trivial rebase.

Not included: the optional user_pool module for projects with their own pool. home-unite-us already declares its own pools directly, so it would have no user.

@github-actions

github-actions Bot commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Terraform plan in terraform
With backend config files: terraform/prod.backend.tfvars

Plan: 6 to import, 1 to add, 1 to change, 0 to destroy.
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+   create
!~  update in-place

Terraform will perform the following actions:

  # aws_cognito_user_pool.shared will be updated in-place
  # (imported from "us-west-2_Fn4rkZpuB")
!~  resource "aws_cognito_user_pool" "shared" {
        arn                        = "arn:aws:cognito-idp:us-west-2:035866691871:userpool/us-west-2_Fn4rkZpuB"
        auto_verified_attributes   = [
            "email",
        ]
        creation_date              = "2022-04-18T03:42:41Z"
        custom_domain              = null
        deletion_protection        = "INACTIVE"
        domain                     = "hackforla-vrms-dev"
        email_verification_message = "Your verification code is {####}. "
        email_verification_subject = "Your verification code"
        endpoint                   = "cognito-idp.us-west-2.amazonaws.com/us-west-2_Fn4rkZpuB"
        estimated_number_of_users  = 24
        id                         = "us-west-2_Fn4rkZpuB"
        last_modified_date         = "2022-04-18T03:42:41Z"
        mfa_configuration          = "OFF"
        name                       = "vrms-dev"
        region                     = "us-west-2"
        sms_authentication_message = "Your authentication code is {####}. "
        sms_verification_message   = "Your verification code is {####}. "
        tags                       = {}
!~      tags_all                   = {
+           "managed-by" = "terraform-incubator"
        }
        user_pool_tier             = "LITE"
        username_attributes        = [
            "email",
        ]

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

        admin_create_user_config {
            allow_admin_create_user_only = false

            invite_message_template {
                email_message = "Your username is {username} and temporary password is {####}. "
                email_subject = "Your temporary password"
                sms_message   = "Your username is {username} and temporary password is {####}. "
            }
        }

        email_configuration {
            configuration_set      = null
            email_sending_account  = "COGNITO_DEFAULT"
            from_email_address     = null
            reply_to_email_address = null
            source_arn             = null
        }

        password_policy {
            minimum_length                   = 8
            password_history_size            = 0
            require_lowercase                = true
            require_numbers                  = true
            require_symbols                  = true
            require_uppercase                = true
            temporary_password_validity_days = 7
        }

        sign_in_policy {
            allowed_first_auth_factors = [
                "PASSWORD",
            ]
        }

        username_configuration {
            case_sensitive = false
        }

        verification_message_template {
            default_email_option  = "CONFIRM_WITH_CODE"
            email_message         = "Your verification code is {####}. "
            email_message_by_link = null
            email_subject         = "Your verification code"
            email_subject_by_link = null
            sms_message           = "Your verification code is {####}. "
        }
    }

  # aws_cognito_user_pool_domain.shared will be imported
    resource "aws_cognito_user_pool_domain" "shared" {
        aws_account_id                  = "************"
        certificate_arn                 = null
        cloudfront_distribution         = "dpp0gtxikpq3y.cloudfront.net"
        cloudfront_distribution_arn     = "dpp0gtxikpq3y.cloudfront.net"
        cloudfront_distribution_zone_id = "**************"
        domain                          = "hackforla-vrms-dev"
        id                              = "hackforla-vrms-dev"
        managed_login_version           = 1
        region                          = "us-west-2"
        s3_bucket                       = "aws-cognito-prod-pdx-assets"
        user_pool_id                    = "*******************"
        version                         = "20220418034315"
    }

  # module.people-depot.module.shared_user_pool_access.aws_cognito_user_pool_client.this["backend"] will be imported
    resource "aws_cognito_user_pool_client" "this" {
        access_token_validity                         = 60
        allowed_oauth_flows                           = [
            "implicit",
        ]
        allowed_oauth_flows_user_pool_client          = true
        allowed_oauth_scopes                          = [
            "openid",
        ]
        auth_session_validity                         = 3
        callback_urls                                 = [
            "http://localhost:8000/admin",
        ]
        client_secret                                 = (sensitive value)
        default_redirect_uri                          = null
        enable_propagate_additional_user_context_data = false
        enable_token_revocation                       = true
        explicit_auth_flows                           = [
            "ALLOW_ADMIN_USER_PASSWORD_AUTH",
            "ALLOW_REFRESH_TOKEN_AUTH",
        ]
        id                                            = "3e3bi1ct2ks9rcktrde8v60v3u"
        id_token_validity                             = 60
        logout_urls                                   = []
        name                                          = "backend is the old app client used by PD, which returns the auth token in the url"
        prevent_user_existence_errors                 = "ENABLED"
        read_attributes                               = [
            "address",
            "birthdate",
            "email",
            "email_verified",
            "family_name",
            "gender",
            "given_name",
            "locale",
            "middle_name",
            "name",
            "nickname",
            "phone_number",
            "phone_number_verified",
            "picture",
            "preferred_username",
            "profile",
            "updated_at",
            "website",
            "zoneinfo",
        ]
        refresh_token_validity                        = 30
        region                                        = "us-west-2"
        supported_identity_providers                  = [
            "COGNITO",
        ]
        user_pool_id                                  = "*******************"
        write_attributes                              = [
            "address",
            "birthdate",
            "email",
            "family_name",
            "gender",
            "given_name",
            "locale",
            "middle_name",
            "name",
            "nickname",
            "phone_number",
            "picture",
            "preferred_username",
            "profile",
            "updated_at",
            "website",
            "zoneinfo",
        ]

        token_validity_units {
            access_token  = "*******"
            id_token      = "*******"
            refresh_token = "****"
        }
    }

  # module.people-depot.module.shared_user_pool_access.aws_cognito_user_pool_client.this["pd-2"] will be imported
    resource "aws_cognito_user_pool_client" "this" {
        access_token_validity                         = 60
        allowed_oauth_flows                           = [
            "code",
        ]
        allowed_oauth_flows_user_pool_client          = true
        allowed_oauth_scopes                          = [
            "email",
            "openid",
            "profile",
        ]
        auth_session_validity                         = 3
        callback_urls                                 = [
            "http://localhost:8000/accounts/amazon-cognito/login/callback/",
            "http://localhost:8000/admin/",
        ]
        client_secret                                 = (sensitive value)
        default_redirect_uri                          = null
        enable_propagate_additional_user_context_data = false
        enable_token_revocation                       = true
        explicit_auth_flows                           = [
            "ALLOW_REFRESH_TOKEN_AUTH",
            "ALLOW_USER_SRP_AUTH",
        ]
        id                                            = "2pn3qa717ae8lq8u801v8t9hps"
        id_token_validity                             = 60
        logout_urls                                   = []
        name                                          = "pd-2 is a secret-less app client which should be used with a frontend and NOT with a backend"
        prevent_user_existence_errors                 = "ENABLED"
        read_attributes                               = [
            "address",
            "birthdate",
            "email",
            "email_verified",
            "family_name",
            "gender",
            "given_name",
            "locale",
            "middle_name",
            "name",
            "nickname",
            "phone_number",
            "phone_number_verified",
            "picture",
            "preferred_username",
            "profile",
            "updated_at",
            "website",
            "zoneinfo",
        ]
        refresh_token_validity                        = 30
        region                                        = "us-west-2"
        supported_identity_providers                  = [
            "COGNITO",
        ]
        user_pool_id                                  = "*******************"
        write_attributes                              = [
            "address",
            "birthdate",
            "email",
            "family_name",
            "gender",
            "given_name",
            "locale",
            "middle_name",
            "name",
            "nickname",
            "phone_number",
            "picture",
            "preferred_username",
            "profile",
            "updated_at",
            "website",
            "zoneinfo",
        ]

        token_validity_units {
            access_token  = "*******"
            id_token      = "*******"
            refresh_token = "****"
        }
    }

  # module.people-depot.module.shared_user_pool_access.aws_cognito_user_pool_client.this["peopledepot"] will be imported
    resource "aws_cognito_user_pool_client" "this" {
        access_token_validity                         = 60
        allowed_oauth_flows                           = [
            "code",
        ]
        allowed_oauth_flows_user_pool_client          = true
        allowed_oauth_scopes                          = [
            "email",
            "openid",
            "profile",
        ]
        auth_session_validity                         = 3
        callback_urls                                 = [
            "http://localhost:8000/accounts/amazon-cognito/login/callback/",
            "http://localhost:8000/admin/",
        ]
        client_secret                                 = (sensitive value)
        default_redirect_uri                          = null
        enable_propagate_additional_user_context_data = false
        enable_token_revocation                       = true
        explicit_auth_flows                           = [
            "ALLOW_REFRESH_TOKEN_AUTH",
            "ALLOW_USER_SRP_AUTH",
        ]
        id                                            = "52n88hbq9kn00utcjk2hg0e8nl"
        id_token_validity                             = 60
        logout_urls                                   = []
        name                                          = "PEOPLEDEPOT is a backend app client that contains a secret"
        prevent_user_existence_errors                 = "ENABLED"
        read_attributes                               = [
            "address",
            "birthdate",
            "email",
            "email_verified",
            "family_name",
            "gender",
            "given_name",
            "locale",
            "middle_name",
            "name",
            "nickname",
            "phone_number",
            "phone_number_verified",
            "picture",
            "preferred_username",
            "profile",
            "updated_at",
            "website",
            "zoneinfo",
        ]
        refresh_token_validity                        = 30
        region                                        = "us-west-2"
        supported_identity_providers                  = [
            "COGNITO",
        ]
        user_pool_id                                  = "*******************"
        write_attributes                              = [
            "address",
            "birthdate",
            "email",
            "family_name",
            "gender",
            "given_name",
            "locale",
            "middle_name",
            "name",
            "nickname",
            "phone_number",
            "picture",
            "preferred_username",
            "profile",
            "updated_at",
            "website",
            "zoneinfo",
        ]

        token_validity_units {
            access_token  = "*******"
            id_token      = "*******"
            refresh_token = "****"
        }
    }

  # module.people-depot.module.shared_user_pool_access.aws_iam_role_policy.admin[0] will be created
+   resource "aws_iam_role_policy" "admin" {
+       id          = (known after apply)
+       name        = "shared-user-pool-admin"
+       name_prefix = (known after apply)
+       policy      = jsonencode(
            {
+               Statement = [
+                   {
+                       Action   = [
+                           "cognito-idp:AdminGetUser",
+                           "cognito-idp:AdminCreateUser",
+                           "cognito-idp:AdminAddUserToGroup",
+                           "cognito-idp:AdminDeleteUser",
                        ]
+                       Effect   = "Allow"
+                       Resource = "arn:aws:cognito-idp:us-west-2:035866691871:userpool/us-west-2_Fn4rkZpuB"
+                       Sid      = "SharedUserPoolAdmin"
                    },
                ]
+               Version   = "2012-10-17"
            }
        )
+       role        = "ecs-container-people-depot-backend-dev"
    }

  # module.vrms.module.shared_user_pool_access.aws_cognito_user_pool_client.this["vrms"] will be imported
    resource "aws_cognito_user_pool_client" "this" {
        access_token_validity                         = 60
        allowed_oauth_flows                           = []
        allowed_oauth_flows_user_pool_client          = false
        allowed_oauth_scopes                          = []
        auth_session_validity                         = 3
        callback_urls                                 = []
        client_secret                                 = (sensitive value)
        default_redirect_uri                          = null
        enable_propagate_additional_user_context_data = false
        enable_token_revocation                       = true
        explicit_auth_flows                           = [
            "ALLOW_REFRESH_TOKEN_AUTH",
            "ALLOW_USER_SRP_AUTH",
        ]
        id                                            = "5u7s2nj55mp9v5qmt9scja4hnr"
        id_token_validity                             = 60
        logout_urls                                   = []
        name                                          = "VRMS"
        prevent_user_existence_errors                 = "ENABLED"
        read_attributes                               = [
            "address",
            "birthdate",
            "email",
            "email_verified",
            "family_name",
            "gender",
            "given_name",
            "locale",
            "middle_name",
            "name",
            "nickname",
            "phone_number",
            "phone_number_verified",
            "picture",
            "preferred_username",
            "profile",
            "updated_at",
            "website",
            "zoneinfo",
        ]
        refresh_token_validity                        = 30
        region                                        = "us-west-2"
        supported_identity_providers                  = []
        user_pool_id                                  = "*******************"
        write_attributes                              = [
            "address",
            "birthdate",
            "email",
            "family_name",
            "gender",
            "given_name",
            "locale",
            "middle_name",
            "name",
            "nickname",
            "phone_number",
            "picture",
            "preferred_username",
            "profile",
            "updated_at",
            "website",
            "zoneinfo",
        ]

        token_validity_units {
            access_token  = "*******"
            id_token      = "*******"
            refresh_token = "****"
        }
    }

Plan: 6 to import, 1 to add, 1 to change, 0 to destroy.

✅ Plan applied in Terraform apply (OIDC) #97

@ale210
ale210 merged commit fefa6a7 into main Sep 30, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant