Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Resources created by this code repository.
| [aws_s3_bucket_public_access_block.tf_backend_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
| [aws_s3_bucket_server_side_encryption_configuration.management_events](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |
| [aws_s3_bucket_server_side_encryption_configuration.tf_backend_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |
| [aws_ssm_parameter.user_bot_slack_token](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource |
| [archive_file.user_bot_placeholder](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
## Inputs
Expand Down
49 changes: 49 additions & 0 deletions terraform/user-bot.tf
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,54 @@ resource "aws_lambda_function" "user_bot" {
filename = data.archive_file.user_bot_placeholder.output_path
source_code_hash = data.archive_file.user_bot_placeholder.output_base64sha256

// The name, not the token. The function reads and decrypts the value at cold start.
environment {
variables = {
SLACK_TOKEN_PARAMETER = aws_ssm_parameter.user_bot_slack_token.name
}
}

depends_on = [aws_cloudwatch_log_group.user_bot]

lifecycle {
ignore_changes = [filename, source_code_hash]
}
}

// ---------------------------------------------------------------------------
// Slack bot token
// ---------------------------------------------------------------------------

// The Slack app's bot token (xoxb-...). Terraform creates the parameter with a
// placeholder; the real token is set by hand with `aws ssm put-parameter --overwrite`
// (see lambda/user-bot/README.md), so it never appears in git or in Terraform state.
// See hackforla/devops-security#212.
//
// value_wo rather than value is what keeps the token out of state. With `value`, the
// provider reads the decrypted parameter back into state on every refresh. With the
// write-only value_wo, its read sets `value` to null, and the value is only ever
// written when value_wo_version changes.
//
// Two traps, both because the real value lives outside Terraform:
// - Never change value_wo_version. That writes the placeholder over the real token,
// and the bot refuses to send until the token is set again.
// - Do not change other arguments, such as description, in place. The provider then
// sends an empty value and the apply fails.
resource "aws_ssm_parameter" "user_bot_slack_token" {
region = local.user_bot_region

name = "/user-bot/slack-bot-token"
description = "Slack bot token for the user-bot Lambda. Set by hand; see lambda/user-bot/README.md in hackforla/devops-security."
type = "SecureString"

value_wo = "placeholder-set-by-hand"
value_wo_version = 1

lifecycle {
prevent_destroy = true
}
}

// ---------------------------------------------------------------------------
// Execution role
// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -165,6 +206,14 @@ resource "aws_iam_role_policy" "user_bot" {
}
}
},
// No kms:Decrypt statement: the parameter uses the AWS-managed aws/ssm key, whose
// key policy already allows decryption through SSM for principals in the account.
{
Sid = "ReadSlackToken"
Effect = "Allow"
Action = "ssm:GetParameter"
Resource = aws_ssm_parameter.user_bot_slack_token.arn
},
{
Sid = "WriteOwnLogs"
Effect = "Allow"
Expand Down
Loading