diff --git a/README.md b/README.md index 5b35a27..6a7d7fb 100644 --- a/README.md +++ b/README.md @@ -140,5 +140,7 @@ Frequently (quartley at least) check and upgrade: | Name | Description | |------|-------------| +| [channels\_config](#output\_channels\_config) | The configuration data for each distribution channel | +| [distributions](#output\_distributions) | The list of slack/teams distributions that are managed | | [sns\_topic\_arn](#output\_sns\_topic\_arn) | The ARN of the SNS topic | diff --git a/locals.tf b/locals.tf index 31f06cd..57cb367 100644 --- a/locals.tf +++ b/locals.tf @@ -29,19 +29,19 @@ locals { teams_webhook_url = local.enable_teams_secret ? try(jsondecode(data.aws_secretsmanager_secret_version.teams[0].secret_string)["webhook_url"], var.teams.webhook_url) : try(var.teams.webhook_url, null) channels_config = { - "slack" = { + "slack" = var.slack != null ? { webhook_url = local.slack_webhook_url lambda_name = try(var.slack.lambda_name, "slack-notify") lambda_description = try(var.slack.lambda_description, "Sends posts to slack") filter_policy = try(var.slack.filter_policy, null) filter_policy_scope = try(var.slack.filter_policy_scope, null) - }, - "teams" = { + } : null, + "teams" = var.teams != null ? { webhook_url = local.teams_webhook_url lambda_name = try(var.teams.lambda_name, "teams-notify") lambda_description = try(var.teams.lambda_description, "Sends posts to teams") filter_policy = try(var.teams.filter_policy, null) filter_policy_scope = try(var.teams.filter_policy_scope, null) - } + } : null, } } diff --git a/main.tf b/main.tf index da27ad5..44611fe 100644 --- a/main.tf +++ b/main.tf @@ -42,7 +42,6 @@ resource "aws_sns_topic_subscription" "subscribers" { # tfsec:ignore:aws-lambda-enable-tracing # tfsec:ignore:aws-lambda-restrict-source-arn module "notify" { - count = var.enable_slack || var.enable_teams ? 1 : 0 source = "./modules/notify" cloudwatch_log_group_kms_key_id = var.cloudwatch_log_group_kms_key_id diff --git a/modules/notify/README.md b/modules/notify/README.md index 1242f09..4de2c0a 100644 --- a/modules/notify/README.md +++ b/modules/notify/README.md @@ -164,7 +164,6 @@ Subsumed by appvia's GNU V3 license; [see license](../../LICENSE). | [lambda\_source\_path](#input\_lambda\_source\_path) | The source path of the custom Lambda function | `string` | `null` | no | | [post\_icons\_url](#input\_post\_icons\_url) | URLs (not base64 encoded!) to publically available icons for highlighting posts of error and/or warning status. Ideally 50px square. |
object({
error_url = string
warning_url = string
})
|
{
"error_url": "https://raw.githubusercontent.com/appvia/terraform-aws-notifications/main/resources/posts-attention-icon.png",
"warning_url": "https://raw.githubusercontent.com/appvia/terraform-aws-notifications/main/resources/posts-warning-icon.png"
}
| no | | [powertools\_layer\_arn\_suffix](#input\_powertools\_layer\_arn\_suffix) | The suffix of the ARN to use for AWS Powertools lambda layer (must match the architecture:https://docs.powertools.aws.dev/lambda/python/latest/. | `string` | `"AWSLambdaPowertoolsPythonV2-Arm64:79"` | no | -| [putin\_khuylo](#input\_putin\_khuylo) | Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo! | `bool` | `true` | no | | [python\_runtime](#input\_python\_runtime) | The lambda python runtime | `string` | `"python3.12"` | no | | [recreate\_missing\_package](#input\_recreate\_missing\_package) | Whether to recreate missing Lambda package if it is missing locally or not | `bool` | `true` | no | | [reserved\_concurrent\_executions](#input\_reserved\_concurrent\_executions) | The amount of reserved concurrent executions for this lambda function. A value of 0 disables lambda from being triggered and -1 removes any concurrency limitations | `number` | `-1` | no | @@ -186,6 +185,7 @@ Subsumed by appvia's GNU V3 license; [see license](../../LICENSE). | Name | Description | |------|-------------| +| [distributions](#output\_distributions) | The list of slack/teams distributions that are managed | | [notify\_slack\_lambda\_function\_arn](#output\_notify\_slack\_lambda\_function\_arn) | The ARN of the Lambda function | | [notify\_slack\_lambda\_function\_version](#output\_notify\_slack\_lambda\_function\_version) | Latest published version of your Lambda function | | [notify\_slack\_slack\_lambda\_function\_name](#output\_notify\_slack\_slack\_lambda\_function\_name) | The name of the Lambda function | diff --git a/modules/notify/main.tf b/modules/notify/main.tf index a7a1385..9593b66 100644 --- a/modules/notify/main.tf +++ b/modules/notify/main.tf @@ -3,7 +3,7 @@ data "aws_partition" "current" {} data "aws_region" "current" {} locals { - create = var.create && var.putin_khuylo + create = var.create sns_topic_arn = try( aws_sns_topic.this[0].arn, @@ -76,12 +76,23 @@ locals { warning-icon-url = var.post_icons_url.warning_url } ) + + # the enable_[slack|teams] variable controls the subscription between SNS and lambda only; it is + # feasible that we want to keep the infrastructure (lambda, lambda role, log group et al) while suspending + # the posts. + # but we only want to create the infrastructure if details of slack or team have been defined + create_distribution = { + "slack" = var.delivery_channels["slack"] != null ? true : false, + "teams" = var.delivery_channels["teams"] != null ? true : false, + } + + distributions = toset([for x in ["slack", "teams"] : x if local.create_distribution[x] == true]) } #trivy:ignore:avd-aws-0059 #trivy:ignore:avd-aws-0057 data "aws_iam_policy_document" "lambda" { - for_each = toset(["slack", "teams"]) + for_each = local.distributions dynamic "statement" { for_each = concat([local.lambda_policy_document[each.value]], var.kms_key_arn != "" ? [local.lambda_policy_document_kms] : []) @@ -95,7 +106,7 @@ data "aws_iam_policy_document" "lambda" { } resource "aws_cloudwatch_log_group" "lambda" { - for_each = toset(["slack", "teams"]) + for_each = local.distributions name = "/aws/lambda/${var.delivery_channels[each.value].lambda_name}" retention_in_days = var.cloudwatch_log_group_retention_in_days @@ -121,7 +132,7 @@ resource "aws_sns_topic" "this" { resource "aws_sns_topic_subscription" "sns_notify_slack" { - count = var.create && var.enable_slack ? 1 : 0 + count = var.create && var.enable_slack && local.create_distribution["slack"] == true ? 1 : 0 topic_arn = local.sns_topic_arn protocol = "lambda" @@ -131,7 +142,7 @@ resource "aws_sns_topic_subscription" "sns_notify_slack" { } resource "aws_sns_topic_subscription" "sns_notify_teams" { - count = var.create && var.enable_teams ? 1 : 0 + count = var.create && var.enable_teams && local.create_distribution["teams"] == true ? 1 : 0 topic_arn = local.sns_topic_arn protocol = "lambda" @@ -187,7 +198,7 @@ resource "local_file" "notification_emblems_python" { #trivy:ignore:avd-aws-0067 module "lambda" { - for_each = toset(["slack", "teams"]) + for_each = local.distributions source = "terraform-aws-modules/lambda/aws" version = "3.2.0" diff --git a/modules/notify/outputs.tf b/modules/notify/outputs.tf index a5bc66c..7685941 100644 --- a/modules/notify/outputs.tf +++ b/modules/notify/outputs.tf @@ -3,31 +3,36 @@ output "sns_topic_arn" { value = local.sns_topic_arn } +output "distributions" { + description = "The list of slack/teams distributions that are managed" + value = local.distributions +} + output "notify_slack_lambda_function_arn" { description = "The ARN of the Lambda function" - value = module.lambda["slack"].lambda_function_arn + value = try(module.lambda["slack"].lambda_function_arn, "") } output "notify_teams_lambda_function_arn" { description = "The ARN of the Lambda function" - value = module.lambda["teams"].lambda_function_arn + value = try(module.lambda["teams"].lambda_function_arn, "") } output "notify_slack_slack_lambda_function_name" { description = "The name of the Lambda function" - value = module.lambda["slack"].lambda_function_name + value = try(module.lambda["slack"].lambda_function_name, "") } output "notify_teams_slack_lambda_function_name" { description = "The name of the Lambda function" - value = module.lambda["teams"].lambda_function_name + value = try(module.lambda["teams"].lambda_function_name, "") } output "notify_slack_lambda_function_version" { description = "Latest published version of your Lambda function" - value = module.lambda["slack"].lambda_function_version + value = try(module.lambda["slack"].lambda_function_version, "") } output "notify_teams_lambda_function_version" { description = "Latest published version of your Lambda function" - value = module.lambda["teams"].lambda_function_version + value = try(module.lambda["teams"].lambda_function_version, "") } output "slack_lambda_cloudwatch_log_group_arn" { diff --git a/modules/notify/variables.tf b/modules/notify/variables.tf index 32e8381..e2556d4 100644 --- a/modules/notify/variables.tf +++ b/modules/notify/variables.tf @@ -1,9 +1,3 @@ -variable "putin_khuylo" { - description = "Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo!" - type = bool - default = true -} - variable "architecture" { description = "Instruction set architecture for your Lambda function. Valid values are \"x86_64\" or \"arm64\"." type = string @@ -34,12 +28,6 @@ variable "create_sns_topic" { default = true } -variable "hash_extra" { - description = "The string to add into hashing function. Useful when building same source path for different functions." - type = string - default = "" -} - variable "lambda_role" { description = "IAM role attached to the Lambda Function. If this is set then a role will not be created for you." type = string @@ -129,12 +117,6 @@ variable "sns_topic_lambda_feedback_sample_rate" { default = 100 } -variable "slack_emoji" { - description = "A custom emoji that will appear on Slack messages" - type = string - default = ":aws:" -} - variable "kms_key_arn" { description = "ARN of the KMS key used for decrypting slack webhook url" type = string @@ -286,17 +268,6 @@ variable "aws_powertools_service_name" { default = "appvia-notifications" } -variable "aws_powertools_log_level" { - description = "The log level for aws powertools" - type = string - default = "DEBUG" - - validation { - condition = contains(["TRACE", "DEBUG", "INFO", "WARNING", "ERROR"], var.aws_powertools_log_level) - error_message = "Valid values are TRACE, DEBUG, INFO, WARNING, ERROR" - } -} - variable "accounts_id_to_name" { description = "A mapping of account id and account name - used by notification lamdba to map an account ID to a human readable name" type = map(string) diff --git a/outputs.tf b/outputs.tf index ccbb9b8..ccca07f 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,5 +1,14 @@ - output "sns_topic_arn" { description = "The ARN of the SNS topic" value = local.sns_topic_arn } + +output "distributions" { + description = "The list of slack/teams distributions that are managed" + value = try(module.notify.distributions, "") +} + +output "channels_config" { + description = "The configuration data for each distribution channel" + value = local.channels_config +} \ No newline at end of file