Skip to content

Commit 2bca470

Browse files
committed
Support CLOUDWATCH_LOG_GROUP, SNS_TOPIC, SQS_QUEUE, SSM_RUN_COMMAND targets for eventbridge-rule
1 parent c954db9 commit 2bca470

File tree

5 files changed

+206
-18
lines changed

5 files changed

+206
-18
lines changed

modules/eventbridge-rule/README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,18 @@ This module creates following resources.
3636
| [aws_cloudwatch_event_target.event_bus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |
3737
| [aws_caller_identity.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
3838
| [aws_iam_policy_document.event_bus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
39+
| [aws_iam_policy_document.ssm_run_command](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
40+
| [aws_iam_policy_document.ssm_run_commands](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
41+
| [aws_partition.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
42+
| [aws_region.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
3943

4044
## Inputs
4145

4246
| Name | Description | Type | Default | Required |
4347
|------|-------------|------|---------|:--------:|
4448
| <a name="input_name"></a> [name](#input\_name) | (Required) A name of the rule for the event bus. | `string` | n/a | yes |
4549
| <a name="input_api_destination_targets"></a> [api\_destination\_targets](#input\_api\_destination\_targets) | (Optional) The configuration to manage the specified EventBridge API destination targets for the rule. Each item of `api_destination_targets` as defined below.<br> (Required) `id` - The unique ID of the target within the specified rule. Use this ID to reference the target when updating the rule.<br> (Required) `api_destination` - The Amazon Resource Name (ARN) of the target API destination.<br><br> (Optional) `execution_role` - The ARN (Amazon Resource Name) of the IAM role to be used for this target when the rule is triggered. Only required if `default_execution_role.enabled` is `false`.<br><br> (Optional) `dead_letter_queue` - The configuration for dead-letter queue of the rule target. Dead letter queues are used for collecting and storing events that were not successfully delivered to targets. `dead_letter_queue` as defined below.<br> (Optional) `enabled` - Whether to enable the dead letter queue. Defaults to `false`.<br> (Optional) `sqs_queue` - The Amazon Resource Name (ARN) of the SQS queue specified as the target for the dead letter queue.<br> (Optional) `retry_policy` - The configuration for retry policy of the rule target. Retry policies are used for specifying how many times to retry sending an event to a target after an error occurs. `retry_policy` as defined below.<br> (Optional) `maximum_event_age` - The maximum amount of time, in seconds, to continue to make retry attempts. Defaults to `86400` (1 hour).<br> (Optional) `maximum_retry_attempts` - The maximum number of times to retry sending an event to a target after an error occurs. Defaults to `185`. | <pre>list(object({<br> id = string<br> api_destination = string<br><br> execution_role = optional(string)<br><br> dead_letter_queue = optional(object({<br> enabled = optional(bool, false)<br> sqs_queue = optional(string)<br> }), {})<br> retry_policy = optional(object({<br> maximum_event_age = optional(number, 86400)<br> maximum_retry_attempts = optional(number, 185)<br> }), {})<br> }))</pre> | `[]` | no |
46-
| <a name="input_aws_service_targets"></a> [aws\_service\_targets](#input\_aws\_service\_targets) | (Optional) The configuration to manage the specified AWS service targets for the rule. Targets are the resources that are invoked when a rule is triggered. Each item of `aws_service_targets` as defined below.<br> (Required) `id` - The unique ID of the target within the specified rule. Use this ID to reference the target when updating the rule.<br> (Required) `target` - The Amazon Resource Name (ARN) of the target.<br><br> (Optional) `execution_role` - The ARN (Amazon Resource Name) of the IAM role to be used for this target when the rule is triggered. Only required if `default_execution_role.enabled` is `false`.<br><br> (Optional) `dead_letter_queue` - The configuration for dead-letter queue of the rule target. Dead letter queues are used for collecting and storing events that were not successfully delivered to targets. `dead_letter_queue` as defined below.<br> (Optional) `enabled` - Whether to enable the dead letter queue. Defaults to `false`.<br> (Optional) `sqs_queue` - The Amazon Resource Name (ARN) of the SQS queue specified as the target for the dead letter queue.<br> (Optional) `retry_policy` - The configuration for retry policy of the rule target. Retry policies are used for specifying how many times to retry sending an event to a target after an error occurs. `retry_policy` as defined below.<br> (Optional) `maximum_event_age` - The maximum amount of time, in seconds, to continue to make retry attempts. Defaults to `86400` (1 hour).<br> (Optional) `maximum_retry_attempts` - The maximum number of times to retry sending an event to a target after an error occurs. Defaults to `185`. | <pre>list(object({<br> id = string<br> target = string<br><br> execution_role = optional(string)<br><br> dead_letter_queue = optional(object({<br> enabled = optional(bool, false)<br> sqs_queue = optional(string)<br> }), {})<br> retry_policy = optional(object({<br> maximum_event_age = optional(number, 86400)<br> maximum_retry_attempts = optional(number, 185)<br> }), {})<br> }))</pre> | `[]` | no |
50+
| <a name="input_aws_service_targets"></a> [aws\_service\_targets](#input\_aws\_service\_targets) | (Optional) The configuration to manage the specified AWS service targets for the rule. Targets are the resources that are invoked when a rule is triggered. Each item of `aws_service_targets` as defined below.<br> (Required) `id` - The unique ID of the target within the specified rule. Use this ID to reference the target when updating the rule.<br> (Required) `type` - The AWS resource type of the target. Valid values are<br> `CLOUDWATCH_LOG_GROUP`, `SNS_TOPIC`, `SQS_QUEUE`, `SSM_RUN_COMMAND`.<br> (Optional) `cloudwatch_log_group` - The configuration for CloudWatch log group target. `cloudwatch_log_group` as defined below.<br> (Required) `arn` - The Amazon Resource Name (ARN) of the CloudWatch log group.<br> (Optional) `sns_topic` - The configuration for SNS topic target. `sns_topic` as defined below.<br> (Required) `arn` - The Amazon Resource Name (ARN) of the SNS topic.<br> (Optional) `sqs_queue` - The configuration for SQS queue target. `sqs_queue` as defined below.<br> (Required) `arn` - The Amazon Resource Name (ARN) of the SQS queue.<br> (Optional) `message_group_id` - The FIFO message group ID to use as the target.<br> (Optional) `ssm_run_command` - The configuration for SSM run command target. `ssm_run_command` as defined below.<br> (Required) `document` - The Amazon Resource Name (ARN) of the SSM document to run on the target.<br> (Required) `target_selector` - The target selector as a Map of key-value pairs. Valid keys are `InstanceIds` or `tag:${tag-name}`.<br><br> (Optional) `execution_role` - The ARN (Amazon Resource Name) of the IAM role to be used for this target when the rule is triggered. Only required if `default_execution_role.enabled` is `false`.<br><br> (Optional) `dead_letter_queue` - The configuration for dead-letter queue of the rule target. Dead letter queues are used for collecting and storing events that were not successfully delivered to targets. `dead_letter_queue` as defined below.<br> (Optional) `enabled` - Whether to enable the dead letter queue. Defaults to `false`.<br> (Optional) `sqs_queue` - The Amazon Resource Name (ARN) of the SQS queue specified as the target for the dead letter queue.<br> (Optional) `retry_policy` - The configuration for retry policy of the rule target. Retry policies are used for specifying how many times to retry sending an event to a target after an error occurs. `retry_policy` as defined below.<br> (Optional) `maximum_event_age` - The maximum amount of time, in seconds, to continue to make retry attempts. Defaults to `86400` (1 hour).<br> (Optional) `maximum_retry_attempts` - The maximum number of times to retry sending an event to a target after an error occurs. Defaults to `185`. | <pre>list(object({<br> id = string<br> type = string<br> cloudwatch_log_group = optional(object({<br> arn = string<br> }))<br> sns_topic = optional(object({<br> arn = string<br> }))<br> sqs_queue = optional(object({<br> arn = string<br> message_group_id = optional(string)<br> }))<br> ssm_run_command = optional(object({<br> document = string<br> target_selector = map(list(string))<br> }))<br><br> execution_role = optional(string)<br><br> dead_letter_queue = optional(object({<br> enabled = optional(bool, false)<br> sqs_queue = optional(string)<br> }), {})<br> retry_policy = optional(object({<br> maximum_event_age = optional(number, 86400)<br> maximum_retry_attempts = optional(number, 185)<br> }), {})<br> }))</pre> | `[]` | no |
4751
| <a name="input_default_execution_role"></a> [default\_execution\_role](#input\_default\_execution\_role) | (Optional) A configuration for the default execution role to use for the rule that is used for target invocation. Use `execution_role` if `default_execution_role.enabled` is `false`. `default_execution_role` as defined below.<br> (Optional) `enabled` - Whether to create the default execution role. Defaults to `true`.<br> (Optional) `name` - The name of the default execution role. Defaults to `aws-eventbridge-${var.event_bus}-rule-${var.name}`.<br> (Optional) `path` - The path of the default execution role. Defaults to `/`.<br> (Optional) `description` - The description of the default execution role.<br> (Optional) `policies` - A list of IAM policy ARNs to attach to the default execution role. Defaults to `[]`.<br> (Optional) `inline_policies` - A Map of inline IAM policies to attach to the default execution role. (`name` => `policy`). | <pre>object({<br> enabled = optional(bool, true)<br> name = optional(string)<br> path = optional(string, "/")<br> description = optional(string, "Managed by Terraform.")<br><br> policies = optional(list(string), [])<br> inline_policies = optional(map(string), {})<br> })</pre> | `{}` | no |
4852
| <a name="input_description"></a> [description](#input\_description) | (Optional) The description of the rule. | `string` | `"Managed by Terraform."` | no |
4953
| <a name="input_event_bus"></a> [event\_bus](#input\_event\_bus) | (Optional) The name or ARN of the event bus to associate with this rule. If you omit this, the `default` event bus is used. | `string` | `"default"` | no |

modules/eventbridge-rule/iam.tf

+79-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1+
data "aws_partition" "this" {}
12
data "aws_caller_identity" "this" {}
3+
data "aws_region" "this" {}
4+
5+
locals {
6+
partition = data.aws_partition.this.partition
7+
account_id = data.aws_caller_identity.this.account_id
8+
region = data.aws_region.this.name
9+
}
10+
211

312
###################################################
413
# IAM Role for Event Bus Rule
@@ -23,7 +32,7 @@ module "role" {
2332
conditions = [{
2433
key = "aws:SourceAccount"
2534
condition = "StringEquals"
26-
values = [data.aws_caller_identity.this.account_id]
35+
values = [local.account_id]
2736
}]
2837
}
2938
]
@@ -36,6 +45,12 @@ module "role" {
3645
}
3746
: {}
3847
),
48+
(one(data.aws_iam_policy_document.ssm_run_commands) != null
49+
? {
50+
"ssm-run-command-targets" = one(data.aws_iam_policy_document.ssm_run_commands).json
51+
}
52+
: {}
53+
),
3954
var.default_execution_role.inline_policies
4055
)
4156

@@ -66,3 +81,66 @@ data "aws_iam_policy_document" "event_bus" {
6681
}
6782
}
6883

84+
data "aws_iam_policy_document" "ssm_run_commands" {
85+
count = length(keys(data.aws_iam_policy_document.ssm_run_command)) > 0 ? 1 : 0
86+
87+
source_policy_documents = values(data.aws_iam_policy_document.ssm_run_command)[*].json
88+
}
89+
90+
data "aws_iam_policy_document" "ssm_run_command" {
91+
for_each = {
92+
for target in var.aws_service_targets :
93+
target.id => target
94+
if var.default_execution_role.enabled && target.type == "SSM_RUN_COMMAND"
95+
}
96+
97+
statement {
98+
effect = "Allow"
99+
actions = ["ssm:SendCommand"]
100+
resources = ["arn:${local.partition}:ssm:${local.region}:*:document/${regex("/([0-9A-Za-z_-]+)$", each.value.ssm_run_command.document)[0]}"]
101+
}
102+
103+
dynamic "statement" {
104+
for_each = {
105+
for k, v in each.value.ssm_run_command.target_selector :
106+
k => v
107+
if k == "InstanceIds"
108+
}
109+
110+
content {
111+
effect = "Allow"
112+
actions = ["ssm:SendCommand"]
113+
resources = [
114+
for instance_id in statement.value :
115+
"arn:${local.partition}:ec2:${local.region}:${local.account_id}:instance/${instance_id}"
116+
]
117+
}
118+
}
119+
dynamic "statement" {
120+
for_each = length([
121+
for k in keys(each.value.ssm_run_command.target_selector) :
122+
k
123+
if startswith(k, "tag:")
124+
]) > 0 ? ["go"] : []
125+
126+
content {
127+
effect = "Allow"
128+
actions = ["ssm:SendCommand"]
129+
resources = ["arn:${local.partition}:ec2:${local.region}:${local.account_id}:instance/*"]
130+
131+
dynamic "condition" {
132+
for_each = {
133+
for k, v in each.value.ssm_run_command.target_selector :
134+
k => v
135+
if startswith(k, "tag:")
136+
}
137+
138+
content {
139+
variable = condition.key
140+
test = "StringEquals"
141+
values = condition.value
142+
}
143+
}
144+
}
145+
}
146+
}

modules/eventbridge-rule/outputs.tf

+5-4
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ output "event_bus_targets" {
4646
value = {
4747
for id, target in aws_cloudwatch_event_target.event_bus :
4848
id => {
49-
id = target.id
49+
id = target.target_id
5050
event_bus = target.arn
5151
execution_role = target.role_arn
5252

@@ -67,7 +67,7 @@ output "api_destination_targets" {
6767
value = {
6868
for id, target in aws_cloudwatch_event_target.api_destination :
6969
id => {
70-
id = target.id
70+
id = target.target_id
7171
api_destination = target.arn
7272
execution_role = target.role_arn
7373

@@ -91,7 +91,7 @@ output "aws_service_targets" {
9191
value = {
9292
for id, target in aws_cloudwatch_event_target.aws_service :
9393
id => {
94-
id = target.id
94+
id = target.target_id
9595
target = target.arn
9696
execution_role = target.role_arn
9797

@@ -109,7 +109,8 @@ output "aws_service_targets" {
109109
z = {
110110
for k, v in target :
111111
k => v
112-
if !contains(["id", "arn", "role_arn", "dead_letter_config"], k)
112+
if !contains(["id", "arn", "role_arn", "dead_letter_config", "retry_policy",
113+
"event_bus_name", "rule", "target_id"], k)
113114
}
114115
}
115116
}

modules/eventbridge-rule/targets.tf

+55-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
locals {
2+
aws_service_types = {
3+
"CLOUDWATCH_LOG_GROUP" = {
4+
support_execution_role = false
5+
}
6+
"SNS_TOPIC" = {
7+
support_execution_role = false
8+
}
9+
"SQS_QUEUE" = {
10+
support_execution_role = false
11+
}
12+
"SSM_RUN_COMMAND" = {
13+
support_execution_role = true
14+
}
15+
}
16+
}
17+
18+
119
###################################################
220
# Rule Targets (Event Bus)
321
###################################################
@@ -83,9 +101,7 @@ resource "aws_cloudwatch_event_target" "api_destination" {
83101
# ecs_target - (Optional) Parameters used when you are using the rule to invoke Amazon ECS Task. Documented below. A maximum of 1 are allowed.
84102
# http_target - (Optional) Parameters used when you are using the rule to invoke an API Gateway REST endpoint. Documented below. A maximum of 1 is allowed.
85103
# kinesis_target - (Optional) Parameters used when you are using the rule to invoke an Amazon Kinesis Stream. Documented below. A maximum of 1 are allowed.
86-
# run_command_targets - (Optional) Parameters used when you are using the rule to invoke Amazon EC2 Run Command. Documented below. A maximum of 5 are allowed.
87104
# redshift_target - (Optional) Parameters used when you are using the rule to invoke an Amazon Redshift Statement. Documented below. A maximum of 1 are allowed.
88-
# sqs_target - (Optional) Parameters used when you are using the rule to invoke an Amazon SQS Queue. Documented below. A maximum of 1 are allowed.
89105
# sagemaker_pipeline_target - (Optional) Parameters used when you are using the rule to invoke an Amazon SageMaker Pipeline. Documented below. A maximum of 1 are allowed.
90106

91107
# NOTE:
@@ -104,14 +120,47 @@ resource "aws_cloudwatch_event_target" "aws_service" {
104120
event_bus_name = var.event_bus
105121
rule = aws_cloudwatch_event_rule.this.name
106122

123+
124+
## Target
107125
target_id = each.key
108-
arn = each.value.target
126+
arn = (
127+
each.value.type == "CLOUDWATCH_LOG_GROUP"
128+
? each.value.cloudwatch_log_group.arn
129+
: each.value.type == "SNS_TOPIC"
130+
? each.value.sns_topic.arn
131+
: each.value.type == "SQS_QUEUE"
132+
? each.value.sqs_queue.arn
133+
: each.value.type == "SSM_RUN_COMMAND"
134+
? each.value.ssm_run_command.document
135+
: null
136+
)
137+
138+
dynamic "sqs_target" {
139+
for_each = each.value.type == "SQS_QUEUE" ? [each.value.sqs_queue] : []
140+
iterator = target
141+
142+
content {
143+
message_group_id = target.value.message_group_id
144+
}
145+
}
146+
dynamic "run_command_targets" {
147+
for_each = each.value.type == "SSM_RUN_COMMAND" ? each.value.ssm_run_command.target_selector : {}
148+
iterator = target
149+
150+
content {
151+
key = target.key
152+
values = target.value
153+
}
154+
}
109155

110156

111157
## Permissions
112-
role_arn = (each.value.execution_role != null
113-
? each.value.execution_role
114-
: (var.default_execution_role.enabled ? module.role[0].arn : null)
158+
role_arn = (local.aws_service_types[each.value.type].support_execution_role
159+
? (each.value.execution_role != null
160+
? each.value.execution_role
161+
: (var.default_execution_role.enabled ? module.role[0].arn : null)
162+
)
163+
: null
115164
)
116165

117166

0 commit comments

Comments
 (0)