diff --git a/.chglog/CHANGELOG.tpl.md b/.chglog/CHANGELOG.tpl.md
new file mode 100644
index 0000000..687d702
--- /dev/null
+++ b/.chglog/CHANGELOG.tpl.md
@@ -0,0 +1,111 @@
+# Change Log
+
+All notable changes to this project will be documented in this file.
+
+{{ if .Versions -}}
+
+## [Unreleased]
+{{ if .Unreleased.CommitGroups -}}
+{{ range .Unreleased.CommitGroups -}}
+### {{ .Title }}
+{{ range .Commits -}}
+{{/* SKIPPING RULES - START */ -}}
+{{- if not (hasPrefix .Subject "Updated CHANGELOG") -}}
+{{- if not (contains .Subject "[ci skip]") -}}
+{{- if not (contains .Subject "[skip ci]") -}}
+{{- if not (hasPrefix .Subject "Merge pull request ") -}}
+{{- if not (hasPrefix .Subject "Added CHANGELOG") -}}
+{{- /* SKIPPING RULES - END */ -}}
+- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
+{{/* SKIPPING RULES - START */ -}}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+{{/* SKIPPING RULES - END */ -}}
+{{ end }}
+{{ end -}}
+{{ else }}
+{{ range .Unreleased.Commits -}}
+{{/* SKIPPING RULES - START */ -}}
+{{- if not (hasPrefix .Subject "Updated CHANGELOG") -}}
+{{- if not (contains .Subject "[ci skip]") -}}
+{{- if not (contains .Subject "[skip ci]") -}}
+{{- if not (hasPrefix .Subject "Merge pull request ") -}}
+{{- if not (hasPrefix .Subject "Added CHANGELOG") -}}
+{{- /* SKIPPING RULES - END */ -}}
+- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
+{{/* SKIPPING RULES - START */ -}}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+{{/* SKIPPING RULES - END */ -}}
+{{ end }}
+{{ end -}}
+{{ end -}}
+
+{{ range .Versions }}
+
+## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }}
+{{ if .CommitGroups -}}
+{{ range .CommitGroups -}}
+### {{ .Title }}
+{{ range .Commits -}}
+{{/* SKIPPING RULES - START */ -}}
+{{- if not (hasPrefix .Subject "Updated CHANGELOG") -}}
+{{- if not (contains .Subject "[ci skip]") -}}
+{{- if not (contains .Subject "[skip ci]") -}}
+{{- if not (hasPrefix .Subject "Merge pull request ") -}}
+{{- if not (hasPrefix .Subject "Added CHANGELOG") -}}
+{{- /* SKIPPING RULES - END */ -}}
+- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
+{{/* SKIPPING RULES - START */ -}}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+{{/* SKIPPING RULES - END */ -}}
+{{ end }}
+{{ end -}}
+{{ else }}
+{{ range .Commits -}}
+{{/* SKIPPING RULES - START */ -}}
+{{- if not (hasPrefix .Subject "Updated CHANGELOG") -}}
+{{- if not (contains .Subject "[ci skip]") -}}
+{{- if not (contains .Subject "[skip ci]") -}}
+{{- if not (hasPrefix .Subject "Merge pull request ") -}}
+{{- if not (hasPrefix .Subject "Added CHANGELOG") -}}
+{{- /* SKIPPING RULES - END */ -}}
+- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
+{{/* SKIPPING RULES - START */ -}}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+{{/* SKIPPING RULES - END */ -}}
+{{ end }}
+{{ end -}}
+
+{{- if .NoteGroups -}}
+{{ range .NoteGroups -}}
+### {{ .Title }}
+{{ range .Notes }}
+{{ .Body }}
+{{ end }}
+{{ end -}}
+{{ end -}}
+{{ end -}}
+
+{{- if .Versions }}
+[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD
+{{ range .Versions -}}
+{{ if .Tag.Previous -}}
+[{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}
+{{ end -}}
+{{ end -}}
+{{ end -}}
diff --git a/.chglog/config.yml b/.chglog/config.yml
new file mode 100644
index 0000000..4f6bab9
--- /dev/null
+++ b/.chglog/config.yml
@@ -0,0 +1,11 @@
+---
+style: github
+template: CHANGELOG.tpl.md
+info:
+ title: CHANGELOG
+ repository_url: https://github.com/svenlito/terraform-aws-eventbridge
+options:
+ header:
+ pattern: "^(.*)$"
+ pattern_maps:
+ - Subject
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..069c4d4
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,32 @@
+# EditorConfig is awesome: http://EditorConfig.org
+# Uses editorconfig to maintain consistent coding styles
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 2
+indent_style = space
+insert_final_newline = true
+max_line_length = 80
+trim_trailing_whitespace = true
+
+[*.{hcl}]
+indent_size = 2
+indent_style = space
+
+[*.md]
+max_line_length = 0
+trim_trailing_whitespace = false
+
+# Tab indentation (no size specified)
+[Makefile]
+tab_width = 2
+indent_style = tab
+
+# Don't wrap lines for Git commit messages
+[COMMIT_EDITMSG]
+max_line_length = 0
diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml
new file mode 100644
index 0000000..2be2f5d
--- /dev/null
+++ b/.github/workflows/pre-commit.yml
@@ -0,0 +1,102 @@
+---
+name: Pre-Commit
+
+on:
+ pull_request:
+ push:
+ branches:
+ - master
+
+jobs:
+ # Min Terraform version(s)
+ getDirectories:
+ name: Get root directories
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Install Python
+ uses: actions/setup-python@v2
+ - name: Build matrix
+ id: matrix
+ run: |
+ DIRS=$(python -c "import json; import glob; print(json.dumps([x.replace('/versions.tf', '') for x in glob.glob('./**/versions.tf', recursive=True)]))")
+ echo "::set-output name=directories::$DIRS"
+ outputs:
+ directories: ${{ steps.matrix.outputs.directories }}
+
+ preCommitMinVersions:
+ name: Min TF validate
+ needs: getDirectories
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ directory: ${{ fromJson(needs.getDirectories.outputs.directories) }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Install Python
+ uses: actions/setup-python@v2
+ - name: Terraform min/max versions
+ id: minMax
+ uses: clowdhaus/terraform-min-max@v1.0.1
+ with:
+ directory: ${{ matrix.directory }}
+ - name: Install Terraform v${{ steps.minMax.outputs.minVersion }}
+ uses: hashicorp/setup-terraform@v1
+ with:
+ terraform_version: ${{ steps.minMax.outputs.minVersion }}
+ - name: Install pre-commit dependencies
+ run: pip install pre-commit
+ - name: Execute pre-commit
+ # Run only validate pre-commit check on min version supported
+ if: ${{ matrix.directory != '.' }}
+ run:
+ pre-commit run terraform_validate --color=always --show-diff-on-failure --files ${{ matrix.directory }}/*
+ - name: Execute pre-commit
+ # Run only validate pre-commit check on min version supported
+ if: ${{ matrix.directory == '.' }}
+ run:
+ pre-commit run terraform_validate --color=always --show-diff-on-failure --files $(ls *.tf)
+
+ # Max Terraform version
+ getBaseVersion:
+ name: Module max TF version
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Terraform min/max versions
+ id: minMax
+ uses: clowdhaus/terraform-min-max@v1.0.1
+ outputs:
+ minVersion: ${{ steps.minMax.outputs.minVersion }}
+ maxVersion: ${{ steps.minMax.outputs.maxVersion }}
+
+ preCommitMaxVersion:
+ name: Max TF pre-commit
+ runs-on: ubuntu-latest
+ needs: getBaseVersion
+ strategy:
+ fail-fast: false
+ matrix:
+ version:
+ - ${{ needs.getBaseVersion.outputs.maxVersion }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Install Python
+ uses: actions/setup-python@v2
+ - name: Install Terraform v${{ matrix.version }}
+ uses: hashicorp/setup-terraform@v1
+ with:
+ terraform_version: ${{ matrix.version }}
+ - name: Install pre-commit dependencies
+ run: |
+ pip install pre-commit
+ curl -L "$(curl -s https://api.github.com/repos/terraform-docs/terraform-docs/releases/latest | grep -o -E "https://.+?-linux-amd64" | head -n1)" > terraform-docs && chmod +x terraform-docs && sudo mv terraform-docs /usr/bin/
+ curl -L "$(curl -s https://api.github.com/repos/terraform-linters/tflint/releases/latest | grep -o -E "https://.+?_linux_amd64.zip")" > tflint.zip && unzip tflint.zip && rm tflint.zip && sudo mv tflint /usr/bin/
+ - name: Execute pre-commit
+ # Run all pre-commit checks on max version supported
+ if: ${{ matrix.version == needs.getBaseVersion.outputs.maxVersion }}
+ run: pre-commit run --color=always --show-diff-on-failure --all-files
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..627f068
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,32 @@
+.DS_Store
+
+# Local .terraform directories
+**/.terraform/*
+
+# Terraform lockfile
+.terraform.lock.hcl
+
+# .tfstate files
+*.tfstate
+*.tfstate.*
+*.tfplan
+
+# Crash log files
+crash.log
+
+# Exclude all .tfvars files, which are likely to contain sentitive data, such as
+# password, private keys, and other secrets. These should not be part of version
+# control as they are data points which are potentially sensitive and subject
+# to change depending on the environment.
+*.tfvars
+
+# Ignore override files as they are usually used to override resources locally and so
+# are not checked in
+override.tf
+override.tf.json
+*_override.tf
+*_override.tf.json
+
+# Ignore CLI configuration files
+.terraformrc
+terraform.rc
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..ed7b682
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,27 @@
+---
+repos:
+ - repo: git://github.com/antonbabenko/pre-commit-terraform
+ rev: v1.48.0
+ hooks:
+ - id: terraform_fmt
+ - id: terraform_validate
+ - id: terraform_docs
+ - id: terraform_tflint
+ args:
+ - '--args=--only=terraform_deprecated_interpolation'
+ - '--args=--only=terraform_deprecated_index'
+ - '--args=--only=terraform_unused_declarations'
+ - '--args=--only=terraform_comment_syntax'
+ - '--args=--only=terraform_documented_outputs'
+ - '--args=--only=terraform_documented_variables'
+ - '--args=--only=terraform_typed_variables'
+ - '--args=--only=terraform_module_pinned_source'
+ - '--args=--only=terraform_naming_convention'
+ - '--args=--only=terraform_required_version'
+ - '--args=--only=terraform_required_providers'
+ - '--args=--only=terraform_standard_module_structure'
+ - '--args=--only=terraform_workspace_remote'
+ - repo: git://github.com/pre-commit/pre-commit-hooks
+ rev: v3.4.0
+ hooks:
+ - id: check-merge-conflict
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..e69de29
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..fe36d3a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2021 Sven Lito
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..558dac5
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,7 @@
+.PHONY: changelog release
+
+changelog:
+ git-chglog -o CHANGELOG.md --next-tag `semtag final -s minor -o`
+
+release:
+ semtag final -s minor
diff --git a/README.md b/README.md
index 7718812..96bdc2b 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,308 @@
-# terraform-aws-eventbridge
+# AWS EventBridge Terraform module
+
+Terraform module to create EventBridge resources.
+
+The following resources are currently supported:
+
+* [Cloudwatch Event Archive](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_archive)
+* [Cloudwatch Event Bus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_bus)
+* [Cloudwatch Event Permission](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_permission)
+* [Cloudwatch Event Rule](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule)
+* [Cloudwatch Event Target](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target)
+
+## Features
+
+- [x] Creates AWS EventBridge Resources
+- [x] Support AWS EventBridge Archives and Replays
+- [x] Conditional creation for many types of resources
+- [x] Support IAM policy attachments and various ways to create and attach additional policies
+- [ ] Support monitoring usage with Cloudwatch Metrics
+
+## Usage
+
+### EventBridge Bus
+
+```hcl
+module "eventbridge" {
+ source = ""
+
+ bus_name = "my-bus"
+
+ tags = {
+ Name = "my-bus"
+ }
+}
+```
+
+### EventBridge Rule
+
+```hcl
+module "eventbridge" {
+ source = ""
+
+ bus_name = "my-bus"
+
+ create_targets = false
+
+ rules = {
+ logs = {
+ description = "Capture log data"
+ event_pattern = jsonencode({ "source" : ["my.app.logs"] })
+ }
+ }
+
+ tags = {
+ Name = "my-bus"
+ }
+}
+```
+
+### EventBridge Target
+
+```hcl
+module "eventbridge" {
+ source = ""
+
+ bus_name = "my-bus"
+
+ rules = {
+ logs = {
+ description = "Capture log data"
+ event_pattern = jsonencode({ "source" : ["my.app.logs"] })
+ }
+ }
+
+ targets = {
+ logs = [
+ {
+ name = "send-logs-to-sqs"
+ arn = aws_sqs_queue.queue.arn
+ },
+ {
+ name = "send-logs-to-cloudwatch"
+ arn = aws_cloudwatch_log_stream.logs.arn
+ }
+ ]
+ }
+
+ tags = {
+ Name = "my-bus"
+ }
+}
+```
+
+### EventBridge Archive
+
+```hcl
+module "eventbridge_with_archive" {
+ source = ""
+
+ bus_name = "my-bus"
+
+ create_archives = true
+
+ archive_config = [
+ {
+ name = "my-bus-launch-archive",
+ description = "EC2 AutoScaling Event archive",
+ retention_days = 1
+ event_pattern = < 0`.
+ 3. `policy` - ARN of existing IAM policy, when `attach_policy = true`.
+ 4. `policies` - List of ARNs of existing IAM policies, when `attach_policies = true` and `number_of_policies > 0`.
+ 5. `policy_statements` - Map of maps to define IAM statements which will be generated as IAM policy. Requires `attach_policy_statements = true`. See `examples/complete` for more information.
+
+## Conditional creation
+
+Sometimes you need to have a way to create resources conditionally but Terraform does not allow usage of `count` inside `module` block, so the solution is to specify `create` arguments.
+
+```hcl
+module "eventbridge" {
+ source = ""
+
+ create = false # to disable all resources
+
+ create_bus = false # to control creation of the EventBridge Bus and related resources
+ create_rule = false # to control creation of EventBridge Rules and related resources
+ create_targets = false # to control creation of EventBridge Targets and related resources
+ create_archives = false # to control creation of EventBridge Archives
+ create_permissions = false # to control creation of EventBridge Permissions
+ create_role = false # to control creation of the IAM role and policies required for EventBridge
+
+ attach_kinesis_policy = false
+ attach_kinesis_firehose_policy = false
+ attach_sqs_policy = false
+ attach_ecs_policy = false
+ attach_lambda_policy = false
+ attach_sfn_policy = false
+ attach_cloudwatch_policy = false
+ attach_tracing_policy = false
+
+ # ... omitted
+}
+```
+
+## Examples
+
+* [Complete](/examples/complete)
+* [Simple](/examples/simple)
+* [Archive](/examples/with-archive)
+* [Permissions](/examples/with-permissions)
+* [SQS Target](/examples/sqs-target)
+* [API-Gateway](/examples/api-gateway-event-source)
+* [Input Transformation](/examples/transform-input)
+* [Step Function Target](/examples/step-function-target)
+
+## Change log
+
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| terraform | >= 0.12.26 |
+| aws | >= 3.19 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| aws | >= 3.19 |
+
+## Modules
+
+No Modules.
+
+## Resources
+
+| Name |
+|------|
+| [aws_cloudwatch_event_archive](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_archive) |
+| [aws_cloudwatch_event_bus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_bus) |
+| [aws_cloudwatch_event_permission](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_permission) |
+| [aws_cloudwatch_event_rule](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) |
+| [aws_cloudwatch_event_target](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) |
+| [aws_iam_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy) |
+| [aws_iam_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) |
+| [aws_iam_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment) |
+| [aws_iam_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) |
+| [aws_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) |
+| [aws_iam_role_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| archive\_config | A list of objects with the EventBridge Archive definitions. | `list(any)` | `[]` | no |
+| attach\_cloudwatch\_policy | Controls whether the Cloudwatch policy should be added to IAM role for EventBridge Target | `bool` | `false` | no |
+| attach\_ecs\_policy | Controls whether the ECS policy should be added to IAM role for EventBridge Target | `bool` | `false` | no |
+| attach\_kinesis\_firehose\_policy | Controls whether the Kinesis Firehose policy should be added to IAM role for EventBridge Target | `bool` | `false` | no |
+| attach\_kinesis\_policy | Controls whether the Kinesis policy should be added to IAM role for EventBridge Target | `bool` | `false` | no |
+| attach\_lambda\_policy | Controls whether the Lambda Function policy should be added to IAM role for EventBridge Target | `bool` | `false` | no |
+| attach\_policies | Controls whether list of policies should be added to IAM role | `bool` | `false` | no |
+| attach\_policy | Controls whether policy should be added to IAM role | `bool` | `false` | no |
+| attach\_policy\_json | Controls whether policy\_json should be added to IAM role | `bool` | `false` | no |
+| attach\_policy\_jsons | Controls whether policy\_jsons should be added to IAM role | `bool` | `false` | no |
+| attach\_policy\_statements | Controls whether policy\_statements should be added to IAM role | `bool` | `false` | no |
+| attach\_sfn\_policy | Controls whether the StepFunction policy should be added to IAM role for EventBridge Target | `bool` | `false` | no |
+| attach\_sqs\_policy | Controls whether the SQS policy should be added to IAM role for EventBridge Target | `bool` | `false` | no |
+| attach\_tracing\_policy | Controls whether X-Ray tracing policy should be added to IAM role for EventBridge | `bool` | `false` | no |
+| bus\_name | A unique name for your EventBridge Bus | `string` | `""` | no |
+| cloudwatch\_target\_arns | The Amazon Resource Name (ARN) of the Cloudwatch Log Streams you want to use as EventBridge targets | `list(string)` | `[]` | no |
+| create | Controls whether resources should be created | `bool` | `true` | no |
+| create\_archives | Controls whether EventBridge Archive resources should be created | `bool` | `false` | no |
+| create\_bus | Controls whether EventBridge Bus resource should be created | `bool` | `true` | no |
+| create\_permissions | Controls whether EventBridge Permission resources should be created | `bool` | `true` | no |
+| create\_role | Controls whether IAM role for Lambda Function should be created | `bool` | `true` | no |
+| create\_rules | Controls whether EventBridge Rule resources should be created | `bool` | `true` | no |
+| create\_targets | Controls whether EventBridge Target resources should be created | `bool` | `true` | no |
+| ecs\_target\_arns | The Amazon Resource Name (ARN) of the AWS ECS Tasks you want to use as EventBridge targets | `list(string)` | `[]` | no |
+| kinesis\_firehose\_target\_arns | The Amazon Resource Name (ARN) of the Kinesis Firehose Delivery Streams you want to use as EventBridge targets | `list(string)` | `[]` | no |
+| kinesis\_target\_arns | The Amazon Resource Name (ARN) of the Kinesis Streams you want to use as EventBridge targets | `list(string)` | `[]` | no |
+| lambda\_target\_arns | The Amazon Resource Name (ARN) of the Lambda Functions you want to use as EventBridge targets | `list(string)` | `[]` | no |
+| number\_of\_policies | Number of policies to attach to IAM role | `number` | `0` | no |
+| number\_of\_policy\_jsons | Number of policies JSON to attach to IAM role | `number` | `0` | no |
+| permission\_config | A list of objects with EventBridge Permission definitions. | `list(any)` | `[]` | no |
+| policies | List of policy statements ARN to attach to IAM role | `list(string)` | `[]` | no |
+| policy | An additional policy document ARN to attach to IAM role | `string` | `null` | no |
+| policy\_json | An additional policy document as JSON to attach to IAM role | `string` | `null` | no |
+| policy\_jsons | List of additional policy documents as JSON to attach to IAM role | `list(string)` | `[]` | no |
+| policy\_statements | Map of dynamic policy statements to attach to IAM role | `any` | `{}` | no |
+| role\_description | Description of IAM role to use for Lambda Function | `string` | `null` | no |
+| role\_force\_detach\_policies | Specifies to force detaching any policies the IAM role has before destroying it. | `bool` | `true` | no |
+| role\_name | Name of IAM role to use for Lambda Function | `string` | `null` | no |
+| role\_path | Path of IAM role to use for Lambda Function | `string` | `null` | no |
+| role\_permissions\_boundary | The ARN of the policy that is used to set the permissions boundary for the IAM role used by Lambda Function | `string` | `null` | no |
+| role\_tags | A map of tags to assign to IAM role | `map(string)` | `{}` | no |
+| rules | A map of objects with EventBridge Rule definitions. | `map(any)` | `{}` | no |
+| sfn\_target\_arns | The Amazon Resource Name (ARN) of the StepFunctions you want to use as EventBridge targets | `list(string)` | `[]` | no |
+| sqs\_target\_arns | The Amazon Resource Name (ARN) of the AWS SQS Queues you want to use as EventBridge targets | `list(string)` | `[]` | no |
+| tags | A map of tags to assign to resources. | `map(string)` | `{}` | no |
+| targets | A Map of objects with EventBridge Target definitions. | `any` | `{}` | no |
+| trusted\_entities | Step Function additional trusted entities for assuming roles (trust relationship) | `list(string)` | `[]` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| eventbridge\_role\_arn | The ARN of the IAM role created for EventBridge |
+| eventbridge\_role\_name | The name of the IAM role created for EventBridge |
+| this\_eventbridge\_archive\_arns | The EventBridge Archive Arns created |
+| this\_eventbridge\_bus\_arn | The EventBridge Bus Arn |
+| this\_eventbridge\_bus\_name | The EventBridge Bus Name |
+| this\_eventbridge\_permission\_ids | The EventBridge Permission Arns created |
+| this\_eventbridge\_rule\_arns | The EventBridge Rule ARNs created |
+| this\_eventbridge\_rule\_ids | The EventBridge Rule IDs created |
+
+
+## Authors
+
+Module managed by [Sven Lito](https://github.com/svenlito). Check out [serverless.tf](https://serverless.tf) to learn more about doing serverless with Terraform.
+
+## License
+
+Apache 2 Licensed. See LICENSE for full details.
diff --git a/examples/api-gateway-event-source/README.md b/examples/api-gateway-event-source/README.md
new file mode 100644
index 0000000..39ae696
--- /dev/null
+++ b/examples/api-gateway-event-source/README.md
@@ -0,0 +1,16 @@
+# EventBridge API Gateway Event Source
+
+Configuration in this directory creates EventBridge resource configuration including an API Gateway and a SQS queue.
+
+## Usage
+
+To run this example you need to execute:
+
+```bash
+$ terraform init
+$ terraform plan
+$ terraform apply
+```
+
+Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
+
diff --git a/examples/api-gateway-event-source/main.tf b/examples/api-gateway-event-source/main.tf
new file mode 100644
index 0000000..8e939ee
--- /dev/null
+++ b/examples/api-gateway-event-source/main.tf
@@ -0,0 +1,158 @@
+terraform {
+ required_version = ">= 0.14.0"
+
+ required_providers {
+ aws = ">= 3.19"
+ random = ">= 0"
+ }
+}
+
+provider "aws" {
+ region = "ap-southeast-1"
+
+ # Make it faster by skipping something
+ skip_get_ec2_platforms = true
+ skip_metadata_api_check = true
+ skip_region_validation = true
+ skip_credentials_validation = true
+ skip_requesting_account_id = true
+}
+
+module "eventbridge" {
+ source = "../../"
+
+ bus_name = "${random_pet.this.id}-bus"
+
+ attach_sqs_policy = true
+ sqs_target_arns = [
+ aws_sqs_queue.queue.arn,
+ aws_sqs_queue.dlq.arn
+ ]
+
+ rules = {
+ orders_create = {
+ description = "Capture all created orders",
+ event_pattern = jsonencode({
+ "detail-type" : ["Order Create"],
+ "source" : ["api.gateway.orders.create"]
+ })
+ }
+ }
+
+ targets = {
+ orders_create = [
+ {
+ name = "send-orders-to-sqs"
+ arn = aws_sqs_queue.queue.arn
+ dead_letter_arn = aws_sqs_queue.dlq.arn
+ target_id = "send-orders-to-sqs"
+ }
+ ]
+ }
+
+ tags = {
+ Name = "${random_pet.this.id}-bus"
+ }
+}
+
+
+##################
+# Extra resources
+##################
+
+resource "random_pet" "this" {
+ length = 2
+}
+
+module "api_gateway" {
+ source = "terraform-aws-modules/apigateway-v2/aws"
+ version = "0.14.0"
+
+ name = "${random_pet.this.id}-http"
+ description = "My ${random_pet.this.id} HTTP API Gateway"
+ protocol_type = "HTTP"
+
+ create_api_domain_name = false
+
+ integrations = {
+ "POST /orders/create" = {
+ integration_type = "AWS_PROXY"
+ integration_subtype = "EventBridge-PutEvents"
+ credentials_arn = module.apigateway_put_events_to_eventbridge_role.this_iam_role_arn
+
+ request_parameters = jsonencode({
+ EventBusName = module.eventbridge.this_eventbridge_bus_name,
+ Source = "api.gateway.orders.create",
+ DetailType = "Order Create",
+ Detail = "$request.body",
+ Time = "$context.requestTimeEpoch"
+ })
+
+ payload_format_version = "1.0"
+ }
+ }
+}
+
+module "apigateway_put_events_to_eventbridge_role" {
+ source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role"
+ version = "3.13.0"
+
+ create_role = true
+
+ role_name = "apigateway-put-events-to-eventbridge"
+ role_requires_mfa = false
+
+ trusted_role_services = [
+ "apigateway.amazonaws.com"
+ ]
+
+ custom_role_policy_arns = [
+ module.apigateway_put_events_to_eventbridge_policy.arn
+ ]
+}
+
+module "apigateway_put_events_to_eventbridge_policy" {
+ source = "terraform-aws-modules/iam/aws//modules/iam-policy"
+ version = "3.13.0"
+
+ name = "apigateway-put-events-to-eventbridge"
+ path = "/"
+ description = "Allow PutEvents to EventBridge"
+
+ policy = data.aws_iam_policy_document.apigateway_put_events_to_eventbridge_policy.json
+}
+
+data "aws_iam_policy_document" "apigateway_put_events_to_eventbridge_policy" {
+ statement {
+ sid = "AllowPutEvents"
+ actions = ["events:PutEvents"]
+ resources = [module.eventbridge.this_eventbridge_bus_arn]
+ }
+
+ depends_on = [module.eventbridge]
+}
+
+resource "aws_sqs_queue" "dlq" {
+ name = "${random_pet.this.id}-dlq"
+}
+
+resource "aws_sqs_queue" "queue" {
+ name = random_pet.this.id
+}
+
+resource "aws_sqs_queue_policy" "queue" {
+ queue_url = aws_sqs_queue.queue.id
+ policy = data.aws_iam_policy_document.queue.json
+}
+
+data "aws_iam_policy_document" "queue" {
+ statement {
+ sid = "AllowSendMessage"
+ actions = ["sqs:SendMessage"]
+ principals {
+ type = "Service"
+ identifiers = ["events.amazonaws.com"]
+ }
+ resources = [aws_sqs_queue.queue.arn]
+ }
+}
diff --git a/examples/api-gateway-event-source/outputs.tf b/examples/api-gateway-event-source/outputs.tf
new file mode 100644
index 0000000..10f1f4e
--- /dev/null
+++ b/examples/api-gateway-event-source/outputs.tf
@@ -0,0 +1,28 @@
+output "this_eventbridge_bus_name" {
+ description = "The EventBridge Bus Name"
+ value = module.eventbridge.this_eventbridge_bus_name
+}
+
+output "this_eventbridge_bus_arn" {
+ description = "The EventBridge Bus Arn"
+ value = module.eventbridge.this_eventbridge_bus_arn
+}
+output "this_eventbridge_rule_ids" {
+ description = "The EventBridge Rule IDs created"
+ value = module.eventbridge.this_eventbridge_rule_ids
+}
+
+output "this_eventbridge_rule_arns" {
+ description = "The EventBridge Rule ARNs created"
+ value = module.eventbridge.this_eventbridge_rule_arns
+}
+
+output "eventbridge_role_arn" {
+ description = "The ARN of the IAM role created for EventBridge"
+ value = module.eventbridge.eventbridge_role_arn
+}
+
+output "eventbridge_role_name" {
+ description = "The name of the IAM role created for EventBridge"
+ value = module.eventbridge.eventbridge_role_name
+}
diff --git a/examples/api-gateway-event-source/sample-order-data.json b/examples/api-gateway-event-source/sample-order-data.json
new file mode 100644
index 0000000..4de316c
--- /dev/null
+++ b/examples/api-gateway-event-source/sample-order-data.json
@@ -0,0 +1,39 @@
+{
+ "data": {
+ "destination": {
+ "name": "accountName"
+ },
+ "orderData": {
+ "sourceOrderId": "1234512345",
+ "items": [
+ {
+ "sku": "Business Cards",
+ "sourceItemId": "1234512346",
+ "components": [
+ {
+ "code": "Content",
+ "fetch": true,
+ "path": "http://www.w2psite.com/businessCard.pdf"
+ }
+ ]
+ }
+ ],
+ "shipments": [
+ {
+ "shipTo": {
+ "name": "John Doe",
+ "companyName": "Acme",
+ "address1": "1234 Main St.",
+ "town": "Capitol",
+ "postcode": "12345",
+ "isoCountry": "US"
+ },
+ "carrier":{
+ "code": "fedex",
+ "service": "ground"
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/examples/api-gateway-event-source/variables.tf b/examples/api-gateway-event-source/variables.tf
new file mode 100644
index 0000000..e69de29
diff --git a/examples/cloudwatch-target/README.md b/examples/cloudwatch-target/README.md
new file mode 100644
index 0000000..e69de29
diff --git a/examples/cloudwatch-target/main.tf b/examples/cloudwatch-target/main.tf
new file mode 100644
index 0000000..3ba6bb5
--- /dev/null
+++ b/examples/cloudwatch-target/main.tf
@@ -0,0 +1,68 @@
+terraform {
+ required_version = ">= 0.14.0"
+
+ required_providers {
+ aws = ">= 3.19"
+ random = ">= 0"
+ }
+}
+
+provider "aws" {
+ region = "ap-southeast-1"
+
+ # Make it faster by skipping something
+ skip_get_ec2_platforms = true
+ skip_metadata_api_check = true
+ skip_region_validation = true
+ skip_credentials_validation = true
+ skip_requesting_account_id = true
+}
+
+module "eventbridge" {
+ source = "../../"
+
+ bus_name = "${random_pet.this.id}-bus"
+
+ attach_cloudwatch_policy = true
+
+ cloudwatch_target_arns = [
+ aws_cloudwatch_log_group.this.arn
+ ]
+
+ rules = {
+ orders = {
+ description = "Capture all created orders",
+ event_pattern = jsonencode({ "source" : ["orders.create"] })
+ }
+ }
+
+ targets = {
+ orders = [
+ {
+ name = "log-orders-to-cloudwatch"
+ arn = aws_cloudwatch_log_group.this.arn
+ }
+ ]
+ }
+
+ tags = {
+ Name = "${random_pet.this.id}-bus"
+ }
+}
+
+##################
+# Extra resources
+##################
+
+resource "random_pet" "this" {
+ length = 2
+}
+
+resource "aws_cloudwatch_log_group" "this" {
+ name = "/aws/events/${random_pet.this.id}"
+
+ tags = {
+ Name = "${random_pet.this.id}-log-group"
+ }
+}
+
diff --git a/examples/cloudwatch-target/outputs.tf b/examples/cloudwatch-target/outputs.tf
new file mode 100644
index 0000000..7a3ecdc
--- /dev/null
+++ b/examples/cloudwatch-target/outputs.tf
@@ -0,0 +1,5 @@
+output "eventbridge_bus_arn" {
+ description = "The EventBridge Bus ARN"
+ value = module.eventbridge.this_eventbridge_bus_arn
+}
+
diff --git a/examples/cloudwatch-target/variables.tf b/examples/cloudwatch-target/variables.tf
new file mode 100644
index 0000000..e69de29
diff --git a/examples/complete/README.md b/examples/complete/README.md
new file mode 100644
index 0000000..9c16b08
--- /dev/null
+++ b/examples/complete/README.md
@@ -0,0 +1,15 @@
+# EventBridge Complete Example
+
+Configuration in this directory creates EventBridge resource configuration including an SQS queue, Kinesis stream, and DynamoDB table.
+
+## Usage
+
+To run this example you need to execute:
+
+```bash
+$ terraform init
+$ terraform plan
+$ terraform apply
+```
+
+Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
new file mode 100644
index 0000000..6b0f193
--- /dev/null
+++ b/examples/complete/main.tf
@@ -0,0 +1,221 @@
+terraform {
+ required_version = ">= 0.14.0"
+
+ required_providers {
+ aws = ">= 3.19"
+ random = ">= 0"
+ }
+}
+
+provider "aws" {
+ region = "ap-southeast-1"
+
+ # Make it faster by skipping something
+ skip_get_ec2_platforms = true
+ skip_metadata_api_check = true
+ skip_region_validation = true
+ skip_credentials_validation = true
+ skip_requesting_account_id = true
+}
+
+resource "random_pet" "this" {
+ length = 2
+}
+
+module "eventbridge" {
+ source = "../../"
+
+ bus_name = "${random_pet.this.id}-bus"
+
+ create_bus = true
+ create_rules = true
+ create_targets = true
+ create_archives = true
+ create_permissions = true
+
+ attach_tracing_policy = true
+ attach_kinesis_policy = true
+ attach_kinesis_firehose_policy = true
+ attach_sqs_policy = true
+ attach_ecs_policy = true
+ attach_lambda_policy = true
+ attach_sfn_policy = true
+ attach_cloudwatch_policy = true
+
+ sqs_target_arns = [aws_sqs_queue.queue.arn]
+ ecs_target_arns = []
+ kinesis_target_arns = [aws_kinesis_stream.this.arn]
+ kinesis_firehose_target_arns = []
+ lambda_target_arns = []
+ sfn_target_arns = []
+ cloudwatch_target_arns = [aws_cloudwatch_log_group.this.arn]
+
+ permission_config = [
+ {
+ account_id = "099720109477",
+ statement_id = "canonical"
+ },
+ {
+ account_id = "099720109466",
+ statement_id = "canonical_two"
+ }
+ ]
+
+ archive_config = [
+ {
+ description = "some archive"
+ retention_days = 1
+ event_pattern = <
+ }
+ EOF
+ }
+}
+
+##################
+# Extra resources
+##################
+
+resource "aws_kinesis_stream" "this" {
+ name = random_pet.this.id
+ shard_count = 1
+}
+
+resource "aws_sqs_queue" "queue" {
+ name = "${random_pet.this.id}-queue"
+}
+
+resource "aws_sqs_queue" "dlq" {
+ name = "${random_pet.this.id}-dlq"
+}
+
+resource "aws_sqs_queue_policy" "queue" {
+ queue_url = aws_sqs_queue.queue.id
+ policy = data.aws_iam_policy_document.queue.json
+}
+
+data "aws_iam_policy_document" "queue" {
+ statement {
+ sid = "events-policy"
+ actions = ["sqs:SendMessage"]
+ principals {
+ type = "Service"
+ identifiers = ["events.amazonaws.com"]
+ }
+ resources = [aws_sqs_queue.queue.arn]
+ }
+}
+
+resource "aws_cloudwatch_log_group" "this" {
+ name = "/aws/events/${random_pet.this.id}"
+
+ tags = {
+ Name = "${random_pet.this.id}-log-group"
+ }
+}
+
diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf
new file mode 100644
index 0000000..4b50256
--- /dev/null
+++ b/examples/complete/outputs.tf
@@ -0,0 +1,14 @@
+output "eventbridge_bus_arn" {
+ description = "The EventBridge Bus ARN"
+ value = module.eventbridge.this_eventbridge_bus_arn
+}
+
+output "eventbridge_rule_ids" {
+ description = "The EventBridge Rule IDs"
+ value = module.eventbridge.this_eventbridge_rule_ids
+}
+
+output "eventbridge_rule_arns" {
+ description = "The EventBridge Rule ARNs"
+ value = module.eventbridge.this_eventbridge_rule_arns
+}
diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf
new file mode 100644
index 0000000..e69de29
diff --git a/examples/simple/README.md b/examples/simple/README.md
new file mode 100644
index 0000000..1d4cc2a
--- /dev/null
+++ b/examples/simple/README.md
@@ -0,0 +1,16 @@
+# EventBridge Simple Example
+
+Configuration in this directory creates EventBridge resource configuration.
+
+## Usage
+
+To run this example you need to execute:
+
+```bash
+$ terraform init
+$ terraform plan
+$ terraform apply
+```
+
+Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
+
diff --git a/examples/simple/main.tf b/examples/simple/main.tf
new file mode 100644
index 0000000..e2dfbb2
--- /dev/null
+++ b/examples/simple/main.tf
@@ -0,0 +1,34 @@
+terraform {
+ required_version = ">= 0.14.0"
+
+ required_providers {
+ aws = ">= 3.19"
+ random = ">= 0"
+ }
+}
+
+provider "aws" {
+ region = "ap-southeast-1"
+
+ # Make it faster by skipping something
+ skip_get_ec2_platforms = true
+ skip_metadata_api_check = true
+ skip_region_validation = true
+ skip_credentials_validation = true
+ skip_requesting_account_id = true
+}
+
+resource "random_pet" "this" {
+ length = 2
+}
+
+module "eventbridge" {
+ source = "../../"
+
+ bus_name = "${random_pet.this.id}-bus"
+
+ tags = {
+ Name = "${random_pet.this.id}-bus"
+ }
+}
+
diff --git a/examples/simple/outputs.tf b/examples/simple/outputs.tf
new file mode 100644
index 0000000..7a3ecdc
--- /dev/null
+++ b/examples/simple/outputs.tf
@@ -0,0 +1,5 @@
+output "eventbridge_bus_arn" {
+ description = "The EventBridge Bus ARN"
+ value = module.eventbridge.this_eventbridge_bus_arn
+}
+
diff --git a/examples/simple/variables.tf b/examples/simple/variables.tf
new file mode 100644
index 0000000..e69de29
diff --git a/examples/sqs-target/README.md b/examples/sqs-target/README.md
new file mode 100644
index 0000000..96fcf85
--- /dev/null
+++ b/examples/sqs-target/README.md
@@ -0,0 +1,17 @@
+# EventBridge SQS Example
+
+Configuration in this directory creates EventBridge resource configuration.
+
+## Usage
+
+To run this example you need to execute:
+
+```bash
+$ terraform init
+$ terraform plan
+$ terraform apply
+```
+
+Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
+
+
diff --git a/examples/sqs-target/main.tf b/examples/sqs-target/main.tf
new file mode 100644
index 0000000..a5afedb
--- /dev/null
+++ b/examples/sqs-target/main.tf
@@ -0,0 +1,115 @@
+terraform {
+ required_version = ">= 0.14.0"
+
+ required_providers {
+ aws = ">= 3.19"
+ random = ">= 0"
+ }
+}
+
+provider "aws" {
+ region = "ap-southeast-1"
+
+ # Make it faster by skipping something
+ skip_get_ec2_platforms = true
+ skip_metadata_api_check = true
+ skip_region_validation = true
+ skip_credentials_validation = true
+ skip_requesting_account_id = true
+}
+
+module "eventbridge" {
+ source = "../../"
+
+ bus_name = "${random_pet.this.id}-bus"
+
+ attach_sqs_policy = true
+ sqs_target_arns = [
+ aws_sqs_queue.queue.arn,
+ aws_sqs_queue.fifo.arn,
+ aws_sqs_queue.dlq.arn
+ ]
+
+ rules = {
+ orders = {
+ description = "Capture all created orders",
+ event_pattern = jsonencode({ "source" : ["orders.create"] })
+ }
+ }
+
+ targets = {
+ orders = [
+ {
+ name = "send-orders-to-sqs"
+ arn = aws_sqs_queue.queue.arn
+ },
+ {
+ name = "send-orders-to-sqs-wth-dead-letter"
+ arn = aws_sqs_queue.queue.arn
+ dead_letter_arn = aws_sqs_queue.dlq.arn
+ },
+ {
+ name = "send-orders-to-sqs-with-retry-policy"
+ arn = aws_sqs_queue.queue.arn
+ dead_letter_arn = aws_sqs_queue.dlq.arn
+ retry_policy = {
+ maximum_retry_attempts = 10
+ maximum_event_age_in_seconds = 300
+ }
+ },
+ {
+ name = "send-orders-to-fifo-sqs"
+ arn = aws_sqs_queue.fifo.arn
+ dead_letter_arn = aws_sqs_queue.dlq.arn
+ message_group_id = "send-orders-to-fifo-sqs"
+ }
+ ]
+ }
+
+ tags = {
+ Name = "${random_pet.this.id}-bus"
+ }
+}
+
+##################
+# Extra resources
+##################
+
+resource "random_pet" "this" {
+ length = 2
+}
+
+resource "aws_sqs_queue" "queue" {
+ name = random_pet.this.id
+}
+
+resource "aws_sqs_queue" "fifo" {
+ name = "${random_pet.this.id}.fifo"
+ fifo_queue = true
+ content_based_deduplication = true
+}
+
+resource "aws_sqs_queue" "dlq" {
+ name = "${random_pet.this.id}-dlq"
+}
+
+resource "aws_sqs_queue_policy" "queue" {
+ queue_url = aws_sqs_queue.queue.id
+ policy = data.aws_iam_policy_document.queue.json
+}
+
+data "aws_iam_policy_document" "queue" {
+ statement {
+ sid = "events-policy"
+ actions = ["sqs:SendMessage"]
+ principals {
+ type = "Service"
+ identifiers = ["events.amazonaws.com"]
+ }
+ resources = [
+ aws_sqs_queue.queue.arn,
+ aws_sqs_queue.fifo.arn
+ ]
+ }
+}
+
diff --git a/examples/sqs-target/outputs.tf b/examples/sqs-target/outputs.tf
new file mode 100644
index 0000000..4b50256
--- /dev/null
+++ b/examples/sqs-target/outputs.tf
@@ -0,0 +1,14 @@
+output "eventbridge_bus_arn" {
+ description = "The EventBridge Bus ARN"
+ value = module.eventbridge.this_eventbridge_bus_arn
+}
+
+output "eventbridge_rule_ids" {
+ description = "The EventBridge Rule IDs"
+ value = module.eventbridge.this_eventbridge_rule_ids
+}
+
+output "eventbridge_rule_arns" {
+ description = "The EventBridge Rule ARNs"
+ value = module.eventbridge.this_eventbridge_rule_arns
+}
diff --git a/examples/sqs-target/variables.tf b/examples/sqs-target/variables.tf
new file mode 100644
index 0000000..e69de29
diff --git a/examples/step-function-target/README.md b/examples/step-function-target/README.md
new file mode 100644
index 0000000..e69de29
diff --git a/examples/step-function-target/main.tf b/examples/step-function-target/main.tf
new file mode 100644
index 0000000..dc694b0
--- /dev/null
+++ b/examples/step-function-target/main.tf
@@ -0,0 +1,79 @@
+terraform {
+ required_version = ">= 0.14.0"
+
+ required_providers {
+ aws = ">= 3.19"
+ random = ">= 0"
+ }
+}
+
+provider "aws" {
+ region = "ap-southeast-1"
+
+ # Make it faster by skipping something
+ skip_get_ec2_platforms = true
+ skip_metadata_api_check = true
+ skip_region_validation = true
+ skip_credentials_validation = true
+ skip_requesting_account_id = true
+}
+
+module "eventbridge" {
+ source = "../../"
+
+ bus_name = "${random_pet.this.id}-bus"
+
+ attach_sfn_policy = true
+ sfn_target_arns = [module.step_function.this_state_machine_arn]
+
+ rules = {
+ orders = {
+ description = "Capture order data"
+ event_pattern = jsonencode({ "source" : ["orders.create"] })
+ }
+ }
+
+ targets = {
+ orders = [
+ {
+ name = "process-order-with-sfn"
+ arn = module.step_function.this_state_machine_arn
+ attach_role_arn = true
+ }
+ ]
+ }
+
+ tags = {
+ Name = "${random_pet.this.id}-bus"
+ }
+}
+
+##################
+# Extra resources
+##################
+
+resource "random_pet" "this" {
+ length = 2
+}
+
+module "step_function" {
+ source = "terraform-aws-modules/step-functions/aws"
+ version = "1.2.0"
+
+ name = random_pet.this.id
+
+ definition = jsonencode(yamldecode(templatefile("sfn.asl.yaml", {})))
+
+ trusted_entities = ["events.amazonaws.com"]
+
+ service_integrations = {
+ stepfunction = {
+ stepfunction = ["*"]
+ }
+ }
+
+ tags = {
+ Name = "${random_pet.this.id}-step-function"
+ }
+}
+
diff --git a/examples/step-function-target/outputs.tf b/examples/step-function-target/outputs.tf
new file mode 100644
index 0000000..7a3ecdc
--- /dev/null
+++ b/examples/step-function-target/outputs.tf
@@ -0,0 +1,5 @@
+output "eventbridge_bus_arn" {
+ description = "The EventBridge Bus ARN"
+ value = module.eventbridge.this_eventbridge_bus_arn
+}
+
diff --git a/examples/step-function-target/sfn.asl.yaml b/examples/step-function-target/sfn.asl.yaml
new file mode 100644
index 0000000..dfc0c19
--- /dev/null
+++ b/examples/step-function-target/sfn.asl.yaml
@@ -0,0 +1,12 @@
+---
+Comment: Default Step Function
+StartAt: Hello
+States:
+ Hello:
+ Type: Pass
+ Result: Hello
+ Next: World
+ World:
+ Type: Pass
+ Result: World
+ End: true
diff --git a/examples/step-function-target/variables.tf b/examples/step-function-target/variables.tf
new file mode 100644
index 0000000..e69de29
diff --git a/examples/transform-input/README.md b/examples/transform-input/README.md
new file mode 100644
index 0000000..2fb4520
--- /dev/null
+++ b/examples/transform-input/README.md
@@ -0,0 +1,17 @@
+# EventBridge Input Transform Example
+
+Configuration in this directory creates EventBridge resource configuration.
+
+## Usage
+
+To run this example you need to execute:
+
+```bash
+$ terraform init
+$ terraform plan
+$ terraform apply
+```
+
+Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
+
+
diff --git a/examples/transform-input/main.tf b/examples/transform-input/main.tf
new file mode 100644
index 0000000..6c6547f
--- /dev/null
+++ b/examples/transform-input/main.tf
@@ -0,0 +1,84 @@
+terraform {
+ required_version = ">= 0.14.0"
+
+ required_providers {
+ aws = ">= 3.19"
+ random = ">= 0"
+ }
+}
+
+provider "aws" {
+ region = "ap-southeast-1"
+
+ # Make it faster by skipping something
+ skip_get_ec2_platforms = true
+ skip_metadata_api_check = true
+ skip_region_validation = true
+ skip_credentials_validation = true
+ skip_requesting_account_id = true
+}
+
+module "eventbridge" {
+ source = "../../"
+
+ bus_name = "${random_pet.this.id}-bus"
+
+ rules = {
+ orders = {
+ description = "Capture all order data"
+ event_pattern = jsonencode({ "source" : ["orders.create"] })
+ }
+ }
+
+ targets = {
+ orders = [
+ {
+ name = "send-orders-to-sqs"
+ arn = aws_sqs_queue.queue.arn
+ input_transformer = {
+ input_paths = {
+ order_id = "$.detail.order_id"
+ }
+ input_template = <
+ }
+ EOF
+ }
+ }
+ ]
+ }
+
+ tags = {
+ Name = "${random_pet.this.id}-bus"
+ }
+}
+
+##################
+# Extra resources
+##################
+
+resource "random_pet" "this" {
+ length = 2
+}
+
+resource "aws_sqs_queue" "queue" {
+ name = "${random_pet.this.id}-queue"
+}
+
+resource "aws_sqs_queue_policy" "queue" {
+ queue_url = aws_sqs_queue.queue.id
+ policy = data.aws_iam_policy_document.queue.json
+}
+
+data "aws_iam_policy_document" "queue" {
+ statement {
+ sid = "events-policy"
+ actions = ["sqs:SendMessage"]
+ principals {
+ type = "Service"
+ identifiers = ["events.amazonaws.com"]
+ }
+ resources = [aws_sqs_queue.queue.arn]
+ }
+}
diff --git a/examples/transform-input/outputs.tf b/examples/transform-input/outputs.tf
new file mode 100644
index 0000000..7a3ecdc
--- /dev/null
+++ b/examples/transform-input/outputs.tf
@@ -0,0 +1,5 @@
+output "eventbridge_bus_arn" {
+ description = "The EventBridge Bus ARN"
+ value = module.eventbridge.this_eventbridge_bus_arn
+}
+
diff --git a/examples/transform-input/variables.tf b/examples/transform-input/variables.tf
new file mode 100644
index 0000000..e69de29
diff --git a/examples/with-archive/README.md b/examples/with-archive/README.md
new file mode 100644
index 0000000..1d4cc2a
--- /dev/null
+++ b/examples/with-archive/README.md
@@ -0,0 +1,16 @@
+# EventBridge Simple Example
+
+Configuration in this directory creates EventBridge resource configuration.
+
+## Usage
+
+To run this example you need to execute:
+
+```bash
+$ terraform init
+$ terraform plan
+$ terraform apply
+```
+
+Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
+
diff --git a/examples/with-archive/main.tf b/examples/with-archive/main.tf
new file mode 100644
index 0000000..2388b31
--- /dev/null
+++ b/examples/with-archive/main.tf
@@ -0,0 +1,100 @@
+terraform {
+ required_version = ">= 0.14.0"
+
+ required_providers {
+ aws = ">= 3.19"
+ random = ">= 0"
+ }
+}
+
+provider "aws" {
+ region = "ap-southeast-1"
+
+ # Make it faster by skipping something
+ skip_get_ec2_platforms = true
+ skip_metadata_api_check = true
+ skip_region_validation = true
+ skip_credentials_validation = true
+ skip_requesting_account_id = true
+}
+
+resource "random_pet" "this" {
+ length = 2
+}
+
+module "eventbridge" {
+ source = "../../"
+
+ create_archives = true
+
+ archive_config = [
+ {
+ name = "${random_pet.this.id}-launch-archive",
+ description = "${random_pet.this.id}-launch-archive",
+ retention_days = 1
+ event_pattern = < rule
+ } : {}
+
+ name = "${replace(each.value.name, "_", "-")}-rule"
+
+ event_bus_name = aws_cloudwatch_event_bus.this[0].name
+
+ description = lookup(each.value, "description", null)
+ name_prefix = lookup(each.value, "name_prefix", null)
+ is_enabled = lookup(each.value, "enabled", true)
+ event_pattern = lookup(each.value, "event_pattern", null)
+ schedule_expression = lookup(each.value, "schedule_expression", null)
+ role_arn = aws_iam_role.eventbridge[0].arn
+
+ tags = merge(var.tags, {
+ Name = "${replace(each.value.name, "_", "-")}-rule"
+ })
+}
+
+resource "aws_cloudwatch_event_target" "this" {
+ for_each = var.create && var.create_targets ? {
+ for target in local.eventbridge_targets : target.name => target
+ } : tomap({})
+
+ event_bus_name = aws_cloudwatch_event_bus.this[0].name
+
+ rule = "${replace(each.value.rule, "_", "-")}-rule"
+ arn = each.value.arn
+
+ role_arn = lookup(each.value, "attach_role_arn", null) != null ? aws_iam_role.eventbridge[0].arn : null
+ target_id = lookup(each.value, "target_id", null)
+ input = lookup(each.value, "input", null)
+ input_path = lookup(each.value, "input_path", null)
+
+ dynamic "run_command_targets" {
+ for_each = lookup(each.value, "run_command_targets", null) != null ? [true] : []
+
+ content {
+ key = run_command_targets.value.key
+ values = run_command_targets.value.values
+ }
+ }
+
+ dynamic "ecs_target" {
+ for_each = lookup(each.value, "ecs_target", null) != null ? [true] : []
+
+ content {
+ group = lookup(ecs_target.value, "group", null)
+ launch_type = lookup(ecs_target.value, "launch_type", null)
+ platform_version = lookup(ecs_target.value, "platform_version", null)
+ task_count = lookup(ecs_target.value, "task_count", null)
+ task_definition_arn = ecs_target.value.task_definition_arn
+
+ dynamic "network_configuration" {
+ for_each = lookup(ecs_target.value, "network_configuration", null) != null ? [true] : []
+
+ content {
+ subnets = network_configuration.value.subnets
+ security_groups = lookup(network_configuration.value, "security_groups", null)
+ assign_public_ip = lookup(network_configuration.value, "assign_public_ip", null)
+ }
+ }
+ }
+ }
+
+ dynamic "batch_target" {
+ for_each = lookup(each.value, "batch_target", null) != null ? [true] : []
+
+ content {
+ job_definition = batch_target.value.job_definition
+ job_name = batch_target.value.job_name
+ array_size = lookup(batch_target.value, "array_size", null)
+ job_attempts = lookup(batch_target.value, "job_attempts", null)
+ }
+ }
+
+ dynamic "kinesis_target" {
+ for_each = lookup(each.value, "kinesis_target", null) != null ? [true] : []
+
+ content {
+ partition_key_path = lookup(kinesis_target.value, "partition_key_path", null)
+ }
+ }
+
+ dynamic "sqs_target" {
+ for_each = lookup(each.value, "message_group_id", null) != null ? [true] : []
+
+ content {
+ message_group_id = each.value.message_group_id
+ }
+ }
+
+ dynamic "input_transformer" {
+ for_each = lookup(each.value, "input_transformer", null) != null ? [
+ each.value.input_transformer
+ ] : []
+
+ content {
+ input_paths = input_transformer.value.input_paths
+ input_template = input_transformer.value.input_template
+ }
+ }
+
+ dynamic "dead_letter_config" {
+ for_each = lookup(each.value, "dead_letter_arn", null) != null ? [true] : []
+
+ content {
+ arn = each.value.dead_letter_arn
+ }
+ }
+
+ dynamic "retry_policy" {
+ for_each = lookup(each.value, "retry_policy", null) != null ? [
+ each.value.retry_policy
+ ] : []
+
+ content {
+ maximum_event_age_in_seconds = retry_policy.value.maximum_event_age_in_seconds
+ maximum_retry_attempts = retry_policy.value.maximum_retry_attempts
+ }
+ }
+}
+
+resource "aws_cloudwatch_event_archive" "this" {
+ for_each = var.create && var.create_archives ? {
+ for k, v in var.archive_config : k => v
+ } : {}
+
+ name = each.value.name
+ event_source_arn = lookup(each.value, "event_source_arn", null) == null ? aws_cloudwatch_event_bus.this[0].arn : null
+ description = lookup(each.value, "description", null)
+ event_pattern = lookup(each.value, "event_pattern", null)
+ retention_days = lookup(each.value, "retention_days", null)
+}
+
+resource "aws_cloudwatch_event_permission" "this" {
+ for_each = var.create && var.create_permissions ? {
+ for permission in var.permission_config : permission.statement_id => permission
+ } : {}
+
+ principal = each.value.account_id
+ statement_id = each.value.statement_id
+ event_bus_name = lookup(each.value, aws_cloudwatch_event_bus.this[0].name, null) == null ? aws_cloudwatch_event_bus.this[0].name : null
+}
diff --git a/outputs.tf b/outputs.tf
new file mode 100644
index 0000000..568855d
--- /dev/null
+++ b/outputs.tf
@@ -0,0 +1,48 @@
+# EventBridge Bus
+output "this_eventbridge_bus_name" {
+ description = "The EventBridge Bus Name"
+ value = var.bus_name
+}
+
+output "this_eventbridge_bus_arn" {
+ description = "The EventBridge Bus Arn"
+ value = element(concat(aws_cloudwatch_event_bus.this.*.arn, [""]), 0)
+}
+
+# EventBridge Archive
+output "this_eventbridge_archive_arns" {
+ description = "The EventBridge Archive Arns created"
+ value = { for v in aws_cloudwatch_event_archive.this : v.name => v.arn }
+}
+
+# EventBridge Permission
+output "this_eventbridge_permission_ids" {
+ description = "The EventBridge Permission Arns created"
+ value = { for k, v in aws_cloudwatch_event_permission.this : k => v.id }
+}
+
+# EventBridge Rule
+output "this_eventbridge_rule_ids" {
+ description = "The EventBridge Rule IDs created"
+ value = {
+ for p in sort(keys(var.rules)) : p => aws_cloudwatch_event_rule.this[p].id
+ }
+}
+
+output "this_eventbridge_rule_arns" {
+ description = "The EventBridge Rule ARNs created"
+ value = {
+ for p in sort(keys(var.rules)) : p => aws_cloudwatch_event_rule.this[p].arn
+ }
+}
+
+# IAM Role
+output "eventbridge_role_arn" {
+ description = "The ARN of the IAM role created for EventBridge"
+ value = element(concat(aws_iam_role.eventbridge.*.arn, [""]), 0)
+}
+
+output "eventbridge_role_name" {
+ description = "The name of the IAM role created for EventBridge"
+ value = element(concat(aws_iam_role.eventbridge.*.name, [""]), 0)
+}
diff --git a/variables.tf b/variables.tf
new file mode 100644
index 0000000..42ba02d
--- /dev/null
+++ b/variables.tf
@@ -0,0 +1,293 @@
+variable "bus_name" {
+ description = "A unique name for your EventBridge Bus"
+ type = string
+ default = ""
+}
+
+variable "rules" {
+ description = "A map of objects with EventBridge Rule definitions."
+ type = map(any)
+ default = {}
+}
+
+variable "targets" {
+ description = "A Map of objects with EventBridge Target definitions."
+ type = any
+ default = {}
+}
+
+variable "archive_config" {
+ description = "A list of objects with the EventBridge Archive definitions."
+ type = list(any)
+ default = []
+}
+
+variable "permission_config" {
+ description = "A list of objects with EventBridge Permission definitions."
+ type = list(any)
+ default = []
+}
+
+variable "tags" {
+ description = "A map of tags to assign to resources."
+ type = map(string)
+ default = {}
+}
+
+variable "create" {
+ description = "Controls whether resources should be created"
+ type = bool
+ default = true
+}
+
+variable "create_role" {
+ description = "Controls whether IAM role for Lambda Function should be created"
+ type = bool
+ default = true
+}
+
+variable "create_bus" {
+ description = "Controls whether EventBridge Bus resource should be created"
+ type = bool
+ default = true
+}
+
+variable "create_rules" {
+ description = "Controls whether EventBridge Rule resources should be created"
+ type = bool
+ default = true
+}
+
+variable "create_targets" {
+ description = "Controls whether EventBridge Target resources should be created"
+ type = bool
+ default = true
+}
+
+variable "create_permissions" {
+ description = "Controls whether EventBridge Permission resources should be created"
+ type = bool
+ default = true
+}
+
+variable "create_archives" {
+ description = "Controls whether EventBridge Archive resources should be created"
+ type = bool
+ default = false
+}
+
+######
+# IAM
+######
+
+variable "role_name" {
+ description = "Name of IAM role to use for Lambda Function"
+ type = string
+ default = null
+}
+
+variable "role_description" {
+ description = "Description of IAM role to use for Lambda Function"
+ type = string
+ default = null
+}
+
+variable "role_path" {
+ description = "Path of IAM role to use for Lambda Function"
+ type = string
+ default = null
+}
+
+variable "role_force_detach_policies" {
+ description = "Specifies to force detaching any policies the IAM role has before destroying it."
+ type = bool
+ default = true
+}
+
+variable "role_permissions_boundary" {
+ description = "The ARN of the policy that is used to set the permissions boundary for the IAM role used by Lambda Function"
+ type = string
+ default = null
+}
+
+variable "role_tags" {
+ description = "A map of tags to assign to IAM role"
+ type = map(string)
+ default = {}
+}
+
+###########
+# Policies
+###########
+
+variable "attach_kinesis_policy" {
+ description = "Controls whether the Kinesis policy should be added to IAM role for EventBridge Target"
+ type = bool
+ default = false
+}
+
+variable "attach_kinesis_firehose_policy" {
+ description = "Controls whether the Kinesis Firehose policy should be added to IAM role for EventBridge Target"
+ type = bool
+ default = false
+}
+
+variable "attach_sqs_policy" {
+ description = "Controls whether the SQS policy should be added to IAM role for EventBridge Target"
+ type = bool
+ default = false
+}
+
+variable "attach_ecs_policy" {
+ description = "Controls whether the ECS policy should be added to IAM role for EventBridge Target"
+ type = bool
+ default = false
+}
+
+variable "attach_lambda_policy" {
+ description = "Controls whether the Lambda Function policy should be added to IAM role for EventBridge Target"
+ type = bool
+ default = false
+}
+
+variable "attach_sfn_policy" {
+ description = "Controls whether the StepFunction policy should be added to IAM role for EventBridge Target"
+ type = bool
+ default = false
+}
+
+variable "attach_cloudwatch_policy" {
+ description = "Controls whether the Cloudwatch policy should be added to IAM role for EventBridge Target"
+ type = bool
+ default = false
+}
+
+variable "attach_tracing_policy" {
+ description = "Controls whether X-Ray tracing policy should be added to IAM role for EventBridge"
+ type = bool
+ default = false
+}
+
+variable "kinesis_target_arns" {
+ description = "The Amazon Resource Name (ARN) of the Kinesis Streams you want to use as EventBridge targets"
+ type = list(string)
+ default = []
+}
+
+variable "kinesis_firehose_target_arns" {
+ description = "The Amazon Resource Name (ARN) of the Kinesis Firehose Delivery Streams you want to use as EventBridge targets"
+ type = list(string)
+ default = []
+}
+
+variable "sqs_target_arns" {
+ description = "The Amazon Resource Name (ARN) of the AWS SQS Queues you want to use as EventBridge targets"
+ type = list(string)
+ default = []
+}
+
+variable "ecs_target_arns" {
+ description = "The Amazon Resource Name (ARN) of the AWS ECS Tasks you want to use as EventBridge targets"
+ type = list(string)
+ default = []
+}
+
+variable "lambda_target_arns" {
+ description = "The Amazon Resource Name (ARN) of the Lambda Functions you want to use as EventBridge targets"
+ type = list(string)
+ default = []
+}
+
+variable "sfn_target_arns" {
+ description = "The Amazon Resource Name (ARN) of the StepFunctions you want to use as EventBridge targets"
+ type = list(string)
+ default = []
+}
+
+variable "cloudwatch_target_arns" {
+ description = "The Amazon Resource Name (ARN) of the Cloudwatch Log Streams you want to use as EventBridge targets"
+ type = list(string)
+ default = []
+}
+
+##########################
+# Various custom policies
+##########################
+
+variable "attach_policy_json" {
+ description = "Controls whether policy_json should be added to IAM role"
+ type = bool
+ default = false
+}
+
+variable "attach_policy_jsons" {
+ description = "Controls whether policy_jsons should be added to IAM role"
+ type = bool
+ default = false
+}
+
+variable "attach_policy" {
+ description = "Controls whether policy should be added to IAM role"
+ type = bool
+ default = false
+}
+
+variable "attach_policies" {
+ description = "Controls whether list of policies should be added to IAM role"
+ type = bool
+ default = false
+}
+
+variable "number_of_policy_jsons" {
+ description = "Number of policies JSON to attach to IAM role"
+ type = number
+ default = 0
+}
+
+variable "number_of_policies" {
+ description = "Number of policies to attach to IAM role"
+ type = number
+ default = 0
+}
+
+variable "attach_policy_statements" {
+ description = "Controls whether policy_statements should be added to IAM role"
+ type = bool
+ default = false
+}
+
+variable "trusted_entities" {
+ description = "Step Function additional trusted entities for assuming roles (trust relationship)"
+ type = list(string)
+ default = []
+}
+
+variable "policy_json" {
+ description = "An additional policy document as JSON to attach to IAM role"
+ type = string
+ default = null
+}
+
+variable "policy_jsons" {
+ description = "List of additional policy documents as JSON to attach to IAM role"
+ type = list(string)
+ default = []
+}
+
+variable "policy" {
+ description = "An additional policy document ARN to attach to IAM role"
+ type = string
+ default = null
+}
+
+variable "policies" {
+ description = "List of policy statements ARN to attach to IAM role"
+ type = list(string)
+ default = []
+}
+
+variable "policy_statements" {
+ description = "Map of dynamic policy statements to attach to IAM role"
+ type = any
+ default = {}
+}
diff --git a/versions.tf b/versions.tf
new file mode 100644
index 0000000..2c2f74f
--- /dev/null
+++ b/versions.tf
@@ -0,0 +1,7 @@
+terraform {
+ required_version = ">= 0.12.26"
+
+ required_providers {
+ aws = ">= 3.19"
+ }
+}