Skip to content

Latest commit

 

History

History
402 lines (324 loc) · 16.1 KB

File metadata and controls

402 lines (324 loc) · 16.1 KB

Fixit Cloud ☁️ Module: AWS EventBridge

Terraform module for defining AWS EventBridge resources (formerly "CloudWatch Events").

Table of Contents

EventBridge IAM

EventBridge, like many AWS services, uses a combination of identity and resource-based IAM policies. The type of policies required and the permissions they must provide vary depending on the nature of the event target. The table below lists EventBridge targets and the types of policies they require; each target links to a corresponding policy example below containing the minimum necessary permissions for each target type. Policy values which need to be replaced upon usage are wrapped in square brackets and capitalized (e.g., the region and account ID values in an EC2 ARN are provided as arn:aws:ec2:[REGION]:[ACCOUNT_ID]:instance/*.)

Cross-account and/or cross-region EventBridge configurations require additional permissions structures.

Target Type IAM Policy Type
EventBridge API destinations Identity-based policy
Kinesis streams Identity-based policy
Systems Manager run commands Identity-based policy
Step Functions state machines Identity-based policy
ECS tasks Identity-based policy
API Gateway endpoints Resource-based policy
CloudWatch Logs resources Resource-based policy
Lambda functions Resource-based policy
SNS topics Resource-based policy
SQS queues Resource-based policy

EventBridge IAM: Identity-Based Policies

For more info, see EventBridge identity-based policies documentation.

EventBridge API Destinations

If the target is an API destination, the role that you specify must include the following policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["events:InvokeApiDestination"],
      "Resource": ["arn:aws:events:::api-destination/*"]
    }
  ]
}

Kinesis Streams

If the target is a Kinesis stream, the role used to send event data to that target must include the following policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["kinesis:PutRecord"],
      "Resource": "*"
    }
  ]
}

Systems Manager Run Commands

If the target is Systems Manager run command, and you specify one or more InstanceIds values for the command, the role that you specify must include the following policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "ssm:SendCommand",
      "Effect": "Allow",
      "Resource": [
        "arn:aws:ec2:[REGION]:[ACCOUNT_ID]:instance/[INSTANCE_IDs]",
        "arn:aws:ssm:[REGION]:*:document/[DOCUMENT_NAME]"
      ]
    }
  ]
}

If the target is Systems Manager run command, and you specify one or more tags for the command, the role that you specify must include the following policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "ssm:SendCommand",
      "Effect": "Allow",
      "Resource": ["arn:aws:ec2:[REGION]:[ACCOUNT_ID]:instance/*"],
      "Condition": {
        "StringEquals": {
          "ec2:ResourceTag/*": ["[[tagValues]]"]
        }
      }
    },
    {
      "Action": "ssm:SendCommand",
      "Effect": "Allow",
      "Resource": ["arn:aws:ssm:[REGION]:*:document/[DOCUMENT_NAME]"]
    }
  ]
}

Step Functions State Machines

If the target is an AWS Step Functions state machine, the role that you specify must include the following policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["states:StartExecution"],
      "Resource": ["arn:aws:states:*:*:stateMachine:*"]
    }
  ]
}

ECS Tasks

If the target is an Amazon ECS task, the role that you specify must include the following policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["ecs:RunTask"],
      "Resource": [
        "arn:aws:ecs:*:[ACCOUNT_ID]:task-definition/[TASK_DEFINITION_NAME]"
      ],
      "Condition": {
        "ArnLike": {
          "ecs:cluster": "arn:aws:ecs:*:[ACCOUNT_ID]:cluster/[CLUSTER_NAME]"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": ["*"],
      "Condition": {
        "StringLike": {
          "iam:PassedToService": "ecs-tasks.amazonaws.com"
        }
      }
    }
  ]
}

EventBridge IAM: Resource-Based Policies

For more info, see EventBridge resource-based policies documentation.

API Gateway Endpoints

To invoke your Amazon API Gateway endpoint by using a EventBridge rule, add the following permission to the policy of your API Gateway endpoint:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "events.amazonaws.com"
      },
      "Action": "execute-api:Invoke",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:events:[REGION]:[ACCOUNT_ID]:rule/[RULE_NAME]"
        }
      },
      "Resource": ["execute-api:/stage/GET/api"]
    }
  ]
}

CloudWatch Logs Resources

When CloudWatch Logs is the target of a rule, EventBridge creates log streams, and CloudWatch Logs stores the text from the events as log entries. To allow EventBridge to create the log stream and log the events, CloudWatch Logs must include a resource-based policy that enables EventBridge to write to CloudWatch Logs.

If you use the AWS Management Console to add CloudWatch Logs as the target of a rule, the resource-based policy is created automatically. If you use the AWS CLI to add the target, and the policy doesn't already exist, you must create it.

The following example allows EventBridge to write to all log groups that have names that start with /aws/events/. If you use a different naming policy for these types of logs, adjust the example accordingly.

{
  "Statement": [
    {
      "Action": ["logs:CreateLogStream", "logs:PutLogEvents"],
      "Effect": "Allow",
      "Principal": {
        "Service": ["events.amazonaws.com", "delivery.logs.amazonaws.com"]
      },
      "Resource": "arn:aws:logs:[REGION]:[ACCOUNT_ID]:log-group:/aws/events/*:*",
      "Sid": "TrustEventsToStoreLogEvent"
    }
  ],
  "Version": "2012-10-17"
}

Lambda Functions

To invoke your AWS Lambda function by using a EventBridge rule, add the following permission to the policy of your Lambda function:

{
  "Effect": "Allow",
  "Action": "lambda:InvokeFunction",
  "Resource": "arn:aws:lambda:[REGION]:[ACCOUNT_ID]:function:[FUNCTION_NAME]",
  "Principal": {
    "Service": "events.amazonaws.com"
  },
  "Condition": {
    "ArnLike": {
      "AWS:SourceArn": "arn:aws:events:[REGION]:[ACCOUNT_ID]:rule/[RULE_NAME]"
    }
  },
  "Sid": "InvokeLambdaFunction"
}

SNS Topics

{
  "Sid": "PublishEventsToMyTopic",
  "Effect": "Allow",
  "Principal": {
    "Service": "events.amazonaws.com"
  },
  "Action": "sns:Publish",
  "Resource": "arn:aws:sns:[REGION]:[ACCOUNT_ID]:[TOPIC_NAME]"
}

SQS Queues

{
  "Sid": "EventsToMyQueue",
  "Effect": "Allow",
  "Principal": {
    "Service": "events.amazonaws.com"
  },
  "Action": "sqs:SendMessage",
  "Resource": "arn:aws:sqs:[REGION]:[ACCOUNT_ID]:[QUEUE_NAME]",
  "Condition": {
    "ArnEquals": {
      "aws:SourceArn": "arn:aws:events:[REGION]:[ACCOUNT_ID]:rule/[RULE_NAME]"
    }
  }
}

Useful Links


⚙️ Module Usage

Usage Examples

Requirements

Name Version
terraform 1.3.2
aws ~> 4.34.0

Providers

Name Version
aws ~> 4.34.0

Modules

No modules.

Resources

Name Type
aws_cloudwatch_event_bus.map resource
aws_cloudwatch_event_bus_policy.map resource
aws_cloudwatch_event_rule.map resource
aws_cloudwatch_event_target.map resource
aws_iam_policy_document.Event_Bus_Policies_Map data source

Inputs

Name Description Type Default Required
event_buses (Optional) Map of EventBridge Event Bus names to config objects. To configure an
event bus policy, you can either provide a JSON-encoded string to "event_bus_policy_json",
or a list of policy statements to "event_bus_policy_statements".
Within policy statements, to include the ARNs of event resources which are created within
the same module call in your "resources" list(s), provide the event bus/target/rule NAME in
"resources" and the name will be replaced by the ARN in the final policy document. Note that
using this feature requires unique resource names; i.e., having an event BUS and event RULE
with the same name would result in an error.
map(
# map keys: Event Bus names
object({
event_source_name = optional(string)
tags = optional(map(string))
event_bus_policy_json = optional(string)
event_bus_policy_statements = optional(list(object({
sid = optional(string)
effect = string
principals = optional(map(
# map keys: "AWS", "Service", and/or "Federated"
list(string)
))
actions = list(string)
resources = optional(list(string))
conditions = optional(map(
# map keys: IAM condition operators (e.g., "StringEquals", "ArnLike")
object({
key = string
values = list(string)
})
))
})))
})
)
{} no
event_rules (Optional) Map of EventBridge rule names to config objects. A "role_arn"
must be provided for rules which invoke targets that are API destinations,
Kinesis streams, Systems Manager Run Commands, Step Functions state machines,
or ECS tasks.
map(
# map keys: event rule names
object({
enabled = optional(bool)
description = optional(string)
role_arn = optional(string)
schedule_expression = optional(string)
event_pattern = optional(string)
event_bus_name = optional(string)
tags = optional(map(string))
})
)
{} no
event_targets (Optional) Map of EventBridge rule target assignment IDs to config objects.
Target assignment IDs can be any valid name/ID string. A "role_arn" must be
provided if the target is an ECS task, EC2 instance, Kinesis data stream,
Step Functions state machine, or Event Bus in a different account or region.
Target event input can be configured with either "input", "input_path", or
"input_transformer". Note that each rule can have at most 5 event targets.
map(
# map keys: event target assignment IDs
object({
rule_name = string
target_arn = string
event_bus_name = optional(string)
role_arn = optional(string)
retry_policy = optional(object({
maximum_event_age_in_seconds = optional(number)
maximum_retry_attempts = optional(number)
}))
input = optional(string)
input_path = optional(string)
input_transformer = optional(object({
input_template = string # JSON-encoded string
input_paths = optional(map(string))
}))
})
)
{} no

Outputs

Name Description
Event_Bus_Policies Map of EventBridge Event Bus Policy resource objects.
Event_Buses Map of EventBridge Event Bus resource objects.
Event_Rules Map of EventBridge Event Rule resource objects.
Event_Targets Map of EventBridge Event Target resource objects.

📝 License

All scripts and source code contained herein are for commercial use only by Nerdware, LLC.

See LICENSE for more information.

💬 Contact

Trevor Anderson - @TeeRevTweets - Trevor@Nerdware.cloud

     

Dare Mighty Things.