Skip to content

Add user-bot Lambda infrastructure and slack_id user tag - #210

Merged
ale210 merged 1 commit into
mainfrom
209-user-bot-terraform
Oct 4, 2026
Merged

ale210 merged 1 commit into
mainfrom
209-user-bot-terraform

Conversation

@ale210

@ale210 ale210 commented Oct 4, 2026

Copy link
Copy Markdown
Member

Part of #209 (PR 1 of 2: Terraform and the request form; the Lambda code and its workflows follow in PR 2)

What changes did you make?

  • aws-users module: optional slack_id input, stored as a slack_id tag; validated as a Slack member ID
  • New terraform/user-bot.tf (us-east-1): EventBridge rule on successful CreateLoginProfile, the user-bot Lambda from a do-nothing placeholder, its log group, and an execution role that can only reset passwords of users tagged managed-by = terraform-devops-security
  • New devops-security-user-bot-deploy OIDC role (main only, UpdateFunctionCode/GetFunction on this function only) for PR 2's deploy workflow
  • hashicorp/archive provider added; optional "Slack Member ID" field on the IAM request form; READMEs regenerated

Why did you make the changes (we will use this info to test)?

  • So new IAM users can be sent a temporary console password by Slack DM (see Add a user-bot Lambda that DMs new IAM users a temporary console password #209)
  • Expected plan: 9 to add, 0 to change, 0 to destroy. Existing users must show no changes. The event rule, target, log group, function and permission should show region = "us-east-1"
  • The Slack field is optional because the form is also used for service accounts

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Terraform plan in terraform
With backend config files: terraform/prod.backend.tfvars
With variables: iam_only = false

Plan: 9 to add, 0 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

Terraform will perform the following actions:

  # aws_cloudwatch_event_rule.user_bot will be created
+   resource "aws_cloudwatch_event_rule" "user_bot" {
+       arn            = (known after apply)
+       description    = "Invokes the user-bot Lambda when an IAM user is given a console login profile"
+       event_bus_name = "default"
+       event_pattern  = jsonencode(
            {
+               detail      = {
+                   errorCode   = [
+                       {
+                           exists = false
                        },
                    ]
+                   eventName   = [
+                       "CreateLoginProfile",
                    ]
+                   eventSource = [
+                       "iam.amazonaws.com",
                    ]
                }
+               detail-type = [
+                   "AWS API Call via CloudTrail",
                ]
+               source      = [
+                   "aws.iam",
                ]
            }
        )
+       force_destroy  = false
+       id             = (known after apply)
+       name           = "user-bot-create-login-profile"
+       name_prefix    = (known after apply)
+       region         = "us-east-1"
+       tags_all       = {
+           "managed-by" = "terraform-devops-security"
        }
    }

  # aws_cloudwatch_event_target.user_bot will be created
+   resource "aws_cloudwatch_event_target" "user_bot" {
+       arn            = (known after apply)
+       event_bus_name = "default"
+       force_destroy  = false
+       id             = (known after apply)
+       region         = "us-east-1"
+       rule           = "user-bot-create-login-profile"
+       target_id      = (known after apply)
    }

  # aws_cloudwatch_log_group.user_bot will be created
+   resource "aws_cloudwatch_log_group" "user_bot" {
+       arn                         = (known after apply)
+       deletion_protection_enabled = (known after apply)
+       id                          = (known after apply)
+       log_group_class             = (known after apply)
+       name                        = "/aws/lambda/user-bot"
+       name_prefix                 = (known after apply)
+       region                      = "us-east-1"
+       retention_in_days           = 90
+       skip_destroy                = false
+       tags_all                    = {
+           "managed-by" = "terraform-devops-security"
        }
    }

  # aws_iam_role.user_bot will be created
+   resource "aws_iam_role" "user_bot" {
+       arn                   = (known after apply)
+       assume_role_policy    = jsonencode(
            {
+               Statement = [
+                   {
+                       Action    = "sts:AssumeRole"
+                       Effect    = "Allow"
+                       Principal = {
+                           Service = "lambda.amazonaws.com"
                        }
                    },
                ]
+               Version   = "2012-10-17"
            }
        )
+       create_date           = (known after apply)
+       force_detach_policies = false
+       id                    = (known after apply)
+       managed_policy_arns   = (known after apply)
+       max_session_duration  = 3600
+       name                  = "user-bot"
+       name_prefix           = (known after apply)
+       path                  = "/"
+       tags_all              = {
+           "managed-by" = "terraform-devops-security"
        }
+       unique_id             = (known after apply)

+       inline_policy (known after apply)
    }

  # aws_iam_role.user_bot_deploy will be created
+   resource "aws_iam_role" "user_bot_deploy" {
+       arn                   = (known after apply)
+       assume_role_policy    = jsonencode(
            {
+               Statement = [
+                   {
+                       Action    = "sts:AssumeRoleWithWebIdentity"
+                       Condition = {
+                           StringEquals = {
+                               "token.actions.githubusercontent.com:aud" = "*****************"
+                               "token.actions.githubusercontent.com:sub" = "**************************************************"
                            }
                        }
+                       Effect    = "Allow"
+                       Principal = {
+                           Federated = "arn:aws:iam::035866691871:oidc-provider/token.actions.githubusercontent.com"
                        }
                    },
                ]
+               Version   = "2012-10-17"
            }
        )
+       create_date           = (known after apply)
+       force_detach_policies = false
+       id                    = (known after apply)
+       managed_policy_arns   = (known after apply)
+       max_session_duration  = 3600
+       name                  = "devops-security-user-bot-deploy"
+       name_prefix           = (known after apply)
+       path                  = "/"
+       tags_all              = {
+           "managed-by" = "terraform-devops-security"
        }
+       unique_id             = (known after apply)

+       inline_policy (known after apply)
    }

  # aws_iam_role_policy.user_bot will be created
+   resource "aws_iam_role_policy" "user_bot" {
+       id          = (known after apply)
+       name        = "user-bot"
+       name_prefix = (known after apply)
+       policy      = (known after apply)
+       role        = (known after apply)
    }

  # aws_iam_role_policy.user_bot_deploy will be created
+   resource "aws_iam_role_policy" "user_bot_deploy" {
+       id          = (known after apply)
+       name        = "user-bot-deploy"
+       name_prefix = (known after apply)
+       policy      = (known after apply)
+       role        = (known after apply)
    }

  # aws_lambda_function.user_bot will be created
+   resource "aws_lambda_function" "user_bot" {
+       architectures                  = (known after apply)
+       arn                            = (known after apply)
+       code_sha256                    = (known after apply)
+       description                    = "DMs new IAM users a temporary console password. Code is deployed by user-bot-deploy.yml in hackforla/devops-security."
+       filename                       = "./.terraform/user-bot-placeholder.zip"
+       function_name                  = "user-bot"
+       handler                        = "index.handler"
+       id                             = (known after apply)
+       invoke_arn                     = (known after apply)
+       last_modified                  = (known after apply)
+       memory_size                    = 128
+       package_type                   = "Zip"
+       publish                        = false
+       qualified_arn                  = (known after apply)
+       qualified_invoke_arn           = (known after apply)
+       region                         = "us-east-1"
+       reserved_concurrent_executions = -1
+       response_streaming_invoke_arn  = (known after apply)
+       role                           = (known after apply)
+       runtime                        = "nodejs24.x"
+       signing_job_arn                = (known after apply)
+       signing_profile_version_arn    = (known after apply)
+       skip_destroy                   = false
+       source_code_hash               = "LLba/aL0rfujZfe2GX308Af+BuAl7oqRUuVOV4dV1mo="
+       source_code_size               = (known after apply)
+       tags_all                       = {
+           "managed-by" = "terraform-devops-security"
        }
+       timeout                        = 30
+       version                        = (known after apply)

+       ephemeral_storage (known after apply)

+       logging_config (known after apply)

+       tracing_config (known after apply)
    }

  # aws_lambda_permission.user_bot_eventbridge will be created
+   resource "aws_lambda_permission" "user_bot_eventbridge" {
+       action              = "lambda:InvokeFunction"
+       function_name       = "user-bot"
+       id                  = (known after apply)
+       principal           = "events.amazonaws.com"
+       region              = "us-east-1"
+       source_arn          = (known after apply)
+       statement_id        = "*************************************"
+       statement_id_prefix = (known after apply)
    }

Plan: 9 to add, 0 to change, 0 to destroy.

✅ Plan applied in Apply Terraform changes on merge #50

@ale210
ale210 merged commit 181557e into main Oct 4, 2026
2 checks passed
@ale210
ale210 deleted the 209-user-bot-terraform branch October 4, 2026 21:25
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