├── blog ├── account-a-web-store │ ├── order_function │ │ ├── __init__.py │ │ ├── requirements.txt │ │ └── app.py │ ├── events │ │ ├── put_events_cli.json │ │ └── put_events.json │ ├── template.yaml │ ├── publish.sh │ └── README.md ├── account-c-invoice-processing │ ├── invoice_processing │ │ ├── invoice_processing_function │ │ │ ├── __init__.py │ │ │ └── app.py │ │ ├── requirements.txt │ │ └── schema │ │ │ └── com_examplecorp_webstore │ │ │ └── newordercreated │ │ │ ├── __init__.py │ │ │ ├── NewOrderCreatedItem.py │ │ │ └── NewOrderCreated.py │ ├── events │ │ └── event.json │ ├── conftest.py │ ├── README.md │ └── template.yaml ├── pyproject.toml ├── account-b-central-bus │ ├── README.md │ ├── central-event-bus-resource-policy.json │ └── template.yaml └── README.md ├── patterns ├── multi-bus-multi-account-pattern │ ├── blue-service-account │ │ └── blue-service-app │ │ │ ├── __init__.py │ │ │ ├── blue_p_e1 │ │ │ ├── __init__.py │ │ │ ├── requirements.txt │ │ │ └── app.py │ │ │ ├── blue_s_e2 │ │ │ ├── __init__.py │ │ │ ├── app.py │ │ │ └── requirements.txt │ │ │ ├── README.md │ │ │ ├── events │ │ │ └── event.json │ │ │ ├── pyproject.toml │ │ │ ├── Makefile │ │ │ ├── subscriptions.yaml │ │ │ ├── template.yaml │ │ │ └── .gitignore │ ├── orange-service-account │ │ └── orange-service-app │ │ │ ├── __init__.py │ │ │ ├── orange_p_e3 │ │ │ ├── __init__.py │ │ │ ├── requirements.txt │ │ │ └── app.py │ │ │ ├── orange_s_e2 │ │ │ ├── __init__.py │ │ │ ├── app.py │ │ │ └── requirements.txt │ │ │ ├── README.md │ │ │ ├── pyproject.toml │ │ │ ├── Makefile │ │ │ ├── events │ │ │ └── event.json │ │ │ ├── subscriptions.yaml │ │ │ ├── template.yaml │ │ │ └── .gitignore │ ├── purple-service-account │ │ └── purple-service-app │ │ │ ├── __init__.py │ │ │ ├── purple_p_e2 │ │ │ ├── __init__.py │ │ │ ├── requirements.txt │ │ │ └── app.py │ │ │ ├── purple_s_e1 │ │ │ ├── __init__.py │ │ │ ├── app.py │ │ │ └── requirements.txt │ │ │ ├── purple_s_e3 │ │ │ ├── __init__.py │ │ │ ├── app.py │ │ │ └── requirements.txt │ │ │ ├── README.md │ │ │ ├── pyproject.toml │ │ │ ├── Makefile │ │ │ ├── events │ │ │ └── event.json │ │ │ ├── subscriptions.yaml │ │ │ └── .gitignore │ └── Makefile ├── single-bus-multi-account-pattern │ ├── blue-service-account │ │ └── blue-service-app │ │ │ ├── __init__.py │ │ │ ├── blue_p_e1 │ │ │ ├── __init__.py │ │ │ ├── requirements.txt │ │ │ └── app.py │ │ │ ├── blue_s_e2 │ │ │ ├── __init__.py │ │ │ ├── app.py │ │ │ └── requirements.txt │ │ │ ├── README.md │ │ │ ├── events │ │ │ └── event.json │ │ │ ├── pyproject.toml │ │ │ ├── Makefile │ │ │ ├── .gitignore │ │ │ └── template.yaml │ ├── orange-service-account │ │ └── orange-service-app │ │ │ ├── __init__.py │ │ │ ├── orange_p_e3 │ │ │ ├── __init__.py │ │ │ ├── requirements.txt │ │ │ └── app.py │ │ │ ├── orange_s_e2 │ │ │ ├── __init__.py │ │ │ ├── app.py │ │ │ └── requirements.txt │ │ │ ├── README.md │ │ │ ├── pyproject.toml │ │ │ ├── Makefile │ │ │ ├── events │ │ │ └── event.json │ │ │ └── .gitignore │ ├── purple-service-account │ │ └── purple-service-app │ │ │ ├── __init__.py │ │ │ ├── purple_p_e2 │ │ │ ├── __init__.py │ │ │ ├── requirements.txt │ │ │ └── app.py │ │ │ ├── purple_s_e1 │ │ │ ├── __init__.py │ │ │ ├── app.py │ │ │ └── requirements.txt │ │ │ ├── purple_s_e3 │ │ │ ├── __init__.py │ │ │ ├── app.py │ │ │ └── requirements.txt │ │ │ ├── README.md │ │ │ ├── pyproject.toml │ │ │ ├── Makefile │ │ │ ├── events │ │ │ └── event.json │ │ │ └── .gitignore │ ├── Makefile │ └── devops-account │ │ └── template.yaml ├── cross-region-cross-account-pattern │ ├── applications │ │ ├── account_1 │ │ │ └── template.yaml │ │ ├── account_3 │ │ │ ├── events.json │ │ │ └── template.yaml │ │ └── account_2 │ │ │ ├── events.json │ │ │ └── template.yaml │ ├── security │ │ └── account_1 │ │ │ ├── eu-central-1-rules.yaml │ │ │ ├── template.yaml │ │ │ └── us-east-1-rules.yaml │ ├── Makefile │ └── README.md └── README.md ├── docs └── images │ ├── sde.png │ ├── reinvent.png │ ├── account-a.png │ ├── account-b.png │ ├── account-c.png │ ├── cross-region.png │ ├── cross-region-rules.png │ ├── ecommerce-example.png │ ├── reinvent_building.png │ ├── reinvent_designing.png │ ├── reinvent_platform.png │ ├── multi-bus-multi-account.png │ └── single-bus-multi-account.png ├── CODE_OF_CONDUCT.md ├── LICENSE ├── CONTRIBUTING.md └── .gitignore /blog/account-a-web-store/order_function/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog/account-a-web-store/order_function/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 -------------------------------------------------------------------------------- /blog/account-c-invoice-processing/invoice_processing/invoice_processing_function/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/blue-service-account/blue-service-app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/orange-service-account/orange-service-app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/blue_p_e1/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/blue_s_e2/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/blue-service-account/blue-service-app/blue_p_e1/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/blue-service-account/blue-service-app/blue_s_e2/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/orange_p_e3/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/orange_s_e2/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_p_e2/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_s_e1/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_s_e3/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/orange-service-account/orange-service-app/orange_p_e3/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/orange-service-account/orange-service-app/orange_s_e2/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_p_e2/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_s_e1/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_s_e3/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog/account-c-invoice-processing/invoice_processing/requirements.txt: -------------------------------------------------------------------------------- 1 | requests==2.32.5 2 | six==1.17.0 3 | regex==2025.11.3 -------------------------------------------------------------------------------- /docs/images/sde.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-eventbridge-resource-policy-samples/HEAD/docs/images/sde.png -------------------------------------------------------------------------------- /docs/images/reinvent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-eventbridge-resource-policy-samples/HEAD/docs/images/reinvent.png -------------------------------------------------------------------------------- /docs/images/account-a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-eventbridge-resource-policy-samples/HEAD/docs/images/account-a.png -------------------------------------------------------------------------------- /docs/images/account-b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-eventbridge-resource-policy-samples/HEAD/docs/images/account-b.png -------------------------------------------------------------------------------- /docs/images/account-c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-eventbridge-resource-policy-samples/HEAD/docs/images/account-c.png -------------------------------------------------------------------------------- /docs/images/cross-region.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-eventbridge-resource-policy-samples/HEAD/docs/images/cross-region.png -------------------------------------------------------------------------------- /docs/images/cross-region-rules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-eventbridge-resource-policy-samples/HEAD/docs/images/cross-region-rules.png -------------------------------------------------------------------------------- /docs/images/ecommerce-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-eventbridge-resource-policy-samples/HEAD/docs/images/ecommerce-example.png -------------------------------------------------------------------------------- /docs/images/reinvent_building.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-eventbridge-resource-policy-samples/HEAD/docs/images/reinvent_building.png -------------------------------------------------------------------------------- /docs/images/reinvent_designing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-eventbridge-resource-policy-samples/HEAD/docs/images/reinvent_designing.png -------------------------------------------------------------------------------- /docs/images/reinvent_platform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-eventbridge-resource-policy-samples/HEAD/docs/images/reinvent_platform.png -------------------------------------------------------------------------------- /docs/images/multi-bus-multi-account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-eventbridge-resource-policy-samples/HEAD/docs/images/multi-bus-multi-account.png -------------------------------------------------------------------------------- /docs/images/single-bus-multi-account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-eventbridge-resource-policy-samples/HEAD/docs/images/single-bus-multi-account.png -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS := $(wildcard */*/.) 2 | 3 | dev-deps: $(SUBDIRS) 4 | $(SUBDIRS): 5 | $(MAKE) -C $@ dev-deps 6 | 7 | .PHONY: all $(SUBDIRS) 8 | 9 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS := $(wildcard */*/.) 2 | 3 | dev-deps: $(SUBDIRS) 4 | $(SUBDIRS): 5 | $(MAKE) -C $@ dev-deps 6 | 7 | .PHONY: all $(SUBDIRS) 8 | 9 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/README.md: -------------------------------------------------------------------------------- 1 | # Blue Service 2 | 3 | This application represents the Blue service application. It publishes "Event 1" and subscribes to "Event 2" from the Purple service. 4 | 5 | All events are published via the Blue event bus. 6 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/README.md: -------------------------------------------------------------------------------- 1 | # Orange Service 2 | 3 | This application represents the Orange service application. It publishes "Event 3" and subscribes to "Event 2" from the Purple service. 4 | 5 | All events are published via the Orange event bus. 6 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/blue-service-account/blue-service-app/README.md: -------------------------------------------------------------------------------- 1 | # Blue Service 2 | 3 | This application represents the Blue service application. It publishes "Event 1" and subscribes to "Event 2" from the Purple service. 4 | 5 | All events are published via the Devops event bus in another AWS account. 6 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/orange-service-account/orange-service-app/README.md: -------------------------------------------------------------------------------- 1 | # Orange Service 2 | 3 | This application represents the Orange service application. It publishes "Event 3" and subscribes to "Event 2" from the Purple service. 4 | 5 | All events are published via the Devops event bus in another AWS account. 6 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/README.md: -------------------------------------------------------------------------------- 1 | # Purple Service 2 | 3 | This application represents the Purple service application. It publishes "Event 2" and subscribes to "Event 1" from the Blue service and "Event 3" from the orange service 4 | 5 | All events are published via the Purple event bus. 6 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/README.md: -------------------------------------------------------------------------------- 1 | # Purple Service 2 | 3 | This application represents the Purple service application. It publishes "Event 2" and subscribes to "Event 1" from the Blue service and "Event 3" from the orange service 4 | 5 | All events are published via the Devops event bus in another AWS account. 6 | -------------------------------------------------------------------------------- /blog/account-a-web-store/events/put_events_cli.json: -------------------------------------------------------------------------------- 1 | aws events put-events --entries '[{"EventBusName":"ecommerce", "Source": "com.exampleCorp.webStore", "DetailType": "newOrderCreated", "Detail": "{ \"orderNo\": \"123\", \"orderDate\": \"2020-09-09T22:01:02Z\", \"customerId\": \"789\", \"lineItems\": [ { \"productCode\": \"P1\", \"quantityOrdered\": 3, \"unitPrice\": 23.5, \"currency\": \"USD\" } ]}" }]' -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/events/event.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c", 3 | "detail-type": "Scheduled Event", 4 | "source": "aws.events", 5 | "account": "123456789012", 6 | "time": "2020-12-01T00:00:00Z", 7 | "region": "us-east-1", 8 | "resources": [ 9 | "arn:aws:events:us-east-1:123456789012:rule/ExampleRule" 10 | ], 11 | "detail": {} 12 | } -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/blue-service-account/blue-service-app/events/event.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c", 3 | "detail-type": "Scheduled Event", 4 | "source": "aws.events", 5 | "account": "123456789012", 6 | "time": "2020-12-01T00:00:00Z", 7 | "region": "us-east-1", 8 | "resources": [ 9 | "arn:aws:events:us-east-1:123456789012:rule/ExampleRule" 10 | ], 11 | "detail": {} 12 | } -------------------------------------------------------------------------------- /blog/account-c-invoice-processing/events/event.json: -------------------------------------------------------------------------------- 1 | { 2 | "id":"7bf73129-1428-4cd3-a780-95db273d1602", 3 | "detail-type":"newOrderCreated", 4 | "source":"com.exampleCorp.webStore", 5 | "account":"123456789012", 6 | "time":"2015-11-11T21:29:54Z", 7 | "region":"us-east-1", 8 | "version":"0", 9 | "resources":[ 10 | "arn:aws:ec2:us-east-1:123456789012:instance/i-abcd1111" 11 | ], 12 | "detail":{ 13 | "ADD-YOUR-FIELDS-HERE":"" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /blog/account-c-invoice-processing/invoice_processing/schema/com_examplecorp_webstore/newordercreated/__init__.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import absolute_import 4 | 5 | from schema.com_examplecorp_webstore.newordercreated.marshaller import Marshaller 6 | from schema.com_examplecorp_webstore.newordercreated.AWSEvent import AWSEvent 7 | from schema.com_examplecorp_webstore.newordercreated.NewOrderCreated import NewOrderCreated 8 | from schema.com_examplecorp_webstore.newordercreated.NewOrderCreatedItem import NewOrderCreatedItem 9 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "blue-service-app" 3 | version = "0.1.0" 4 | description = "Blue service app for multi-bus multi-account pattern" 5 | authors = ["Stephen Liedig "] 6 | 7 | [tool.poetry.dependencies] 8 | python = "^3.12" 9 | boto3 = "^1.41.5" 10 | 11 | [tool.poetry.group.dev.dependencies] 12 | black = "^24.8.0" 13 | 14 | [build-system] 15 | requires = ["poetry-core"] 16 | build-backend = "poetry.core.masonry.api" 17 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/blue-service-account/blue-service-app/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "blue-service-app" 3 | version = "0.1.0" 4 | description = "Blue service app for single-bus multi-account pattern" 5 | authors = ["Stephen Liedig "] 6 | 7 | [tool.poetry.dependencies] 8 | python = "^3.12" 9 | boto3 = "^1.41.5" 10 | 11 | [tool.poetry.group.dev.dependencies] 12 | black = "^24.8.0" 13 | 14 | [build-system] 15 | requires = ["poetry-core"] 16 | build-backend = "poetry.core.masonry.api" 17 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "orange-service-app" 3 | version = "0.1.0" 4 | description = "Orange service app for multi-bus multi-account pattern" 5 | authors = ["Stephen Liedig "] 6 | 7 | [tool.poetry.dependencies] 8 | python = "^3.12" 9 | boto3 = "^1.41.5" 10 | 11 | [tool.poetry.group.dev.dependencies] 12 | black = "^24.8.0" 13 | 14 | [build-system] 15 | requires = ["poetry-core"] 16 | build-backend = "poetry.core.masonry.api" 17 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "purple-service-app" 3 | version = "0.1.0" 4 | description = "Purple service app for multi-bus multi-account pattern" 5 | authors = ["Stephen Liedig "] 6 | 7 | [tool.poetry.dependencies] 8 | python = "^3.12" 9 | boto3 = "^1.41.5" 10 | 11 | [tool.poetry.group.dev.dependencies] 12 | black = "^24.8.0" 13 | 14 | [build-system] 15 | requires = ["poetry-core"] 16 | build-backend = "poetry.core.masonry.api" 17 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/orange-service-account/orange-service-app/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "orange-service-app" 3 | version = "0.1.0" 4 | description = "Orange service app for single-bus multi-account pattern" 5 | authors = ["Stephen Liedig "] 6 | 7 | [tool.poetry.dependencies] 8 | python = "^3.12" 9 | boto3 = "^1.41.5" 10 | 11 | [tool.poetry.group.dev.dependencies] 12 | black = "^24.8.0" 13 | 14 | [build-system] 15 | requires = ["poetry-core"] 16 | build-backend = "poetry.core.masonry.api" 17 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "purple-service-app" 3 | version = "0.1.0" 4 | description = "Purple service app for single-bus multi-account pattern" 5 | authors = ["Stephen Liedig "] 6 | 7 | [tool.poetry.dependencies] 8 | python = "^3.12" 9 | boto3 = "^1.41.5" 10 | 11 | [tool.poetry.group.dev.dependencies] 12 | black = "^24.8.0" 13 | 14 | [build-system] 15 | requires = ["poetry-core"] 16 | build-backend = "poetry.core.masonry.api" 17 | -------------------------------------------------------------------------------- /blog/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "amazon-eventbridge-resource-policy-samples" 3 | version = "0.1.0" 4 | description = "Sample implementation that demonstrates how to apply Amazon EventBridge resource policies in cross account scenarios" 5 | authors = ["Stephen Liedig "] 6 | 7 | [tool.poetry.dependencies] 8 | python = "^3.12" 9 | boto3 = "^1.41.5" 10 | 11 | [tool.poetry.group.dev.dependencies] 12 | black = "^24.8.0" 13 | 14 | [build-system] 15 | requires = ["poetry-core"] 16 | build-backend = "poetry.core.masonry.api" 17 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/Makefile: -------------------------------------------------------------------------------- 1 | # build: test lint poetry-export 2 | lint: 3 | cfn-lint template.yaml -a cfn_lint_serverless.rules 4 | 5 | build: lint 6 | sam build --parallel --cached 7 | 8 | deploy: build 9 | sam deploy 10 | 11 | clean: 12 | find . \ 13 | -type f -name '*.py[co]' -delete \ 14 | -o -type f -name 'requirements.txt' -delete \ 15 | -o -type d -name __pycache__ -delete 16 | rm -rf .pytest_cache/ 17 | 18 | purge: clean 19 | sam delete --no-prompts 20 | rm -rf .aws-sam/ 21 | 22 | dev-init: 23 | poetry install --no-root 24 | 25 | dev-deps: 26 | poetry update 27 | poetry export -f requirements.txt --output requirements.txt 28 | cp requirements.txt blue_p_e1/ 29 | cp requirements.txt blue_s_e2/ 30 | rm ./requirements.txt 31 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/blue-service-account/blue-service-app/Makefile: -------------------------------------------------------------------------------- 1 | # build: test lint poetry-export 2 | lint: 3 | cfn-lint template.yaml -a cfn_lint_serverless.rules 4 | 5 | build: lint 6 | sam build --parallel --cached 7 | 8 | deploy: build 9 | sam deploy 10 | 11 | clean: 12 | find . \ 13 | -type f -name '*.py[co]' -delete \ 14 | -o -type f -name 'requirements.txt' -delete \ 15 | -o -type d -name __pycache__ -delete 16 | rm -rf .pytest_cache/ 17 | 18 | purge: clean 19 | sam delete --no-prompts 20 | rm -rf .aws-sam/ 21 | 22 | dev-init: 23 | poetry install --no-root 24 | 25 | dev-deps: 26 | poetry update 27 | poetry export -f requirements.txt --output requirements.txt 28 | cp requirements.txt blue_p_e1/ 29 | cp requirements.txt blue_s_e2/ 30 | rm ./requirements.txt 31 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/Makefile: -------------------------------------------------------------------------------- 1 | # build: test lint poetry-export 2 | lint: 3 | cfn-lint template.yaml -a cfn_lint_serverless.rules 4 | 5 | build: lint 6 | sam build --parallel --cached 7 | 8 | deploy: build 9 | sam deploy 10 | 11 | clean: 12 | find . \ 13 | -type f -name '*.py[co]' -delete \ 14 | -o -type f -name 'requirements.txt' -delete \ 15 | -o -type d -name __pycache__ -delete 16 | rm -rf .pytest_cache/ 17 | 18 | purge: clean 19 | sam delete --no-prompts 20 | rm -rf .aws-sam/ 21 | 22 | dev-init: 23 | poetry install --no-root 24 | 25 | dev-deps: 26 | poetry update 27 | poetry export -f requirements.txt --output requirements.txt 28 | cp requirements.txt orange_p_e3/ 29 | cp requirements.txt orange_s_e2/ 30 | rm ./requirements.txt 31 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/orange-service-account/orange-service-app/Makefile: -------------------------------------------------------------------------------- 1 | # build: test lint poetry-export 2 | lint: 3 | cfn-lint template.yaml -a cfn_lint_serverless.rules 4 | 5 | build: lint 6 | sam build --parallel --cached 7 | 8 | deploy: build 9 | sam deploy 10 | 11 | clean: 12 | find . \ 13 | -type f -name '*.py[co]' -delete \ 14 | -o -type f -name 'requirements.txt' -delete \ 15 | -o -type d -name __pycache__ -delete 16 | rm -rf .pytest_cache/ 17 | 18 | purge: clean 19 | sam delete --no-prompts 20 | rm -rf .aws-sam/ 21 | 22 | dev-init: 23 | poetry install --no-root 24 | 25 | dev-deps: 26 | poetry update 27 | poetry export -f requirements.txt --output requirements.txt 28 | cp requirements.txt orange_p_e3/ 29 | cp requirements.txt orange_s_e2/ 30 | rm ./requirements.txt 31 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/Makefile: -------------------------------------------------------------------------------- 1 | # build: test lint poetry-export 2 | lint: 3 | cfn-lint template.yaml -a cfn_lint_serverless.rules 4 | 5 | build: lint 6 | sam build --parallel --cached 7 | 8 | deploy: build 9 | sam deploy 10 | 11 | clean: 12 | find . \ 13 | -type f -name '*.py[co]' -delete \ 14 | -o -type f -name 'requirements.txt' -delete \ 15 | -o -type d -name __pycache__ -delete 16 | rm -rf .pytest_cache/ 17 | 18 | purge: clean 19 | sam delete --no-prompts 20 | rm -rf .aws-sam/ 21 | 22 | dev-init: 23 | poetry install --no-root 24 | 25 | dev-deps: 26 | poetry update 27 | poetry export -f requirements.txt --output requirements.txt 28 | cp requirements.txt purple_p_e2/ 29 | cp requirements.txt purple_s_e1/ 30 | cp requirements.txt purple_s_e3/ 31 | rm ./requirements.txt 32 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/Makefile: -------------------------------------------------------------------------------- 1 | # build: test lint poetry-export 2 | lint: 3 | cfn-lint template.yaml -a cfn_lint_serverless.rules 4 | 5 | build: lint 6 | sam build --parallel --cached 7 | 8 | deploy: build 9 | sam deploy 10 | 11 | release: build 12 | sam deploy --config-env prod 13 | 14 | # test: 15 | # pytest tests/unit/ 16 | 17 | clean: 18 | find . \ 19 | -type f -name '*.py[co]' -delete \ 20 | -o -type f -name 'requirements.txt' -delete \ 21 | -o -type d -name __pycache__ -delete 22 | rm -rf .pytest_cache/ 23 | 24 | purge: clean 25 | sam delete --no-prompts 26 | rm -rf .aws-sam/ 27 | 28 | dev-init: 29 | poetry install --no-root 30 | 31 | dev-deps: 32 | poetry update 33 | poetry export -f requirements.txt --output requirements.txt 34 | cp requirements.txt purple_p_e2/ 35 | cp requirements.txt purple_s_e1/ 36 | cp requirements.txt purple_s_e3/ 37 | rm ./requirements.txt 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /blog/account-c-invoice-processing/conftest.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import sys, os 15 | 16 | here = os.path.abspath("hello_world_function") 17 | sys.path.insert(0, here) -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/blue_s_e2/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import json 15 | 16 | 17 | def lambda_handler(event, context): 18 | print(event) 19 | return event -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/blue-service-account/blue-service-app/blue_s_e2/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import json 15 | 16 | 17 | def lambda_handler(event, context): 18 | print(event) 19 | return event -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/orange_s_e2/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import json 15 | 16 | 17 | def lambda_handler(event, context): 18 | print(event) 19 | return event -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_s_e1/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import json 15 | 16 | def lambda_handler(event, context): 17 | print(event) 18 | return event 19 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_s_e3/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import json 15 | 16 | def lambda_handler(event, context): 17 | print(event) 18 | return event 19 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/orange-service-account/orange-service-app/orange_s_e2/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import json 15 | 16 | 17 | def lambda_handler(event, context): 18 | print(event) 19 | return event -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_s_e1/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import json 15 | 16 | def lambda_handler(event, context): 17 | print(event) 18 | return event 19 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_s_e3/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import json 15 | 16 | def lambda_handler(event, context): 17 | print(event) 18 | return event 19 | -------------------------------------------------------------------------------- /blog/account-b-central-bus/README.md: -------------------------------------------------------------------------------- 1 | # Deploy the central event bus in account B 2 | 3 | This template creates the Central event bus in account B. **Make sure you deploy this first, before any other applications.** 4 | 5 | ![Walkthrough architecture](../../docs/images/account-b.png "Walkthrough architecture") 6 | 7 | For more details on the implementation visit the accompanying AWS blog post ["Simplifying cross-account access with Amazon EventBridge resource policies"](https://aws.amazon.com/blogs/compute/simplifying-cross-account-access-with-amazon-eventbridge-resource-policies) 8 | 9 | 10 | ## Deploy the application 11 | 12 | To install simply create a new stack via the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/home) or via the AWS CLI below (make sure to substitute your account details). 13 | 14 | The template takes three parameters: 15 | 16 | * **EventBusName:** Name of the central event bus 17 | * **AccountA:** Account number for account A 18 | * **AccountC:** Account number for account C 19 | 20 | 21 | 22 | ``` bash 23 | aws cloudformation create-stack / 24 | --stack-name central-event-bus / 25 | --template-body file://template.yaml / 26 | --parameters ParameterKey=AccountA,ParameterValue=111111111111 ParameterKey=AccountC,ParameterValue=2222222222222 27 | ``` 28 | -------------------------------------------------------------------------------- /patterns/cross-region-cross-account-pattern/applications/account_1/template.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | Transform: AWS::Serverless-2016-10-31 4 | Description: > 5 | Resource policy for default event bus in AWS Account 1 in us-east-1 6 | 7 | Parameters: 8 | SecurityAccountNo: 9 | Description: The account number where the security event bus is deployed 10 | Type: String 11 | 12 | Resources: 13 | 14 | # NOTE: Not defining an event bus for this account as we are using the 15 | # default event bus 16 | 17 | SecurityServiceRuleCreationStatement: 18 | Type: AWS::Events::EventBusPolicy 19 | Properties: 20 | StatementId: "AllowCrossRegionRulesForSecurityTeam" 21 | Statement: 22 | Effect: "Allow" 23 | Principal: 24 | AWS: !Sub "arn:aws:iam::${SecurityAccountNo}:root" 25 | Action: 26 | - "events:PutRule" 27 | - "events:DeleteRule" 28 | - "events:DescribeRule" 29 | - "events:DisableRule" 30 | - "events:EnableRule" 31 | - "events:PutTargets" 32 | - "events:RemoveTargets" 33 | Resource: 34 | - !Sub "arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/*" # default bus 35 | Condition: 36 | StringEqualsIfExists: 37 | "events:creatorAccount": "${aws:PrincipalAccount}" 38 | -------------------------------------------------------------------------------- /blog/account-b-central-bus/central-event-bus-resource-policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Sid": "WebStoreCrossAccountPublish", 6 | "Effect": "Allow", 7 | "Principal": { 8 | "AWS": "arn:aws:iam::[ACCOUNT-A]:root" 9 | }, 10 | "Action": "events:PutEvents", 11 | "Resource": "arn:aws:events:us-east-1:[ACCOUNT-B]:event-bus/central-event-bus", 12 | "Condition": { 13 | "StringEquals": { 14 | "events:detail-type": "newOrderCreated", 15 | "events:source": "com.exampleCorp.webStore" 16 | } 17 | } 18 | }, 19 | { 20 | "Sid": "InvoiceProcessingRuleCreation", 21 | "Effect": "Allow", 22 | "Principal": { 23 | "AWS": "arn:aws:iam::[ACCOUNT-C]:root" 24 | }, 25 | "Action": [ 26 | "events:PutRule", 27 | "events:DeleteRule", 28 | "events:DescribeRule", 29 | "events:DisableRule", 30 | "events:EnableRule", 31 | "events:PutTargets", 32 | "events:RemoveTargets" 33 | ], 34 | "Resource": "arn:aws:events:us-east-1:[ACCOUNT-B]:rule/central-event-bus/*", 35 | "Condition": { 36 | "StringEqualsIfExists": { 37 | "events:creatorAccount": "${aws:PrincipalAccount}", 38 | "events:source": "com.exampleCorp.webStore" 39 | } 40 | } 41 | } 42 | ] 43 | } -------------------------------------------------------------------------------- /blog/account-a-web-store/template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: "2010-09-09" 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: > 4 | Account A - Web store stack 5 | 6 | # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst 7 | Globals: 8 | Function: 9 | Timeout: 3 10 | 11 | Parameters: 12 | CentralEventBusArn: 13 | Description: The ARN of the central event bus # e.g. arn:aws:events:us-east-1:[ACCOUNT-B]:event-bus/central-event-bus 14 | Type: String 15 | 16 | Resources: 17 | OrderFunction: 18 | Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction 19 | Properties: 20 | CodeUri: order_function/ 21 | Handler: app.lambda_handler 22 | Runtime: python3.12 23 | Policies: 24 | - Version: '2012-10-17' 25 | Statement: 26 | - Effect: Allow 27 | Action: 28 | - events:PutEvents 29 | Resource: "*" 30 | Environment: 31 | Variables: 32 | CENTRAL_EVENT_BUS_ARN: !Ref CentralEventBusArn 33 | 34 | Outputs: 35 | OrderFunction: 36 | Description: "Hello World Lambda Function ARN" 37 | Value: !GetAtt OrderFunction.Arn 38 | OrderFunctionIamRole: 39 | Description: "Implicit IAM Role created for Hello World function" 40 | Value: !GetAtt OrderFunctionRole.Arn 41 | -------------------------------------------------------------------------------- /blog/account-a-web-store/publish.sh: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | #!/bin/bash 15 | counter=1 16 | while [ $counter -le 21 ] 17 | do 18 | echo $counter 19 | aws events put-events --entries '[{"EventBusName":"ecommerce", "Source": "com.exampleCorp.webStore", "DetailType": "newOrderCreated", "Detail": "{ \"orderNo\": \"123\", \"orderDate\": \"2020-09-09T22:01:02Z\", \"customerId\": \"789\", \"lineItems\": [ { \"productCode\": \"P1\", \"quantityOrdered\": 3, \"unitPrice\": 23.5, \"currency\": \"USD\" } ]}" }]' 20 | ((counter++)) 21 | done 22 | echo All done -------------------------------------------------------------------------------- /patterns/cross-region-cross-account-pattern/applications/account_3/events.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Source": "com.company.sales", 4 | "Detail": "{ \"customer_id\": \"1\", \"is_preferred\": \"yes\", \"city\": \"Perth\"}", 5 | "DetailType": "Sales Notification", 6 | "EventBusName": "custom-eventbus-account-3" 7 | }, 8 | { 9 | "Source": "com.company.sales", 10 | "Detail": "{ \"customer_id\": \"2\", \"is_preferred\": \"no\", \"city\": \"Sydney\"}", 11 | "DetailType": "Sales Notification", 12 | "EventBusName": "custom-eventbus-account-3" 13 | }, 14 | { 15 | "Source": "com.company.sales", 16 | "Detail": "{ \"customer_id\": \"3\", \"is_preferred\": \"yes\", \"city\": \"Brisbane\"}", 17 | "DetailType": "Sales Notification", 18 | "EventBusName": "custom-eventbus-account-3" 19 | }, 20 | { 21 | "Source": "com.company.sales", 22 | "Detail": "{ \"customer_id\": \"4\", \"is_preferred\": \"yes\", \"city\": \"Perth\"}", 23 | "DetailType": "Sales Notification", 24 | "EventBusName": "custom-eventbus-account-3" 25 | }, 26 | { 27 | "Source": "com.company.sales", 28 | "Detail": "{ \"customer_id\": \"5\", \"is_preferred\": \"no\", \"city\": \"Sydney\"}", 29 | "DetailType": "Sales Notification", 30 | "EventBusName": "custom-eventbus-account-3" 31 | }, 32 | { 33 | "Source": "com.company.sales", 34 | "Detail": "{ \"customer_id\": \"6\", \"is_preferred\": \"yes\", \"city\": \"Melbourne\"}", 35 | "DetailType": "Sales Notification", 36 | "EventBusName": "custom-eventbus-account-3" 37 | } 38 | ] 39 | -------------------------------------------------------------------------------- /patterns/cross-region-cross-account-pattern/applications/account_2/events.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Source": "com.company.marketing", 4 | "Detail": "{ \"category\": \"lab-supplies\", \"value\": 415, \"location\": \"eu-west\"}", 5 | "DetailType": "Marketing Notification", 6 | "EventBusName": "custom-eventbus-account-2" 7 | }, 8 | { 9 | "Source": "com.company.marketing", 10 | "Detail": "{ \"category\": \"office-supplies\", \"value\": 90, \"location\": \"us-west\"}", 11 | "DetailType": "Marketing Notification", 12 | "EventBusName": "custom-eventbus-account-2" 13 | }, 14 | { 15 | "Source": "com.company.marketing", 16 | "Detail": "{ \"category\": \"tech-supplies\", \"value\": 600, \"location\": \"us-east\"}", 17 | "DetailType": "Marketing Notification", 18 | "EventBusName": "custom-eventbus-account-2" 19 | }, 20 | { 21 | "Source": "com.company.marketing", 22 | "Detail": "{ \"category\": \"lab-supplies\", \"value\": 555, \"location\": \"eu-west\"}", 23 | "DetailType": "Marketing Notification", 24 | "EventBusName": "custom-eventbus-account-2" 25 | }, 26 | { 27 | "Source": "com.company.marketing", 28 | "Detail": "{ \"category\": \"office-supplies\", \"value\": 5, \"location\": \"us-west\"}", 29 | "DetailType": "Marketing Notification", 30 | "EventBusName": "custom-eventbus-account-2" 31 | }, 32 | { 33 | "Source": "com.company.marketing", 34 | "Detail": "{ \"category\": \"lab-supplies\", \"value\": 78, \"location\": \"eu-east\"}", 35 | "DetailType": "Marketing Notification", 36 | "EventBusName": "custom-eventbus-account-2" 37 | } 38 | ] 39 | -------------------------------------------------------------------------------- /patterns/cross-region-cross-account-pattern/applications/account_2/template.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | Transform: AWS::Serverless-2016-10-31 4 | Description: > 5 | Resource policy for default event bus in AWS Account 2 in us-east-1 6 | 7 | Parameters: 8 | EventBusName: 9 | Description: Name of the custom event bus 10 | Type: String 11 | 12 | SecurityAccountNo: 13 | Description: The account number where the security event bus is deployed 14 | Type: String 15 | 16 | Resources: 17 | 18 | CustomEventBus: 19 | Type: AWS::Events::EventBus 20 | Properties: 21 | Name: !Ref EventBusName 22 | 23 | SecurityServiceRuleCreationStatement: 24 | Type: AWS::Events::EventBusPolicy 25 | Properties: 26 | EventBusName: !Ref CustomEventBus # If you omit this, the default event bus is used. 27 | StatementId: "AllowCrossRegionRulesForSecurityTeam" 28 | Statement: 29 | Effect: "Allow" 30 | Principal: 31 | AWS: !Sub "arn:aws:iam::${SecurityAccountNo}:root" 32 | Action: 33 | - "events:PutRule" 34 | - "events:DeleteRule" 35 | - "events:DescribeRule" 36 | - "events:DisableRule" 37 | - "events:EnableRule" 38 | - "events:PutTargets" 39 | - "events:RemoveTargets" 40 | Resource: 41 | - !Sub 'arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/${CustomEventBus.Name}/*' 42 | Condition: 43 | StringEqualsIfExists: 44 | "events:creatorAccount": "${aws:PrincipalAccount}" 45 | 46 | Outputs: 47 | EventBus: 48 | Description: EventBus 49 | Value: !GetAtt CustomEventBus.Arn -------------------------------------------------------------------------------- /patterns/cross-region-cross-account-pattern/applications/account_3/template.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | Transform: AWS::Serverless-2016-10-31 4 | Description: > 5 | Resource policy for custom event bus in AWS Account 333333333333 in eu-central-1 6 | 7 | Parameters: 8 | EventBusName: 9 | Description: Name of the custom event bus 10 | Type: String 11 | 12 | SecurityAccountNo: 13 | Description: The account number where the security event bus is deployed 14 | Type: String 15 | 16 | 17 | Resources: 18 | 19 | CustomEventBus: 20 | Type: AWS::Events::EventBus 21 | Properties: 22 | Name: !Ref EventBusName 23 | 24 | SecurityServiceRuleCreationStatement: 25 | Type: AWS::Events::EventBusPolicy 26 | Properties: 27 | EventBusName: !Ref CustomEventBus # If you omit this, the default event bus is used. 28 | StatementId: "AllowCrossRegionRulesForSecurityTeam" 29 | Statement: 30 | Effect: "Allow" 31 | Principal: 32 | AWS: !Sub "arn:aws:iam::${SecurityAccountNo}:root" 33 | Action: 34 | - "events:PutRule" 35 | - "events:DeleteRule" 36 | - "events:DescribeRule" 37 | - "events:DisableRule" 38 | - "events:EnableRule" 39 | - "events:PutTargets" 40 | - "events:RemoveTargets" 41 | Resource: 42 | - !Sub 'arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/${CustomEventBus.Name}/*' 43 | Condition: 44 | StringEqualsIfExists: 45 | "events:creatorAccount": "${aws:PrincipalAccount}" 46 | 47 | Outputs: 48 | EventBus: 49 | Description: EventBus 50 | Value: !GetAtt CustomEventBus.Arn -------------------------------------------------------------------------------- /blog/account-a-web-store/events/put_events.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Source": "com.aws.orders", 4 | "Detail": "{ \"orderNo\": \"123\", \"orderNo\": \"2020-10-10T22:01:02Z\", \"customerId\": \"789\", \"lineItems\": [ { \"productCode\": \"P1\", \"quantityOrdered\": 3, \"unitPrice\": 23.5, \"currency\": \"USD\" } ]}", 5 | "DetailType": "Order Notification", 6 | "EventBusName": "Orders" 7 | }, 8 | { 9 | "Source": "com.aws.orders", 10 | "Detail": "{ \"orderNo\": 830, \"orderDate\": \"2020-11-23T03:04:46Z\", \"customerId\": 30, \"lineItems\": [ { \"productCode\": \"P1\", \"quantityOrdered\": 3, \"unitPrice\": 23.5, \"currency\": \"USD\" } ] }", 11 | "DetailType": "Order Notification", 12 | "EventBusName": "Orders" 13 | }, 14 | { 15 | "Source": "com.aws.orders", 16 | "Detail": "{ \"orderNo\": 149, \"orderDate\": \"2020-11-09T02:07:21Z\", \"customerId\": 41, \"lineItems\": [ { \"productCode\": \"P1\", \"quantityOrdered\": 3, \"unitPrice\": 23.5, \"currency\": \"USD\" } ] }", 17 | "DetailType": "Order Notification", 18 | "EventBusName": "Orders" 19 | }, 20 | { 21 | "Source": "com.aws.orders", 22 | "Detail": "{ \"orderNo\": 409, \"orderDate\": \"2020-11-22T03:32:13Z\", \"customerId\": 27, \"lineItems\": [ { \"productCode\": \"P1\", \"quantityOrdered\": 3, \"unitPrice\": 23.5, \"currency\": \"USD\" } ] }", 23 | "DetailType": "Order Notification", 24 | "EventBusName": "Orders" 25 | }, 26 | { 27 | "Source": "com.aws.orders", 28 | "Detail": "{ \"orderNo\": 183, \"orderDate\": \"2020-11-07T03:11:15Z\", \"customerId\": 51, \"lineItems\": [ { \"productCode\": \"P1\", \"quantityOrdered\": 3, \"unitPrice\": 23.5, \"currency\": \"USD\" } ] }", 29 | "DetailType": "Order Notification", 30 | "EventBusName": "Orders" 31 | } 32 | ] 33 | 34 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/blue_p_e1/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/blue_s_e2/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/blue-service-account/blue-service-app/blue_p_e1/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/blue-service-account/blue-service-app/blue_s_e2/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/orange_p_e3/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/orange_s_e2/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_p_e2/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_s_e1/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_s_e3/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/orange-service-account/orange-service-app/orange_p_e3/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/orange-service-account/orange-service-app/orange_s_e2/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_p_e2/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_s_e1/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_s_e3/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 2 | --hash=sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745 \ 3 | --hash=sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17 4 | botocore==1.41.5 ; python_version >= "3.12" and python_version < "4.0" \ 5 | --hash=sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf \ 6 | --hash=sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a 7 | jmespath==1.0.1 ; python_version >= "3.12" and python_version < "4.0" \ 8 | --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ 9 | --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe 10 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" \ 11 | --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ 12 | --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 13 | s3transfer==0.15.0 ; python_version >= "3.12" and python_version < "4.0" \ 14 | --hash=sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852 \ 15 | --hash=sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379 16 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0" \ 17 | --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ 18 | --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 19 | urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0" \ 20 | --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ 21 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc 22 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/blue_p_e1/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import os 15 | import json 16 | import boto3 17 | 18 | # pull the devops event bus arn from an environment variable where 19 | # DEVOPS_EVENT_BUS_ARN = 'arn:aws:events:us-east-1:[ACCOUNT-B]:event-bus/devops-event-bus' 20 | EVENT_BUS_ARN = os.environ['EVENT_BUS_ARN'] 21 | 22 | # Create EventBridge client 23 | events = boto3.client('events') 24 | 25 | def lambda_handler(event, context): 26 | 27 | # new order created event detail 28 | eventDetail = { 29 | "blueId": "123", 30 | "blueDate": "2020-12-09T22:01:02Z", 31 | "blueFoo": "bar", 32 | } 33 | 34 | try: 35 | # Put an event 36 | response = events.put_events( 37 | Entries=[ 38 | { 39 | 'EventBusName': EVENT_BUS_ARN, 40 | 'Source': 'com.exampleCorp.BlueService', 41 | 'DetailType': 'Event1', 42 | 'Detail': json.dumps(eventDetail) 43 | } 44 | ] 45 | ) 46 | print(response['Entries']) 47 | print(f"Event sent to the event bus {EVENT_BUS_ARN}") 48 | print(f"EventID is {response['Entries'][0]['EventId']}") 49 | except Exception as e: 50 | print(e) -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/blue-service-account/blue-service-app/blue_p_e1/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import os 15 | import json 16 | import boto3 17 | 18 | # pull the devops event bus arn from an environment variable where 19 | # DEVOPS_EVENT_BUS_ARN = 'arn:aws:events:us-east-1:[ACCOUNT-B]:event-bus/devops-event-bus' 20 | EVENT_BUS_ARN = os.environ['DEVOPS_EVENT_BUS_ARN'] 21 | 22 | # Create EventBridge client 23 | events = boto3.client('events') 24 | 25 | def lambda_handler(event, context): 26 | 27 | # new order created event detail 28 | eventDetail = { 29 | "blueId": "123", 30 | "blueDate": "2020-12-09T22:01:02Z", 31 | "blueFoo": "bar", 32 | } 33 | 34 | try: 35 | # Put an event 36 | response = events.put_events( 37 | Entries=[ 38 | { 39 | 'EventBusName': EVENT_BUS_ARN, 40 | 'Source': 'com.exampleCorp.BlueService', 41 | 'DetailType': 'Event1', 42 | 'Detail': json.dumps(eventDetail) 43 | } 44 | ] 45 | ) 46 | print(response['Entries']) 47 | print(f"Event sent to the event bus {EVENT_BUS_ARN}") 48 | print(f"EventID is {response['Entries'][0]['EventId']}") 49 | except Exception as e: 50 | print(e) -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/orange_p_e3/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import os 15 | import json 16 | import boto3 17 | 18 | # pull the devops event bus arn from an environment variable where 19 | # DEVOPS_EVENT_BUS_ARN = 'arn:aws:events:us-east-1:[ACCOUNT-B]:event-bus/devops-event-bus' 20 | EVENT_BUS_ARN = os.environ['EVENT_BUS_ARN'] 21 | 22 | # Create EventBridge client 23 | events = boto3.client('events') 24 | 25 | def lambda_handler(event, context): 26 | 27 | # new order created event detail 28 | eventDetail = { 29 | "orangeId": "456", 30 | "orangeDate": "2020-12-10T22:01:02Z", 31 | "orangeFoo": "bar", 32 | } 33 | 34 | try: 35 | # Put an event 36 | response = events.put_events( 37 | Entries=[ 38 | { 39 | 'EventBusName': EVENT_BUS_ARN, 40 | 'Source': 'com.exampleCorp.OrangeService', 41 | 'DetailType': 'Event3', 42 | 'Detail': json.dumps(eventDetail) 43 | } 44 | ] 45 | ) 46 | print(response['Entries']) 47 | print(f"Event sent to the event bus {EVENT_BUS_ARN}") 48 | print(f"EventID is {response['Entries'][0]['EventId']}") 49 | except Exception as e: 50 | print(e) -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_p_e2/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import os 15 | import json 16 | import boto3 17 | 18 | # pull the devops event bus arn from an environment variable where 19 | # DEVOPS_EVENT_BUS_ARN = 'arn:aws:events:us-east-1:[ACCOUNT-B]:event-bus/devops-event-bus' 20 | EVENT_BUS_ARN = os.environ['EVENT_BUS_ARN'] 21 | 22 | # Create EventBridge client 23 | events = boto3.client('events') 24 | 25 | def lambda_handler(event, context): 26 | 27 | # new order created event detail 28 | eventDetail = { 29 | "purpleId": "789", 30 | "purpleDate": "2020-12-11T22:01:02Z", 31 | "purpleFoo": "bar", 32 | } 33 | 34 | try: 35 | # Put an event 36 | response = events.put_events( 37 | Entries=[ 38 | { 39 | 'EventBusName': EVENT_BUS_ARN, 40 | 'Source': 'com.exampleCorp.PurpleService', 41 | 'DetailType': 'Event2', 42 | 'Detail': json.dumps(eventDetail) 43 | } 44 | ] 45 | ) 46 | print(response['Entries']) 47 | print(f"Event sent to the event bus {EVENT_BUS_ARN}") 48 | print(f"EventID is {response['Entries'][0]['EventId']}") 49 | except Exception as e: 50 | print(e) -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/orange-service-account/orange-service-app/orange_p_e3/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import os 15 | import json 16 | import boto3 17 | 18 | # pull the devops event bus arn from an environment variable where 19 | # DEVOPS_EVENT_BUS_ARN = 'arn:aws:events:us-east-1:[ACCOUNT-B]:event-bus/devops-event-bus' 20 | EVENT_BUS_ARN = os.environ['DEVOPS_EVENT_BUS_ARN'] 21 | 22 | # Create EventBridge client 23 | events = boto3.client('events') 24 | 25 | def lambda_handler(event, context): 26 | 27 | # new order created event detail 28 | eventDetail = { 29 | "orangeId": "456", 30 | "orangeDate": "2020-12-10T22:01:02Z", 31 | "orangeFoo": "bar", 32 | } 33 | 34 | try: 35 | # Put an event 36 | response = events.put_events( 37 | Entries=[ 38 | { 39 | 'EventBusName': EVENT_BUS_ARN, 40 | 'Source': 'com.exampleCorp.OrangeService', 41 | 'DetailType': 'Event3', 42 | 'Detail': json.dumps(eventDetail) 43 | } 44 | ] 45 | ) 46 | print(response['Entries']) 47 | print(f"Event sent to the event bus {EVENT_BUS_ARN}") 48 | print(f"EventID is {response['Entries'][0]['EventId']}") 49 | except Exception as e: 50 | print(e) -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/purple_p_e2/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import os 15 | import json 16 | import boto3 17 | 18 | # pull the devops event bus arn from an environment variable where 19 | # DEVOPS_EVENT_BUS_ARN = 'arn:aws:events:us-east-1:[ACCOUNT-B]:event-bus/devops-event-bus' 20 | EVENT_BUS_ARN = os.environ['DEVOPS_EVENT_BUS_ARN'] 21 | 22 | # Create EventBridge client 23 | events = boto3.client('events') 24 | 25 | def lambda_handler(event, context): 26 | 27 | # new order created event detail 28 | eventDetail = { 29 | "purpleId": "789", 30 | "purpleDate": "2020-12-11T22:01:02Z", 31 | "purpleFoo": "bar", 32 | } 33 | 34 | try: 35 | # Put an event 36 | response = events.put_events( 37 | Entries=[ 38 | { 39 | 'EventBusName': EVENT_BUS_ARN, 40 | 'Source': 'com.exampleCorp.PurpleService', 41 | 'DetailType': 'Event2', 42 | 'Detail': json.dumps(eventDetail) 43 | } 44 | ] 45 | ) 46 | print(response['Entries']) 47 | print(f"Event sent to the event bus {EVENT_BUS_ARN}") 48 | print(f"EventID is {response['Entries'][0]['EventId']}") 49 | except Exception as e: 50 | print(e) -------------------------------------------------------------------------------- /patterns/cross-region-cross-account-pattern/security/account_1/eu-central-1-rules.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: 2010-09-09 3 | 4 | Parameters: 5 | SecurityEventBusArn: 6 | Description: ARN of the Security event bus. This is the target for security rules in this region. 7 | Type: String 8 | 9 | EventBusArnAccount3: 10 | Description: ARN of the default event bus in Account 3 11 | Type: String 12 | 13 | Resources: 14 | 15 | # This IAM role allows EventBridge to assume the permissions necessary to send events 16 | # from the source event buses to the destination event bus. 17 | SourceToDestinationEventBusRole: 18 | Type: "AWS::IAM::Role" 19 | Properties: 20 | AssumeRolePolicyDocument: 21 | Version: 2012-10-17 22 | Statement: 23 | - Effect: Allow 24 | Principal: 25 | Service: 26 | - events.amazonaws.com 27 | Action: 28 | - "sts:AssumeRole" 29 | Path: / 30 | Policies: 31 | - PolicyName: PutEventsOnDestinationEventBus 32 | PolicyDocument: 33 | Version: 2012-10-17 34 | Statement: 35 | - Effect: Allow 36 | Action: "events:PutEvents" 37 | Resource: 38 | - !Ref SecurityEventBusArn 39 | 40 | SecurityAuditRule3: 41 | Type: AWS::Events::Rule 42 | Properties: 43 | Name: SecurityAuditRuleAccount3 44 | Description: Audit rule for the Security team in Europe 45 | EventBusName: !Ref EventBusArnAccount3 # ARN of the custom event bus in Account 2 46 | EventPattern: 47 | source: 48 | - com.company.sales 49 | State: ENABLED 50 | Targets: 51 | - Id: SendEventToSecurityEventBusArn 52 | Arn: !Ref SecurityEventBusArn 53 | RoleArn: !GetAtt SourceToDestinationEventBusRole.Arn 54 | 55 | Outputs: 56 | SourceToDestinationEventBusRole: 57 | Description: ARN of the role that allows EventBridge to assume permissions to send events to another event bus 58 | Value: !GetAtt SourceToDestinationEventBusRole.Arn 59 | 60 | SecurityAuditRule1Arn: 61 | Description: ARN of the security audit rule 3 62 | Value: !GetAtt SecurityAuditRule3.Arn -------------------------------------------------------------------------------- /blog/account-b-central-bus/template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: "2010-09-09" 2 | Description: > 3 | Account B - Central event bus stack 4 | 5 | Parameters: 6 | EventBusName: 7 | Description: Name of the central event bus 8 | Type: String 9 | Default: central-event-bus 10 | AccountA: 11 | Description: Account number for account A 12 | Type: String 13 | AccountC: 14 | Description: Account number for account C 15 | Type: String 16 | 17 | Resources: 18 | CentralEventBus: 19 | Type: AWS::Events::EventBus 20 | Properties: 21 | Name: !Ref EventBusName 22 | 23 | WebStoreCrossAccountPublishStatement: 24 | Type: AWS::Events::EventBusPolicy 25 | Properties: 26 | EventBusName: !Ref CentralEventBus 27 | StatementId: "WebStoreCrossAccountPublish" 28 | Statement: 29 | Effect: "Allow" 30 | Principal: 31 | AWS: !Sub arn:aws:iam::${AccountA}:root 32 | Action: "events:PutEvents" 33 | Resource: !GetAtt CentralEventBus.Arn 34 | Condition: 35 | StringEquals: 36 | "events:detail-type": "newOrderCreated" 37 | "events:source": "com.exampleCorp.webStore" 38 | 39 | InvoiceProcessingRuleCreationStatement: 40 | Type: AWS::Events::EventBusPolicy 41 | Properties: 42 | EventBusName: !Ref CentralEventBus 43 | StatementId: "InvoiceProcessingRuleCreation" 44 | Statement: 45 | Effect: "Allow" 46 | Principal: 47 | AWS: !Sub arn:aws:iam::${AccountC}:root 48 | Action: 49 | - "events:PutRule" 50 | - "events:DeleteRule" 51 | - "events:DescribeRule" 52 | - "events:DisableRule" 53 | - "events:EnableRule" 54 | - "events:PutTargets" 55 | - "events:RemoveTargets" 56 | Resource: 57 | - !Sub arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/${CentralEventBus.Name}/* 58 | Condition: 59 | StringEqualsIfExists: 60 | "events:creatorAccount": "${aws:PrincipalAccount}" 61 | "events:source": "com.exampleCorp.webStore" 62 | 63 | Outputs: 64 | CentralEventBusArn: 65 | Description: The ARN of the central event bus 66 | Value: !GetAtt CentralEventBus.Arn 67 | -------------------------------------------------------------------------------- /blog/account-c-invoice-processing/invoice_processing/invoice_processing_function/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | from schema.com_examplecorp_webstore.newordercreated import Marshaller 15 | from schema.com_examplecorp_webstore.newordercreated import AWSEvent 16 | from schema.com_examplecorp_webstore.newordercreated import NewOrderCreated 17 | 18 | 19 | def lambda_handler(event, context): 20 | """Sample Lambda function reacting to EventBridge events 21 | 22 | Parameters 23 | ---------- 24 | event: dict, required 25 | Event Bridge Events Format 26 | 27 | Event doc: https://docs.aws.amazon.com/eventbridge/latest/userguide/event-types.html 28 | 29 | context: object, required 30 | Lambda Context runtime methods and attributes 31 | 32 | Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html 33 | 34 | Returns 35 | ------ 36 | The same input event file 37 | """ 38 | print(event) 39 | 40 | #Deserialize event into strongly typed object 41 | awsEvent:AWSEvent = Marshaller.unmarshall(event, AWSEvent) 42 | detail:NewOrderCreated = awsEvent.detail 43 | 44 | #Execute business logic 45 | print(f"Invoice Processing function processed event {awsEvent.detail_type}") 46 | 47 | #Return event for further processing 48 | return Marshaller.marshall(awsEvent) 49 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/events/event.json: -------------------------------------------------------------------------------- 1 | { 2 | "body": "{\"message\": \"hello world\"}", 3 | "resource": "/{proxy+}", 4 | "path": "/path/to/resource", 5 | "httpMethod": "POST", 6 | "isBase64Encoded": false, 7 | "queryStringParameters": { 8 | "foo": "bar" 9 | }, 10 | "pathParameters": { 11 | "proxy": "/path/to/resource" 12 | }, 13 | "stageVariables": { 14 | "baz": "qux" 15 | }, 16 | "headers": { 17 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", 18 | "Accept-Encoding": "gzip, deflate, sdch", 19 | "Accept-Language": "en-US,en;q=0.8", 20 | "Cache-Control": "max-age=0", 21 | "CloudFront-Forwarded-Proto": "https", 22 | "CloudFront-Is-Desktop-Viewer": "true", 23 | "CloudFront-Is-Mobile-Viewer": "false", 24 | "CloudFront-Is-SmartTV-Viewer": "false", 25 | "CloudFront-Is-Tablet-Viewer": "false", 26 | "CloudFront-Viewer-Country": "US", 27 | "Host": "1234567890.execute-api.us-east-1.amazonaws.com", 28 | "Upgrade-Insecure-Requests": "1", 29 | "User-Agent": "Custom User Agent String", 30 | "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", 31 | "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", 32 | "X-Forwarded-For": "127.0.0.1, 127.0.0.2", 33 | "X-Forwarded-Port": "443", 34 | "X-Forwarded-Proto": "https" 35 | }, 36 | "requestContext": { 37 | "accountId": "123456789012", 38 | "resourceId": "123456", 39 | "stage": "prod", 40 | "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", 41 | "requestTime": "09/Apr/2015:12:34:56 +0000", 42 | "requestTimeEpoch": 1428582896000, 43 | "identity": { 44 | "cognitoIdentityPoolId": null, 45 | "accountId": null, 46 | "cognitoIdentityId": null, 47 | "caller": null, 48 | "accessKey": null, 49 | "sourceIp": "127.0.0.1", 50 | "cognitoAuthenticationType": null, 51 | "cognitoAuthenticationProvider": null, 52 | "userArn": null, 53 | "userAgent": "Custom User Agent String", 54 | "user": null 55 | }, 56 | "path": "/prod/path/to/resource", 57 | "resourcePath": "/{proxy+}", 58 | "httpMethod": "POST", 59 | "apiId": "1234567890", 60 | "protocol": "HTTP/1.1" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/events/event.json: -------------------------------------------------------------------------------- 1 | { 2 | "body": "{\"message\": \"hello world\"}", 3 | "resource": "/{proxy+}", 4 | "path": "/path/to/resource", 5 | "httpMethod": "POST", 6 | "isBase64Encoded": false, 7 | "queryStringParameters": { 8 | "foo": "bar" 9 | }, 10 | "pathParameters": { 11 | "proxy": "/path/to/resource" 12 | }, 13 | "stageVariables": { 14 | "baz": "qux" 15 | }, 16 | "headers": { 17 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", 18 | "Accept-Encoding": "gzip, deflate, sdch", 19 | "Accept-Language": "en-US,en;q=0.8", 20 | "Cache-Control": "max-age=0", 21 | "CloudFront-Forwarded-Proto": "https", 22 | "CloudFront-Is-Desktop-Viewer": "true", 23 | "CloudFront-Is-Mobile-Viewer": "false", 24 | "CloudFront-Is-SmartTV-Viewer": "false", 25 | "CloudFront-Is-Tablet-Viewer": "false", 26 | "CloudFront-Viewer-Country": "US", 27 | "Host": "1234567890.execute-api.us-east-1.amazonaws.com", 28 | "Upgrade-Insecure-Requests": "1", 29 | "User-Agent": "Custom User Agent String", 30 | "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", 31 | "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", 32 | "X-Forwarded-For": "127.0.0.1, 127.0.0.2", 33 | "X-Forwarded-Port": "443", 34 | "X-Forwarded-Proto": "https" 35 | }, 36 | "requestContext": { 37 | "accountId": "123456789012", 38 | "resourceId": "123456", 39 | "stage": "prod", 40 | "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", 41 | "requestTime": "09/Apr/2015:12:34:56 +0000", 42 | "requestTimeEpoch": 1428582896000, 43 | "identity": { 44 | "cognitoIdentityPoolId": null, 45 | "accountId": null, 46 | "cognitoIdentityId": null, 47 | "caller": null, 48 | "accessKey": null, 49 | "sourceIp": "127.0.0.1", 50 | "cognitoAuthenticationType": null, 51 | "cognitoAuthenticationProvider": null, 52 | "userArn": null, 53 | "userAgent": "Custom User Agent String", 54 | "user": null 55 | }, 56 | "path": "/prod/path/to/resource", 57 | "resourcePath": "/{proxy+}", 58 | "httpMethod": "POST", 59 | "apiId": "1234567890", 60 | "protocol": "HTTP/1.1" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/orange-service-account/orange-service-app/events/event.json: -------------------------------------------------------------------------------- 1 | { 2 | "body": "{\"message\": \"hello world\"}", 3 | "resource": "/{proxy+}", 4 | "path": "/path/to/resource", 5 | "httpMethod": "POST", 6 | "isBase64Encoded": false, 7 | "queryStringParameters": { 8 | "foo": "bar" 9 | }, 10 | "pathParameters": { 11 | "proxy": "/path/to/resource" 12 | }, 13 | "stageVariables": { 14 | "baz": "qux" 15 | }, 16 | "headers": { 17 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", 18 | "Accept-Encoding": "gzip, deflate, sdch", 19 | "Accept-Language": "en-US,en;q=0.8", 20 | "Cache-Control": "max-age=0", 21 | "CloudFront-Forwarded-Proto": "https", 22 | "CloudFront-Is-Desktop-Viewer": "true", 23 | "CloudFront-Is-Mobile-Viewer": "false", 24 | "CloudFront-Is-SmartTV-Viewer": "false", 25 | "CloudFront-Is-Tablet-Viewer": "false", 26 | "CloudFront-Viewer-Country": "US", 27 | "Host": "1234567890.execute-api.us-east-1.amazonaws.com", 28 | "Upgrade-Insecure-Requests": "1", 29 | "User-Agent": "Custom User Agent String", 30 | "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", 31 | "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", 32 | "X-Forwarded-For": "127.0.0.1, 127.0.0.2", 33 | "X-Forwarded-Port": "443", 34 | "X-Forwarded-Proto": "https" 35 | }, 36 | "requestContext": { 37 | "accountId": "123456789012", 38 | "resourceId": "123456", 39 | "stage": "prod", 40 | "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", 41 | "requestTime": "09/Apr/2015:12:34:56 +0000", 42 | "requestTimeEpoch": 1428582896000, 43 | "identity": { 44 | "cognitoIdentityPoolId": null, 45 | "accountId": null, 46 | "cognitoIdentityId": null, 47 | "caller": null, 48 | "accessKey": null, 49 | "sourceIp": "127.0.0.1", 50 | "cognitoAuthenticationType": null, 51 | "cognitoAuthenticationProvider": null, 52 | "userArn": null, 53 | "userAgent": "Custom User Agent String", 54 | "user": null 55 | }, 56 | "path": "/prod/path/to/resource", 57 | "resourcePath": "/{proxy+}", 58 | "httpMethod": "POST", 59 | "apiId": "1234567890", 60 | "protocol": "HTTP/1.1" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/events/event.json: -------------------------------------------------------------------------------- 1 | { 2 | "body": "{\"message\": \"hello world\"}", 3 | "resource": "/{proxy+}", 4 | "path": "/path/to/resource", 5 | "httpMethod": "POST", 6 | "isBase64Encoded": false, 7 | "queryStringParameters": { 8 | "foo": "bar" 9 | }, 10 | "pathParameters": { 11 | "proxy": "/path/to/resource" 12 | }, 13 | "stageVariables": { 14 | "baz": "qux" 15 | }, 16 | "headers": { 17 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", 18 | "Accept-Encoding": "gzip, deflate, sdch", 19 | "Accept-Language": "en-US,en;q=0.8", 20 | "Cache-Control": "max-age=0", 21 | "CloudFront-Forwarded-Proto": "https", 22 | "CloudFront-Is-Desktop-Viewer": "true", 23 | "CloudFront-Is-Mobile-Viewer": "false", 24 | "CloudFront-Is-SmartTV-Viewer": "false", 25 | "CloudFront-Is-Tablet-Viewer": "false", 26 | "CloudFront-Viewer-Country": "US", 27 | "Host": "1234567890.execute-api.us-east-1.amazonaws.com", 28 | "Upgrade-Insecure-Requests": "1", 29 | "User-Agent": "Custom User Agent String", 30 | "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", 31 | "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", 32 | "X-Forwarded-For": "127.0.0.1, 127.0.0.2", 33 | "X-Forwarded-Port": "443", 34 | "X-Forwarded-Proto": "https" 35 | }, 36 | "requestContext": { 37 | "accountId": "123456789012", 38 | "resourceId": "123456", 39 | "stage": "prod", 40 | "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", 41 | "requestTime": "09/Apr/2015:12:34:56 +0000", 42 | "requestTimeEpoch": 1428582896000, 43 | "identity": { 44 | "cognitoIdentityPoolId": null, 45 | "accountId": null, 46 | "cognitoIdentityId": null, 47 | "caller": null, 48 | "accessKey": null, 49 | "sourceIp": "127.0.0.1", 50 | "cognitoAuthenticationType": null, 51 | "cognitoAuthenticationProvider": null, 52 | "userArn": null, 53 | "userAgent": "Custom User Agent String", 54 | "user": null 55 | }, 56 | "path": "/prod/path/to/resource", 57 | "resourcePath": "/{proxy+}", 58 | "httpMethod": "POST", 59 | "apiId": "1234567890", 60 | "protocol": "HTTP/1.1" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /blog/README.md: -------------------------------------------------------------------------------- 1 | # Simplifying cross-account access with Amazon EventBridge resource policies 2 | 3 | > **For more details on the implementation visit the [accompanying AWS blog post](https://aws.amazon.com/blogs/compute/simplifying-cross-account-access-with-amazon-eventbridge-resource-policies)** 4 | 5 | In this ecommerce example, there are multiple services distributed across different accounts. A web store publishes an event when a new order is created. The event is sent via a central event bus, which is in another account. The bus has two rules with target services in different AWS accounts. 6 | 7 | ![Walkthrough architecture](../docs/images/ecommerce-example.png "Walkthrough architecture") 8 | 9 | The goal is to create fine-grained permissions that only allow: 10 | 11 | * The web store to publish events for a specific detail-type and source. 12 | * The invoice processing service to create and manage its own rules on the central bus. 13 | 14 | To complete this walk through, you set up three accounts. For account A (Web Store), you deploy an [AWS Lambda](https://aws.amazon.com/lambda) function that sends the `newOrderCreated` event directly to the `central event bus` in account B. The invoice processing Lambda function in account C creates a rule on the central event bus to process the event published by account A. 15 | 16 | ## Requirements 17 | 18 | * AWS CLI already configured with Administrator permission 19 | * [AWS SAM CLI installed](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) 20 | 21 | ## Installation Instructions 22 | 23 | 1. [Create 3 AWS accounts](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have them and login. 24 | 25 | 2. Clone the repo onto your local development machine: 26 | 27 | ``` bash 28 | git clone https://github.com/aws-samples/amazon-eventbridge-resource-policy-samples 29 | ``` 30 | 31 | ## Getting started 32 | 33 | To get started follow the instructions on [deploying the central event bus to account B](account-b-central-bus/README.md) 34 | 35 | ## Next Steps 36 | 37 | The AWS Compute Blog series and video link at the top of this README file contains additional information about the application design and architecture. 38 | 39 | If you have any questions, please contact the author or raise an issue in the GitHub repo. -------------------------------------------------------------------------------- /blog/account-a-web-store/order_function/app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | import os 15 | import json 16 | import boto3 17 | 18 | # pull the central event bus arn from an environment variable where 19 | # CENTRAL_EVENT_BUS_ARN = 'arn:aws:events:us-east-1:[ACCOUNT-B]:event-bus/central-event-bus' 20 | EVENT_BUS_ARN = os.environ['CENTRAL_EVENT_BUS_ARN'] 21 | 22 | # Create EventBridge client 23 | events = boto3.client('events') 24 | 25 | def lambda_handler(event, context): 26 | 27 | # new order created event detail 28 | eventDetail = { 29 | "orderNo": "123", 30 | "orderDate": "2020-09-09T22:01:02Z", 31 | "customerId": "789", 32 | "lineItems": { 33 | "productCode": "P1", 34 | "quantityOrdered": 3, 35 | "unitPrice": 23.5, 36 | "currency": "USD" 37 | } 38 | } 39 | 40 | try: 41 | # Put an event 42 | response = events.put_events( 43 | Entries=[ 44 | { 45 | 'EventBusName': EVENT_BUS_ARN, 46 | 'Source': 'com.exampleCorp.webStore', 47 | 'DetailType': 'newOrderCreated', 48 | 'Detail': json.dumps(eventDetail) 49 | } 50 | ] 51 | ) 52 | print(response['Entries']) 53 | print(f"Event sent to the event bus {EVENT_BUS_ARN}") 54 | print(f"EventID is {response['Entries'][0]['EventId']}") 55 | except Exception as e: 56 | print(e) 57 | -------------------------------------------------------------------------------- /patterns/cross-region-cross-account-pattern/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: deploy-source deploy-destination get-source-event-bus-arn 2 | 3 | SECURITY_ACCOUNT_NO := "999999999999" 4 | 5 | TEMPLATE_FILE := "" 6 | TARGET_REGION := "ap-southeast-1" 7 | 8 | # Add your profile names here 9 | PROFILE1 := "profile_for_account_1" 10 | PROFILE2 := "profile_for_account_2" 11 | PROFILE3 := "profile_for_account_3" 12 | 13 | SECURITYEVENTBUSARN := "" 14 | EVENTBUSARNACCOUNT1 := "" 15 | EVENTBUSARNACCOUNT2 := "" 16 | EVENTBUSARNACCOUNT3 := "" 17 | 18 | 19 | deploy-source: source-1 source-2 source-3 20 | 21 | source-1: 22 | $(MAKE) source \ 23 | TEMPLATE_FILE=applications/account_1/template.yaml \ 24 | TARGET_REGION=us-east-1 \ 25 | STACK_NAME=default-event-bus-policy-account-1 \ 26 | PROFILE=$(PROFILE1) \ 27 | PARAMETER_OVERRIDES="SecurityAccountNo=\"$(SECURITY_ACCOUNT_NO)\"" 28 | 29 | source-2: 30 | $(MAKE) source \ 31 | TEMPLATE_FILE=applications/account_2/template.yaml \ 32 | TARGET_REGION=us-east-1 \ 33 | STACK_NAME=custom-bus-account-2 \ 34 | PROFILE=$(PROFILE2) \ 35 | PARAMETER_OVERRIDES="SecurityAccountNo=\"$(SECURITY_ACCOUNT_NO)\" EventBusName=\"custom-eventbus-account-2\"" 36 | 37 | source-3: 38 | $(MAKE) source \ 39 | TEMPLATE_FILE=applications/account_3/template.yaml \ 40 | TARGET_REGION=eu-central-1 \ 41 | STACK_NAME=custom-bus-account-3 \ 42 | PROFILE=$(PROFILE3) \ 43 | PARAMETER_OVERRIDES="SecurityAccountNo=\"$(SECURITY_ACCOUNT_NO)\" EventBusName=\"custom-eventbus-account-3\"" 44 | 45 | source: 46 | cfn-lint $(TEMPLATE_FILE) 47 | 48 | - sam deploy -t $(TEMPLATE_FILE) \ 49 | --stack-name $(STACK_NAME) \ 50 | --region $(TARGET_REGION) \ 51 | --profile $(PROFILE) \ 52 | --capabilities=CAPABILITY_IAM \ 53 | --parameter-overrides $(PARAMETER_OVERRIDES) 54 | 55 | deploy-security-bus: 56 | $(MAKE) security-bus \ 57 | TEMPLATE_FILE=security/account_1/template.yaml \ 58 | PROFILE=$(PROFILE1) 59 | 60 | security-bus: 61 | cfn-lint $(TEMPLATE_FILE) 62 | 63 | - sam deploy -t $(TEMPLATE_FILE) \ 64 | --stack-name security-event-bus \ 65 | --capabilities=CAPABILITY_IAM \ 66 | --region $(TARGET_REGION) \ 67 | --profile $(PROFILE) 68 | 69 | deploy-rules: rules-us rules-eu 70 | 71 | rules-us: 72 | $(MAKE) rules \ 73 | TEMPLATE_FILE=security/account_1/us-east-1-rules.yaml \ 74 | TARGET_REGION=us-east-1 \ 75 | STACK_NAME=us-east-1-rules \ 76 | PROFILE=$(PROFILE1) \ 77 | PARAMETER_OVERRIDES="SecurityEventBusArn=\"$(SECURITYEVENTBUSARN)\" EventBusArnAccount1=\"$(EVENTBUSARNACCOUNT1)\" EventBusArnAccount2=\"$(EVENTBUSARNACCOUNT2)\"" 78 | 79 | rules-eu: 80 | $(MAKE) rules \ 81 | TEMPLATE_FILE=security/account_1/eu-central-1-rules.yaml \ 82 | TARGET_REGION=eu-central-1 \ 83 | STACK_NAME=eu-central-1-rules \ 84 | PROFILE=$(PROFILE3) \ 85 | PARAMETER_OVERRIDES="SecurityEventBusArn=\"$(SECURITYEVENTBUSARN)\" EventBusArnAccount3=\"$(EVENTBUSARNACCOUNT3)"" 86 | 87 | rules: 88 | cfn-lint $(TEMPLATE_FILE) 89 | 90 | - sam deploy -t $(TEMPLATE_FILE) \ 91 | --stack-name $(STACK_NAME) \ 92 | --region $(TARGET_REGION) \ 93 | --profile $(PROFILE) \ 94 | --capabilities=CAPABILITY_IAM \ 95 | --parameter-overrides $(PARAMETER_OVERRIDES) 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /patterns/cross-region-cross-account-pattern/security/account_1/template.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: "2010-09-09" 3 | Transform: AWS::Serverless-2016-10-31 4 | Description: > 5 | Resource policy for security event bus in AWS Account 11111111111 in ap-southeast-1 6 | 7 | Parameters: 8 | SecurityEventBusName: 9 | Description: Event bus receiving cross-Region events 10 | Type: String 11 | Default: SecurityEventBus 12 | 13 | Resources: 14 | SecurityEventBus: 15 | Type: AWS::Events::EventBus 16 | Properties: 17 | Name: !Ref SecurityEventBusName 18 | 19 | # This rule processes events coming in from cross-Region accounts 20 | SecurityAnalysisRule: 21 | Type: AWS::Events::Rule 22 | Properties: 23 | Name: SecurityAnalysisRule 24 | Description: Analyse events from cross-Region event buses 25 | EventBusName: !GetAtt SecurityEventBus.Arn 26 | EventPattern: 27 | source: 28 | - anything-but: com.company.security 29 | State: ENABLED 30 | RoleArn: !GetAtt WriteToCwlRole.Arn 31 | Targets: 32 | - Id: SendEventToSecurityAnalysisRule 33 | Arn: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${SecurityAnalysisRuleTarget}" 34 | 35 | SecurityAnalysisRuleTarget: 36 | Type: AWS::Logs::LogGroup 37 | Properties: 38 | RetentionInDays: 3 39 | LogGroupName: "/aws/events/SecurityAnalysisRule" 40 | 41 | WriteToCwlRole: 42 | Type: "AWS::IAM::Role" 43 | Properties: 44 | AssumeRolePolicyDocument: 45 | Version: 2012-10-17 46 | Statement: 47 | - Effect: Allow 48 | Principal: 49 | Service: 50 | - events.amazonaws.com 51 | Action: 52 | - "sts:AssumeRole" 53 | Path: / 54 | Policies: 55 | - PolicyName: WriteToSecurityAnalysisRule 56 | PolicyDocument: 57 | Version: 2012-10-17 58 | Statement: 59 | - Effect: Allow 60 | Action: 61 | - "logs:CreateLogGroup" 62 | - "logs:CreateLogStreams" 63 | - "logs:PutLogEvents" 64 | Resource: 65 | - !GetAtt SecurityAnalysisRuleTarget.Arn 66 | 67 | CWLogsResourcePolicy: 68 | Type: AWS::Logs::ResourcePolicy 69 | Properties: 70 | PolicyName: "EventBridgeToCWLogs" 71 | PolicyDocument: !Sub 72 | - > 73 | { 74 | "Version": "2012-10-17", 75 | "Statement": [ 76 | { 77 | "Sid": "EventBridgetoCWLogsPolicy", 78 | "Effect": "Allow", 79 | "Principal": { 80 | "Service": [ 81 | "delivery.logs.amazonaws.com", 82 | "events.amazonaws.com" 83 | ] 84 | }, 85 | "Action": [ 86 | "logs:CreateLogStream", 87 | "logs:PutLogEvents" 88 | ], 89 | "Resource": [ 90 | "${logArn}" 91 | ] 92 | } 93 | ] 94 | } 95 | - logArn: !GetAtt SecurityAnalysisRuleTarget.Arn 96 | 97 | Outputs: 98 | EventBus: 99 | Description: EventBus 100 | Value: !GetAtt SecurityEventBus.Arn 101 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/subscriptions.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | Description: Orange service app subscriptions for for multi-bus, multi-account-pattern 4 | 5 | Parameters: 6 | 7 | OrangeServiceEventBusArn: 8 | Description: Arn of the orange service app event bus 9 | Type: String 10 | 11 | OrangeServiceEventBusDlqUrl: 12 | Description: URL of the blue service Dead Letter Queue 13 | Type: String 14 | 15 | OrangeServiceEventBusDlqArn: 16 | Description: ARN of the orange service Dead Letter Queue 17 | Type: String 18 | 19 | PurpleServiceEventBusArn: 20 | Description: ARN of the Purple service event bus to add rules 21 | Type: String 22 | 23 | 24 | Resources: 25 | 26 | # Rule that is placed on the Orange event bus for Event 2 27 | OrangeServiceE2SubscriptionRule: 28 | Type: AWS::Events::Rule 29 | Properties: 30 | Name: OrangeE2Subscription 31 | Description: Cross account rule created by Orange service for event 2 32 | EventBusName: !Ref PurpleServiceEventBusArn # ARN of the purple event bus 33 | EventPattern: 34 | source: 35 | - com.exampleCorp.PurpleService 36 | detail-type: 37 | - Event2 38 | State: ENABLED 39 | Targets: 40 | - Id: SendEvent2ToOrangeServiceEventBus 41 | Arn: !Ref OrangeServiceEventBusArn 42 | RoleArn: !GetAtt ServiceEventBusToOrangeEventBusRole.Arn 43 | DeadLetterConfig: 44 | Arn: !Ref OrangeServiceEventBusDlqArn 45 | 46 | # This IAM role allows EventBridge to assume the permissions necessary to send events 47 | # from the Purple event bus to the Orange service event bus. No resource policy is required 48 | # on the Orange service event bus. 49 | ServiceEventBusToOrangeEventBusRole: 50 | Type: 'AWS::IAM::Role' 51 | Properties: 52 | AssumeRolePolicyDocument: 53 | Version: 2012-10-17 54 | Statement: 55 | - Effect: Allow 56 | Principal: 57 | Service: 58 | - events.amazonaws.com 59 | Action: 60 | - 'sts:AssumeRole' 61 | Path: / 62 | Policies: 63 | - PolicyName: PutEventsOnOrangeServiceEventBus 64 | PolicyDocument: 65 | Version: 2012-10-17 66 | Statement: 67 | - Effect: Allow 68 | Action: 'events:PutEvents' 69 | Resource: !Ref OrangeServiceEventBusArn 70 | 71 | 72 | # SQS resource policy required to allow targets on service buses to send failed messages to target DLQ 73 | OrangeServiceEventBusDlqPolicy: 74 | Type: AWS::SQS::QueuePolicy 75 | Properties: 76 | Queues: 77 | - !Ref OrangeServiceEventBusDlqUrl 78 | PolicyDocument: 79 | Statement: 80 | - Action: 81 | - "SQS:SendMessage" 82 | Effect: "Allow" 83 | Resource: !Ref OrangeServiceEventBusDlqArn 84 | Principal: 85 | Service: "events.amazonaws.com" 86 | Condition: 87 | ArnEquals: 88 | "aws:SourceArn": !GetAtt OrangeServiceE2SubscriptionRule.Arn 89 | 90 | Outputs: 91 | OrangE2Subscription: 92 | Description: Rule ARN for blue service event 2 subscription 93 | Value: !GetAtt OrangeServiceE2SubscriptionRule.Arn -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/subscriptions.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | Description: Blue service app subscriptions for for multi-bus, multi-account-pattern 4 | 5 | Parameters: 6 | BlueServiceEventBusArn: 7 | Description: Name of the blue service app event bus 8 | Type: String 9 | Default: blue-service-event-bus-multi-bus 10 | 11 | BlueServiceEventBusDlqUrl: 12 | Description: URL of the blue service Dead Letter Queue 13 | Type: String 14 | 15 | BlueServiceEventBusDlqArn: 16 | Description: ARN of the blue service Dead Letter Queue 17 | Type: String 18 | 19 | PurpleServiceEventBusArn: 20 | Description: ARN of the Purple service event bus to add rules 21 | Type: String 22 | 23 | Resources: 24 | # Rule that is placed on the Purple event bus for Event 2 25 | BlueServiceE2SubscriptionRule: 26 | Type: AWS::Events::Rule 27 | Properties: 28 | Name: BlueE2Subscription 29 | Description: Cross account rule created by Blue service for event 2 30 | EventBusName: !Ref PurpleServiceEventBusArn # ARN of the Purple service event bus 31 | EventPattern: 32 | source: 33 | - com.exampleCorp.PurpleService 34 | detail-type: 35 | - Event2 36 | State: ENABLED 37 | Targets: 38 | - Id: SendEvent2ToBlueServiceEventBus 39 | Arn: !Ref BlueServiceEventBusArn 40 | RoleArn: !GetAtt PurpleServiceEventBusToBlueServiceEventBusRole.Arn 41 | DeadLetterConfig: 42 | Arn: !Ref BlueServiceEventBusDlqArn 43 | 44 | # This IAM role allows EventBridge to assume the permissions necessary to send events 45 | # from the Purple event bus to the Blue service event bus. No resource policy is required 46 | # on the Blue service event bus. 47 | PurpleServiceEventBusToBlueServiceEventBusRole: 48 | Type: 'AWS::IAM::Role' 49 | Properties: 50 | AssumeRolePolicyDocument: 51 | Version: 2012-10-17 52 | Statement: 53 | - Effect: Allow 54 | Principal: 55 | Service: 56 | - events.amazonaws.com 57 | Action: 58 | - 'sts:AssumeRole' 59 | Path: / 60 | Policies: 61 | - PolicyName: PutEventsOnBlueServiceEventBus 62 | PolicyDocument: 63 | Version: 2012-10-17 64 | Statement: 65 | - Effect: Allow 66 | Action: 'events:PutEvents' 67 | Resource: !Ref BlueServiceEventBusArn 68 | 69 | # SQS resource policy required to allow target on devops bus to send failed messages to target DLQ 70 | BlueServiceEventBusDlqPolicy: 71 | Type: AWS::SQS::QueuePolicy 72 | Properties: 73 | Queues: 74 | - !Ref BlueServiceEventBusDlqUrl 75 | PolicyDocument: 76 | Statement: 77 | - Action: 78 | - "SQS:SendMessage" 79 | Effect: "Allow" 80 | Resource: !Ref BlueServiceEventBusDlqArn 81 | Principal: 82 | Service: "events.amazonaws.com" 83 | Condition: 84 | ArnEquals: 85 | "aws:SourceArn": !GetAtt BlueServiceE2SubscriptionRule.Arn 86 | 87 | Outputs: 88 | BlueE2Subscription: 89 | Description: Rule ARN for blue service event 2 subscription 90 | Value: !GetAtt BlueServiceE2SubscriptionRule.Arn -------------------------------------------------------------------------------- /patterns/README.md: -------------------------------------------------------------------------------- 1 | # Multi-account design patterns with Amazon EventBridge 2 | 3 | > For more information regarding these patterns see AWS re:Invent 2020 session [Building event-driven applications with Amazon EventBridge](https://virtual.awsevents.com/media/t/1_ynykxz80/186983983) which is available on demand. 4 | 5 | In this section, there are two sample applications that implement the patterns for single-bus and multi-bus topologies across multiple accounts. 6 | 7 | In both cases we are illustrating 3 service teams creating a blue, purple and orange microservice. I’ve named them after colors to keep them as agnostic as possible and allow you to substitute your own names for your own particular use cases. The important thing to remember is that they each represent a unique service boundary that is using EventBridge to publish and subscribe to events from other services. 8 | 9 | Each service has its own own autonomous development team not dissimilar to AWS’ two pizza team concept. 10 | 11 | The Purple service subscribe to Event 1 (E1) from the Blue service and Event 3 (E3) from the Orange Service, and both the Blue and Orange services subscribing to Event 2 (E2), which is published by the Purple service. 12 | 13 | ## Single-bus, multi-account account pattern 14 | 15 | When you use Amazon EventBridge with multiple accounts, event buses need to be created in the account receiving events. At this point in time, EventBridge does not allow you to directly invoke services (such as AWS Lambda) in other accounts. This bus-to-bus communication is what facilitates the transfer of events between account boundaries. 16 | 17 | It is very typical for organizations to have a "DevOps" team that is responsible for managing a shared resource via a single event bus. Each service team owns and manages its own application stack, while the DevOps team manages the stack that defines event bus rules and target configurations for the services integrations. 18 | 19 | ![Single-bus, multi-account](../docs/images/single-bus-multi-account.png "Single-bus, multi-account") 20 | 21 | **Walkthrough the [Single-bus, multi-account account pattern](single-bus-multi-account-pattern/README.md) >>** 22 | 23 | ## Multi-bus, multi-account account pattern 24 | 25 | In this pattern, each of the event buses are owned by the service teams. Each of the service teams manages their own buses. There is no centralized management of routing logic or target configuration. 26 | 27 | Service teams need to be aware of the services that are interested in subscribing to events they are publishing. Each event bus sets it's own EventBusPolicy to scope what event sources can publish to the bus, and create EventBusPolicies defining which accounts can manage rules and targets on their account. 28 | 29 | ![Multi-bus, multi-account](../docs/images/multi-bus-multi-account.png "Multi-bus, multi-account") 30 | 31 | **Walkthrough the [Multi-bus, multi-account account pattern](multi-bus-multi-account-pattern/README.md) >>** 32 | 33 | ## Cross-region event routing with Amazon EventBridge 34 | 35 | In this scenario, a company has their base of operations located in Asia Pacific (Singapore) with applications distributed across two additional Regions in US East (N. Virginia) and Europe (Frankfurt). The applications in US East (N. Virginia) and Europe (Frankfurt) are using Amazon EventBridge for their respective applications and services. The security team in Asia Pacific (Singapore) wishes to analyse events from the respective applications as well as receive AWS CloudTrail events for specific API calls made to specific operations to monitor infrastructure security. 36 | 37 | **Walkthrough the [Cross-region, cross-account pattern](cross-region-cross-account-pattern/README.md) >>** 38 | 39 | ![Cross-Region](../docs/images/cross-region.png "Cross-Region") 40 | -------------------------------------------------------------------------------- /patterns/cross-region-cross-account-pattern/security/account_1/us-east-1-rules.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: 2010-09-09 3 | 4 | Parameters: 5 | SecurityEventBusArn: 6 | Description: ARN of the Security event bus. This is the target for security rules in this region. 7 | Type: String 8 | 9 | EventBusArnAccount1: 10 | Description: ARN of the default event bus in Account 1 11 | Type: String 12 | 13 | EventBusArnAccount2: 14 | Description: ARN of the custom event bus in Account 2 15 | Type: String 16 | 17 | Resources: 18 | 19 | # This IAM role allows EventBridge to assume the permissions necessary to send events 20 | # from the source event buses to the destination event bus. 21 | SourceToDestinationEventBusRole: 22 | Type: "AWS::IAM::Role" 23 | Properties: 24 | AssumeRolePolicyDocument: 25 | Version: 2012-10-17 26 | Statement: 27 | - Effect: Allow 28 | Principal: 29 | Service: 30 | - events.amazonaws.com 31 | Action: 32 | - "sts:AssumeRole" 33 | Path: / 34 | Policies: 35 | - PolicyName: PutEventsOnDestinationEventBus 36 | PolicyDocument: 37 | Version: 2012-10-17 38 | Statement: 39 | - Effect: Allow 40 | Action: "events:PutEvents" 41 | Resource: 42 | - !Ref SecurityEventBusArn 43 | 44 | SecurityAuditRule1: 45 | Type: AWS::Events::Rule 46 | Properties: 47 | Name: SecurityAuditRuleAccount1 48 | Description: Audit rule for the Security team in Singapore 49 | EventBusName: !Ref EventBusArnAccount1 # ARN of the default event bus in Account 1 50 | EventPattern: 51 | source: 52 | - aws.cloudtrail 53 | detail-type: 54 | - AWS API Call via CloudTrail 55 | detail: 56 | eventSource: 57 | - cloudtrail.amazonaws.com 58 | eventName: 59 | - ConsoleLogin 60 | - StopLogging 61 | - CreateNetworkAclEntry 62 | - CreateRoute 63 | - AuthorizeSecurityGroupEgress 64 | - AuthorizeSecurityGroupIngress 65 | - RevokeSecurityGroupEgress 66 | - RevokeSecurityGroupIngresss 67 | - ApplySecurityGroupsToLoadBalancer 68 | - SetSecurityGroups 69 | - AuthorizeDBSecurityGroupIngress 70 | - CreateDBSecurityGroup 71 | - DeleteDBSecurityGroup 72 | - RevokeDBSecurityGroupIngress 73 | State: ENABLED 74 | Targets: 75 | - Id: SendEventToSecurityEventBusArn 76 | Arn: !Ref SecurityEventBusArn 77 | RoleArn: !GetAtt SourceToDestinationEventBusRole.Arn 78 | 79 | SecurityAuditRule2: 80 | Type: AWS::Events::Rule 81 | Properties: 82 | Name: SecurityAuditRuleAccount2 83 | Description: Audit rule for the Security team in Singapore 84 | EventBusName: !Ref EventBusArnAccount2 # ARN of the custom event bus in Account 2 85 | EventPattern: 86 | source: 87 | - com.company.marketing 88 | State: ENABLED 89 | Targets: 90 | - Id: SendEventToSecurityEventBusArn 91 | Arn: !Ref SecurityEventBusArn 92 | RoleArn: !GetAtt SourceToDestinationEventBusRole.Arn 93 | 94 | Outputs: 95 | SourceToDestinationEventBusRole: 96 | Description: ARN of the role that allows EventBridge to assume permissions to send events to another event bus 97 | Value: !GetAtt SourceToDestinationEventBusRole.Arn 98 | 99 | SecurityAuditRule1Arn: 100 | Description: ARN of the security audit rule 1 101 | Value: !GetAtt SecurityAuditRule1.Arn 102 | 103 | SecurityAuditRule2Arn: 104 | Description: ARN of the security audit rule 2 105 | Value: !GetAtt SecurityAuditRule2.Arn -------------------------------------------------------------------------------- /blog/account-a-web-store/README.md: -------------------------------------------------------------------------------- 1 | # Deploy the web store function to account A 2 | 3 | This template creates the AWS Lambda function for the web store in account A. Make [sure you have deployed the Central event bus before deploying this application](../account-b-central-bus/README.md), as you will need Amazon Resource Name (ARN) for the event bus as an input parameter for this application stack. 4 | 5 | ![Walkthrough architecture](../../docs/images/account-a.png "Walkthrough architecture") 6 | 7 | For more details on the implementation visit the accompanying AWS blog post ["Simplifying cross-account access with Amazon EventBridge resource policies"](https://aws.amazon.com/blogs/compute/simplifying-cross-account-access-with-amazon-eventbridge-resource-policies) 8 | 9 | 10 | ## Deploy the application 11 | 12 | The Serverless Application Model Command Line Interface (AWS SAM CLI) is an extension of the AWS CLI that adds functionality for building and testing Lambda applications. It uses Docker to run your functions in an Amazon Linux environment that matches Lambda. It can also emulate your application's build environment and API. 13 | 14 | To use the SAM CLI, you need the following tools. 15 | 16 | * AWS SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) 17 | * [Python 3 installed](https://www.python.org/downloads/) 18 | * Docker - [Install Docker community edition](https://hub.docker.com/search/?type=edition&offering=community) 19 | 20 | To build and deploy your application for the first time, run the following in your shell: 21 | 22 | ```bash 23 | sam build --use-container 24 | sam deploy --guided 25 | ``` 26 | 27 | The first command will build the source of your application. The second command will package and deploy your application to AWS, with a series of prompts: 28 | 29 | * **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name. 30 | * **AWS Region**: The AWS region you want to deploy your app to. 31 | * **Parameters**: The values of parameters in your template. 32 | * **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes. 33 | * **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modified IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command. 34 | * **Save arguments to samconfig.toml**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application. 35 | 36 | The template takes one parameters: 37 | 38 | * **`CentralEventBusArn`**: the ARN of the central event bus in account B 39 | 40 | ## Cleanup 41 | 42 | To delete the sample application that you created, use the AWS CLI. Assuming you used your project name for the stack name, you can run the following: 43 | 44 | ```bash 45 | aws cloudformation delete-stack --stack-name web-store 46 | ``` 47 | 48 | ## Resources 49 | 50 | See the [AWS SAM developer guide](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) for an introduction to AWS SAM specification, the AWS SAM CLI, and serverless application concepts. 51 | 52 | Next, you can use AWS Serverless Application Repository to deploy ready to use Apps that go beyond hello world samples and learn how authors developed their applications: [AWS Serverless Application Repository main page](https://aws.amazon.com/serverless/serverlessrepo/) 53 | -------------------------------------------------------------------------------- /blog/account-c-invoice-processing/README.md: -------------------------------------------------------------------------------- 1 | # Deploy the invoice processing function to account C 2 | 3 | This template creates the AWS Lambda function for the web store in account A. Make [sure you have deployed the Central event bus before deploying this application](../account-b-central-bus/README.md), as you will need Amazon Resource Name (ARN) for the event bus as an input parameter for this application stack. 4 | 5 | ![Walkthrough architecture](../../docs/images/account-c.png "Walkthrough architecture") 6 | 7 | For more details on the implementation visit the accompanying AWS blog post ["Simplifying cross-account access with Amazon EventBridge resource policies"](https://aws.amazon.com/blogs/compute/simplifying-cross-account-access-with-amazon-eventbridge-resource-policies) 8 | 9 | ## Deploy the application 10 | 11 | The Serverless Application Model Command Line Interface (AWS SAM CLI) is an extension of the AWS CLI that adds functionality for building and testing Lambda applications. It uses Docker to run your functions in an Amazon Linux environment that matches Lambda. It can also emulate your application's build environment and API. 12 | 13 | To use the SAM CLI, you need the following tools. 14 | 15 | * SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) 16 | * [Python 3 installed](https://www.python.org/downloads/) 17 | * Docker - [Install Docker community edition](https://hub.docker.com/search/?type=edition&offering=community) 18 | 19 | To build and deploy your application for the first time, run the following in your shell: 20 | 21 | ```bash 22 | sam build --use-container 23 | sam deploy --guided 24 | ``` 25 | 26 | The first command will build the source of your application. The second command will package and deploy your application to AWS, with a series of prompts: 27 | 28 | * **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name. 29 | * **AWS Region**: The AWS region you want to deploy your app to. 30 | * **Parameters**: The values of parameters in your template. 31 | * **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes. 32 | * **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modified IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command. 33 | * **Save arguments to samconfig.toml**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application. 34 | 35 | The template takes two parameters: 36 | 37 | * **EventBusName:** Name of the invoice processing event bus in account C 38 | * **CentralEventBusArn:** the ARN of the central event bus 39 | 40 | ## Cleanup 41 | 42 | To delete the sample application that you created, use the AWS CLI. Assuming you used your project name for the stack name, you can run the following: 43 | 44 | ```bash 45 | aws cloudformation delete-stack --stack-name web-store 46 | ``` 47 | 48 | ## Resources 49 | 50 | See the [AWS SAM developer guide](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) for an introduction to SAM specification, the SAM CLI, and serverless application concepts. 51 | 52 | Next, you can use AWS Serverless Application Repository to deploy ready to use Apps that go beyond hello world samples and learn how authors developed their applications: [AWS Serverless Application Repository main page](https://aws.amazon.com/serverless/serverlessrepo/) 53 | -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: > 4 | Blue service app for for multi-bus, multi-account-pattern 5 | 6 | Globals: 7 | Function: 8 | Timeout: 3 9 | Handler: app.lambda_handler 10 | Runtime: python3.12 11 | Tags: 12 | pattern: multi-bus-multi-account-pattern 13 | 14 | Parameters: 15 | EventBusName: 16 | Description: Name of the blue service app event bus 17 | Type: String 18 | Default: blue-service-event-bus-multi-bus 19 | 20 | PurpleServiceAccountNo: 21 | Description: Account Id Purple service event bus to add rules 22 | Type: String 23 | 24 | OrangeServiceAccountNo: 25 | Description: Account Id Orange service event bus to add rules 26 | Type: String 27 | 28 | Resources: 29 | # Event bus for blue service 30 | BlueServiceEventBus: 31 | Type: AWS::Events::EventBus 32 | Properties: 33 | Name: !Ref EventBusName 34 | 35 | # Resource policy for Blue service event bus 36 | BlueServicePublishStatement: 37 | Type: AWS::Events::EventBusPolicy 38 | Properties: 39 | EventBusName: !Ref BlueServiceEventBus 40 | StatementId: "BlueServicePublish" 41 | Statement: 42 | Effect: "Allow" 43 | Principal: 44 | AWS: 45 | - !Sub arn:aws:iam::${AWS::AccountId}:root 46 | Action: "events:PutEvents" 47 | Resource: !GetAtt BlueServiceEventBus.Arn 48 | Condition: 49 | StringEquals: 50 | "events:source": ["com.exampleCorp.BlueService"] 51 | 52 | BlueEventBusRuleCreationStatement: 53 | Type: AWS::Events::EventBusPolicy 54 | Properties: 55 | EventBusName: !Ref BlueServiceEventBus 56 | StatementId: "AllServiceRuleCreation" 57 | Statement: 58 | Effect: "Allow" 59 | Principal: 60 | AWS: 61 | - !Sub arn:aws:iam::${PurpleServiceAccountNo}:root 62 | - !Sub arn:aws:iam::${OrangeServiceAccountNo}:root 63 | Action: 64 | - "events:PutRule" 65 | - "events:DeleteRule" 66 | - "events:DescribeRule" 67 | - "events:DisableRule" 68 | - "events:EnableRule" 69 | - "events:PutTargets" 70 | - "events:RemoveTargets" 71 | Resource: 72 | - !Sub arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/${BlueServiceEventBus.Name}/* 73 | Condition: 74 | StringEqualsIfExists: 75 | "events:creatorAccount": "${aws:PrincipalAccount}" 76 | "events:source": ["com.exampleCorp.BlueService"] 77 | 78 | BlueServicePublisherE1: 79 | Type: AWS::Serverless::Function 80 | Properties: 81 | CodeUri: blue_p_e1/ 82 | Policies: 83 | - Version: '2012-10-17' 84 | Statement: 85 | - Effect: Allow 86 | Action: 87 | - events:PutEvents 88 | Resource: !GetAtt BlueServiceEventBus.Arn 89 | Environment: 90 | Variables: 91 | EVENT_BUS_ARN: !Ref BlueServiceEventBus 92 | 93 | BlueServiceSubscriberE2: 94 | Type: AWS::Serverless::Function 95 | Properties: 96 | CodeUri: blue_s_e2/ 97 | Events: 98 | BlueE2Rule: 99 | Type: EventBridgeRule 100 | Properties: 101 | EventBusName: !Ref BlueServiceEventBus 102 | Pattern: 103 | source: 104 | - com.exampleCorp.PurpleService 105 | detail-type: 106 | - Event2 107 | 108 | # Blue service event bus targe DLQ 109 | BlueServiceEventBusDlq: 110 | Type: AWS::SQS::Queue 111 | 112 | Outputs: 113 | BlueServiceEventBusArn: 114 | Description: The ARN of the Purple event bus 115 | Value: !GetAtt BlueServiceEventBus.Arn 116 | BlueServicePublisherE1: 117 | Description: Lambda function ARN for blue service publishing event 1 118 | Value: !Ref BlueServicePublisherE1 119 | BlueServiceSubscriberE2: 120 | Description: Lambda function name for purple service subscriber to event 2 121 | Value: !Ref BlueServiceSubscriberE2 122 | BlueServiceEventBusDlqUrl: 123 | Description: URL of the SQS Queue for rules DeadLetterConfig 124 | Value: !Ref BlueServiceEventBusDlq 125 | BlueServiceEventBusDlqArn: 126 | Description: ARN of the SQS Queue for rules DeadLetterConfig 127 | Value: !GetAtt BlueServiceEventBusDlq.Arn -------------------------------------------------------------------------------- /blog/account-c-invoice-processing/invoice_processing/schema/com_examplecorp_webstore/newordercreated/NewOrderCreatedItem.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | # coding: utf-8 15 | import pprint 16 | import re # noqa: F401 17 | 18 | import six 19 | from enum import Enum 20 | 21 | class NewOrderCreatedItem(object): 22 | 23 | 24 | _types = { 25 | 'currency': 'str', 26 | 'productCode': 'str', 27 | 'quantityOrdered': 'float', 28 | 'unitPrice': 'float' 29 | } 30 | 31 | _attribute_map = { 32 | 'currency': 'currency', 33 | 'productCode': 'productCode', 34 | 'quantityOrdered': 'quantityOrdered', 35 | 'unitPrice': 'unitPrice' 36 | } 37 | 38 | def __init__(self, currency=None, productCode=None, quantityOrdered=None, unitPrice=None): # noqa: E501 39 | self._currency = None 40 | self._productCode = None 41 | self._quantityOrdered = None 42 | self._unitPrice = None 43 | self.discriminator = None 44 | self.currency = currency 45 | self.productCode = productCode 46 | self.quantityOrdered = quantityOrdered 47 | self.unitPrice = unitPrice 48 | 49 | 50 | @property 51 | def currency(self): 52 | 53 | return self._currency 54 | 55 | @currency.setter 56 | def currency(self, currency): 57 | 58 | 59 | self._currency = currency 60 | 61 | 62 | @property 63 | def productCode(self): 64 | 65 | return self._productCode 66 | 67 | @productCode.setter 68 | def productCode(self, productCode): 69 | 70 | 71 | self._productCode = productCode 72 | 73 | 74 | @property 75 | def quantityOrdered(self): 76 | 77 | return self._quantityOrdered 78 | 79 | @quantityOrdered.setter 80 | def quantityOrdered(self, quantityOrdered): 81 | 82 | 83 | self._quantityOrdered = quantityOrdered 84 | 85 | 86 | @property 87 | def unitPrice(self): 88 | 89 | return self._unitPrice 90 | 91 | @unitPrice.setter 92 | def unitPrice(self, unitPrice): 93 | 94 | 95 | self._unitPrice = unitPrice 96 | 97 | def to_dict(self): 98 | result = {} 99 | 100 | for attr, _ in six.iteritems(self._types): 101 | value = getattr(self, attr) 102 | if isinstance(value, list): 103 | result[attr] = list(map( 104 | lambda x: x.to_dict() if hasattr(x, "to_dict") else x, 105 | value 106 | )) 107 | elif hasattr(value, "to_dict"): 108 | result[attr] = value.to_dict() 109 | elif isinstance(value, dict): 110 | result[attr] = dict(map( 111 | lambda item: (item[0], item[1].to_dict()) 112 | if hasattr(item[1], "to_dict") else item, 113 | value.items() 114 | )) 115 | else: 116 | result[attr] = value 117 | if issubclass(NewOrderCreatedItem, dict): 118 | for key, value in self.items(): 119 | result[key] = value 120 | 121 | return result 122 | 123 | def to_str(self): 124 | return pprint.pformat(self.to_dict()) 125 | 126 | def __repr__(self): 127 | return self.to_str() 128 | 129 | def __eq__(self, other): 130 | if not isinstance(other, NewOrderCreatedItem): 131 | return False 132 | 133 | return self.__dict__ == other.__dict__ 134 | 135 | def __ne__(self, other): 136 | return not self == other 137 | 138 | -------------------------------------------------------------------------------- /blog/account-c-invoice-processing/invoice_processing/schema/com_examplecorp_webstore/newordercreated/NewOrderCreated.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 8 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 9 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 10 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 11 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 12 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | # coding: utf-8 15 | import pprint 16 | import re # noqa: F401 17 | 18 | import six 19 | from enum import Enum 20 | from schema.com_examplecorp_webstore.newordercreated.NewOrderCreatedItem import NewOrderCreatedItem # noqa: F401,E501 21 | 22 | class NewOrderCreated(object): 23 | 24 | 25 | _types = { 26 | 'customerId': 'str', 27 | 'lineItems': 'list[NewOrderCreatedItem]', 28 | 'orderDate': 'datetime', 29 | 'orderNo': 'str' 30 | } 31 | 32 | _attribute_map = { 33 | 'customerId': 'customerId', 34 | 'lineItems': 'lineItems', 35 | 'orderDate': 'orderDate', 36 | 'orderNo': 'orderNo' 37 | } 38 | 39 | def __init__(self, customerId=None, lineItems=None, orderDate=None, orderNo=None): # noqa: E501 40 | self._customerId = None 41 | self._lineItems = None 42 | self._orderDate = None 43 | self._orderNo = None 44 | self.discriminator = None 45 | self.customerId = customerId 46 | self.lineItems = lineItems 47 | self.orderDate = orderDate 48 | self.orderNo = orderNo 49 | 50 | 51 | @property 52 | def customerId(self): 53 | 54 | return self._customerId 55 | 56 | @customerId.setter 57 | def customerId(self, customerId): 58 | 59 | 60 | self._customerId = customerId 61 | 62 | 63 | @property 64 | def lineItems(self): 65 | 66 | return self._lineItems 67 | 68 | @lineItems.setter 69 | def lineItems(self, lineItems): 70 | 71 | 72 | self._lineItems = lineItems 73 | 74 | 75 | @property 76 | def orderDate(self): 77 | 78 | return self._orderDate 79 | 80 | @orderDate.setter 81 | def orderDate(self, orderDate): 82 | 83 | 84 | self._orderDate = orderDate 85 | 86 | 87 | @property 88 | def orderNo(self): 89 | 90 | return self._orderNo 91 | 92 | @orderNo.setter 93 | def orderNo(self, orderNo): 94 | 95 | 96 | self._orderNo = orderNo 97 | 98 | def to_dict(self): 99 | result = {} 100 | 101 | for attr, _ in six.iteritems(self._types): 102 | value = getattr(self, attr) 103 | if isinstance(value, list): 104 | result[attr] = list(map( 105 | lambda x: x.to_dict() if hasattr(x, "to_dict") else x, 106 | value 107 | )) 108 | elif hasattr(value, "to_dict"): 109 | result[attr] = value.to_dict() 110 | elif isinstance(value, dict): 111 | result[attr] = dict(map( 112 | lambda item: (item[0], item[1].to_dict()) 113 | if hasattr(item[1], "to_dict") else item, 114 | value.items() 115 | )) 116 | else: 117 | result[attr] = value 118 | if issubclass(NewOrderCreated, dict): 119 | for key, value in self.items(): 120 | result[key] = value 121 | 122 | return result 123 | 124 | def to_str(self): 125 | return pprint.pformat(self.to_dict()) 126 | 127 | def __repr__(self): 128 | return self.to_str() 129 | 130 | def __eq__(self, other): 131 | if not isinstance(other, NewOrderCreated): 132 | return False 133 | 134 | return self.__dict__ == other.__dict__ 135 | 136 | def __ne__(self, other): 137 | return not self == other 138 | 139 | -------------------------------------------------------------------------------- /blog/account-c-invoice-processing/template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: > 4 | Account C - Invoice processing service stack 5 | 6 | Parameters: 7 | EventBusName: 8 | Description: Name of the invoice processing event bus 9 | Type: String 10 | Default: invoice-processing-event-bus 11 | 12 | CentralEventBusArn: 13 | Description: The ARN of the central event bus # e.g. arn:aws:events:us-east-1:[ACCOUNT-B]:event-bus/central-event-bus 14 | Type: String 15 | 16 | Resources: 17 | 18 | # This is the receiving invoice processing event bus in account C. 19 | InvoiceProcessingEventBus: 20 | Type: AWS::Events::EventBus 21 | Properties: 22 | Name: !Ref EventBusName 23 | 24 | # AWS Lambda function processes the newOrderCreated event 25 | InvoiceProcessingFunction: 26 | Type: AWS::Serverless::Function 27 | Properties: 28 | CodeUri: invoice_processing 29 | Handler: invoice_processing_function/app.lambda_handler 30 | Runtime: python3.12 31 | Events: 32 | NewOrderCreatedRule: 33 | Type: EventBridgeRule 34 | Properties: 35 | EventBusName: !Ref InvoiceProcessingEventBus 36 | Pattern: 37 | source: 38 | - com.exampleCorp.webStore 39 | detail-type: 40 | - newOrderCreated 41 | 42 | # This is the rule that the invoice processing service creates on the central event bus 43 | InvoiceProcessingRule: 44 | Type: AWS::Events::Rule 45 | Properties: 46 | Name: InvoiceProcessingNewOrderCreatedSubscription 47 | Description: Cross account rule created by Invoice Processing service 48 | EventBusName: !Ref CentralEventBusArn # ARN of the central event bus 49 | EventPattern: 50 | source: 51 | - com.exampleCorp.webStore 52 | detail-type: 53 | - newOrderCreated 54 | State: ENABLED 55 | Targets: 56 | - Id: SendEventsToInvoiceProcessingEventBus 57 | Arn: !GetAtt InvoiceProcessingEventBus.Arn 58 | RoleArn: !GetAtt CentralEventBusToInvoiceProcessingEventBusRole.Arn 59 | DeadLetterConfig: 60 | Arn: !GetAtt InvoiceProcessingTargetDLQ.Arn 61 | 62 | # This IAM role allows EventBridge to assume the permissions necessary to send events to the 63 | # Invoice Processing event bus, without you having to create an additional resource policy 64 | # on the Invoice Processing event bus. 65 | CentralEventBusToInvoiceProcessingEventBusRole: 66 | Type: 'AWS::IAM::Role' 67 | Properties: 68 | AssumeRolePolicyDocument: 69 | Version: 2012-10-17 70 | Statement: 71 | - Effect: Allow 72 | Principal: 73 | Service: 74 | - events.amazonaws.com 75 | Action: 76 | - 'sts:AssumeRole' 77 | Path: / 78 | Policies: 79 | - PolicyName: PutEventsOnInvoiceProcessingEventBus 80 | PolicyDocument: 81 | Version: 2012-10-17 82 | Statement: 83 | - Effect: Allow 84 | Action: 'events:PutEvents' 85 | Resource: !GetAtt InvoiceProcessingEventBus.Arn 86 | 87 | 88 | # Invoice Processing Target Dead Letter Queue 89 | InvoiceProcessingTargetDLQ: 90 | Type: AWS::SQS::Queue 91 | 92 | # SQS resource policy required to allow target on central bus to send failed messages to target DLQ 93 | InvoiceProcessingTargetDLQPolicy: 94 | Type: AWS::SQS::QueuePolicy 95 | Properties: 96 | Queues: 97 | - !Ref InvoiceProcessingTargetDLQ 98 | PolicyDocument: 99 | Statement: 100 | - Action: 101 | - "SQS:SendMessage" 102 | Effect: "Allow" 103 | Resource: !GetAtt InvoiceProcessingTargetDLQ.Arn 104 | Principal: 105 | Service: "events.amazonaws.com" 106 | Condition: 107 | ArnEquals: 108 | "aws:SourceArn": !GetAtt InvoiceProcessingRule.Arn 109 | 110 | Outputs: 111 | InvoiceProcessingFunction: 112 | Description: "Invoice Processing Lambda Function ARN" 113 | Value: !GetAtt InvoiceProcessingFunction.Arn 114 | InvoiceProcessingFunctionIamRole: 115 | Description: "Implicit IAM Role created for Invoice Processing function" 116 | Value: !GetAtt InvoiceProcessingFunctionRole.Arn 117 | InvoiceProcessingTargetDLQArn: 118 | Description: Arn of the DLQ for Invoice Processing TargetDLQ 119 | Value: !GetAtt InvoiceProcessingTargetDLQ.Arn -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/devops-account/template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: "2010-09-09" 2 | Description: > 3 | DevOps event bus stack for single bus, multi-account-pattern 4 | 5 | Parameters: 6 | EventBusName: 7 | Description: Name of the DevOps event bus 8 | Type: String 9 | Default: devops-event-bus 10 | BlueServiceAccountNo: 11 | Description: Account number for blue service 12 | Type: String 13 | AllowedPattern: ^\d{12}$ 14 | PurpleServiceAccountNo: 15 | Description: Account number for purple service 16 | Type: String 17 | AllowedPattern: ^\d{12}$ 18 | OrangeServiceAccountNo: 19 | Description: Account number for orange service 20 | Type: String 21 | AllowedPattern: ^\d{12}$ 22 | 23 | Resources: 24 | DevOpsEventBus: 25 | Type: AWS::Events::EventBus 26 | Properties: 27 | Name: !Ref EventBusName 28 | 29 | CrossAccountPublishStatement: 30 | Type: AWS::Events::EventBusPolicy 31 | Properties: 32 | EventBusName: !Ref DevOpsEventBus 33 | StatementId: "CrossAccountPublish" 34 | Statement: 35 | Effect: "Allow" 36 | Principal: 37 | AWS: 38 | - !Sub arn:aws:iam::${BlueServiceAccountNo}:root 39 | - !Sub arn:aws:iam::${PurpleServiceAccountNo}:root 40 | - !Sub arn:aws:iam::${OrangeServiceAccountNo}:root 41 | Action: "events:PutEvents" 42 | Resource: !GetAtt DevOpsEventBus.Arn 43 | Condition: 44 | StringEquals: 45 | "events:source": ["com.exampleCorp.BlueService", "com.exampleCorp.PurpleService", "com.exampleCorp.OrangeService"] 46 | 47 | BlueServiceRuleCreationStatement: 48 | Type: AWS::Events::EventBusPolicy 49 | Properties: 50 | EventBusName: !Ref DevOpsEventBus 51 | StatementId: "BlueServiceRuleCreation" 52 | Statement: 53 | Effect: "Allow" 54 | Principal: 55 | AWS: !Sub arn:aws:iam::${BlueServiceAccountNo}:root 56 | Action: 57 | - "events:PutRule" 58 | - "events:DeleteRule" 59 | - "events:DescribeRule" 60 | - "events:DisableRule" 61 | - "events:EnableRule" 62 | - "events:PutTargets" 63 | - "events:RemoveTargets" 64 | Resource: 65 | - !Sub arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/${DevOpsEventBus.Name}/* 66 | Condition: 67 | StringEqualsIfExists: 68 | "events:creatorAccount": "${aws:PrincipalAccount}" 69 | "events:source": "com.exampleCorp.PurpleService" 70 | 71 | PurpleServiceRuleCreationStatement: 72 | Type: AWS::Events::EventBusPolicy 73 | Properties: 74 | EventBusName: !Ref DevOpsEventBus 75 | StatementId: "PurpleServiceRuleCreation" 76 | Statement: 77 | Effect: "Allow" 78 | Principal: 79 | AWS: !Sub arn:aws:iam::${PurpleServiceAccountNo}:root 80 | Action: 81 | - "events:PutRule" 82 | - "events:DeleteRule" 83 | - "events:DescribeRule" 84 | - "events:DisableRule" 85 | - "events:EnableRule" 86 | - "events:PutTargets" 87 | - "events:RemoveTargets" 88 | Resource: 89 | - !Sub arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/${DevOpsEventBus.Name}/* 90 | Condition: 91 | StringEqualsIfExists: 92 | "events:creatorAccount": "${aws:PrincipalAccount}" 93 | "events:source": [ "com.exampleCorp.BlueService", "com.exampleCorp.OrangeService" ] 94 | 95 | OrangeServiceRuleCreationStatement: 96 | Type: AWS::Events::EventBusPolicy 97 | Properties: 98 | EventBusName: !Ref DevOpsEventBus 99 | StatementId: "OrangeServiceRuleCreation" 100 | Statement: 101 | Effect: "Allow" 102 | Principal: 103 | AWS: !Sub arn:aws:iam::${OrangeServiceAccountNo}:root 104 | Action: 105 | - "events:PutRule" 106 | - "events:DeleteRule" 107 | - "events:DescribeRule" 108 | - "events:DisableRule" 109 | - "events:EnableRule" 110 | - "events:PutTargets" 111 | - "events:RemoveTargets" 112 | Resource: 113 | - !Sub arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/${DevOpsEventBus.Name}/* 114 | Condition: 115 | StringEqualsIfExists: 116 | "events:creatorAccount": "${aws:PrincipalAccount}" 117 | "events:source": "com.exampleCorp.PurpleService" 118 | Outputs: 119 | DevOpsEventBusArn: 120 | Description: The ARN of the DevOps event bus 121 | Value: !GetAtt DevOpsEventBus.Arn -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/subscriptions.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | Description: Purple service app subscriptions for for multi-bus, multi-account-pattern 4 | 5 | Parameters: 6 | 7 | PurpleServiceEventBusArn: 8 | Description: ARN of the purple service app event bus 9 | Type: String 10 | 11 | PurpleServiceEventBusDlqUrl: 12 | Description: URL of the purple service Dead Letter Queue 13 | Type: String 14 | 15 | PurpleServiceEventBusDlqArn: 16 | Description: ARN of the purple service Dead Letter Queue 17 | Type: String 18 | 19 | BlueServiceEventBusArn: 20 | Description: ARN of the Blue service event bus to add rules 21 | Type: String 22 | 23 | OrangeServiceEventBusArn: 24 | Description: ARN of the Orange service event bus to add rules 25 | Type: String 26 | 27 | Resources: 28 | 29 | # Rule that is placed on the Purple event bus for Event 1 30 | PurpleServiceE1SubscriptionRule: 31 | Type: AWS::Events::Rule 32 | Properties: 33 | Name: PurpleE1Subscription 34 | Description: Cross account rule created by Purple service for event 1 35 | EventBusName: !Ref BlueServiceEventBusArn # ARN of the blue event bus 36 | EventPattern: 37 | source: 38 | - com.exampleCorp.BlueService 39 | detail-type: 40 | - Event1 41 | State: ENABLED 42 | Targets: 43 | - Id: SendEvent1ToPurpleServiceEventBus 44 | Arn: !Ref PurpleServiceEventBusArn 45 | RoleArn: !GetAtt ServiceEventBusToPurpleServiceEventBusRole.Arn 46 | DeadLetterConfig: 47 | Arn: !Ref PurpleServiceEventBusDlqArn 48 | 49 | # Rule that is placed on the DevOps event bus for Event 2 50 | PurpleServiceE3SubscriptionRule: 51 | Type: AWS::Events::Rule 52 | Properties: 53 | Name: PurpleE3Subscription 54 | Description: Cross account rule created by Blue service for event 2 55 | EventBusName: !Ref OrangeServiceEventBusArn # ARN of the orange event bus 56 | EventPattern: 57 | source: 58 | - com.exampleCorp.OrangeService 59 | detail-type: 60 | - Event3 61 | State: ENABLED 62 | Targets: 63 | - Id: SendEvent3ToPurpleServiceEventBus 64 | Arn: !Ref PurpleServiceEventBusArn 65 | RoleArn: !GetAtt ServiceEventBusToPurpleServiceEventBusRole.Arn 66 | DeadLetterConfig: 67 | Arn: !Ref PurpleServiceEventBusDlqArn 68 | 69 | # This IAM role allows EventBridge to assume the permissions necessary to send events 70 | # from the DevOps event bus to the Blue service event bus. No resource policy is required 71 | # on the Blue service event bus. 72 | ServiceEventBusToPurpleServiceEventBusRole: 73 | Type: 'AWS::IAM::Role' 74 | Properties: 75 | AssumeRolePolicyDocument: 76 | Version: 2012-10-17 77 | Statement: 78 | - Effect: Allow 79 | Principal: 80 | Service: 81 | - events.amazonaws.com 82 | Action: 83 | - 'sts:AssumeRole' 84 | Path: / 85 | Policies: 86 | - PolicyName: PutEventsOnPurpleServiceEventBus 87 | PolicyDocument: 88 | Version: 2012-10-17 89 | Statement: 90 | - Effect: Allow 91 | Action: 'events:PutEvents' 92 | Resource: !Ref PurpleServiceEventBusArn 93 | 94 | 95 | # SQS resource policy required to allow targets on service buses to send failed messages to target DLQ 96 | PurpleServiceEventBusDlqPolicy: 97 | Type: AWS::SQS::QueuePolicy 98 | Properties: 99 | Queues: 100 | - !Ref PurpleServiceEventBusDlqUrl 101 | PolicyDocument: 102 | Statement: 103 | - Action: 104 | - "SQS:SendMessage" 105 | Effect: "Allow" 106 | Resource: !Ref PurpleServiceEventBusDlqArn 107 | Principal: 108 | Service: "events.amazonaws.com" 109 | Condition: 110 | ArnEquals: 111 | "aws:SourceArn": [ 112 | !GetAtt PurpleServiceE1SubscriptionRule.Arn, 113 | !GetAtt PurpleServiceE3SubscriptionRule.Arn 114 | ] 115 | 116 | Outputs: 117 | PurpleE1Subscription: 118 | Description: Rule ARN for purple service event 1 subscription 119 | Value: !GetAtt PurpleServiceE1SubscriptionRule.Arn 120 | PurpleE3Subscription: 121 | Description: Rule ARN for purple service event 3 subscription 122 | Value: !GetAtt PurpleServiceE3SubscriptionRule.Arn -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: > 4 | Orange service app for for multi-bus, multi-account-pattern 5 | 6 | # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst 7 | Globals: 8 | Function: 9 | Timeout: 3 10 | Handler: app.lambda_handler 11 | Runtime: python3.12 12 | Tags: 13 | pattern: multi-bus-multi-account-pattern 14 | 15 | Parameters: 16 | EventBusName: 17 | Description: Name of the orange service app event bus 18 | Type: String 19 | Default: orange-service-event-bus-multi-bus 20 | 21 | BlueServiceAccountNo: 22 | Description: Account Id Blue service event bus to add rules 23 | Type: String 24 | 25 | PurpleServiceAccountNo: 26 | Description: Account Id Purple service event bus to add rules 27 | Type: String 28 | 29 | Resources: 30 | 31 | # Event bus for orange service. 32 | OrangeServiceEventBus: 33 | Type: AWS::Events::EventBus 34 | Properties: 35 | Name: !Ref EventBusName 36 | 37 | # Resource policy for Orange service event bus 38 | OrangeServicePublishStatement: 39 | Type: AWS::Events::EventBusPolicy 40 | Properties: 41 | EventBusName: !Ref OrangeServiceEventBus 42 | StatementId: "OrangeServicePublish" 43 | Statement: 44 | Effect: "Allow" 45 | Principal: 46 | AWS: 47 | - !Sub arn:aws:iam::${AWS::AccountId}:root 48 | Action: "events:PutEvents" 49 | Resource: !GetAtt OrangeServiceEventBus.Arn 50 | Condition: 51 | StringEquals: 52 | "events:source": ["com.exampleCorp.OrangeService"] 53 | 54 | OrangeEventBusRuleCreationStatement: 55 | Type: AWS::Events::EventBusPolicy 56 | Properties: 57 | EventBusName: !Ref OrangeServiceEventBus 58 | StatementId: "AllServiceRuleCreation" 59 | Statement: 60 | Effect: "Allow" 61 | Principal: 62 | AWS: 63 | - !Sub arn:aws:iam::${BlueServiceAccountNo}:root 64 | - !Sub arn:aws:iam::${PurpleServiceAccountNo}:root 65 | Action: 66 | - "events:PutRule" 67 | - "events:DeleteRule" 68 | - "events:DescribeRule" 69 | - "events:DisableRule" 70 | - "events:EnableRule" 71 | - "events:PutTargets" 72 | - "events:RemoveTargets" 73 | Resource: 74 | - !Sub arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/${OrangeServiceEventBus.Name}/* 75 | Condition: 76 | StringEqualsIfExists: 77 | "events:creatorAccount": "${aws:PrincipalAccount}" 78 | "events:source": ["com.exampleCorp.OrangeService"] 79 | 80 | OrangeServicePublisherE3: 81 | Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction 82 | Properties: 83 | CodeUri: orange_p_e3/ 84 | Policies: 85 | - Version: '2012-10-17' 86 | Statement: 87 | - Effect: Allow 88 | Action: 89 | - events:PutEvents 90 | Resource: "*" 91 | Environment: 92 | Variables: 93 | EVENT_BUS_ARN: !Ref OrangeServiceEventBus 94 | 95 | OrangeServiceSubscriberE2: 96 | Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction 97 | Properties: 98 | CodeUri: orange_s_e2/ 99 | Events: 100 | OrangeE2Rule: 101 | Type: EventBridgeRule 102 | Properties: 103 | EventBusName: !Ref OrangeServiceEventBus 104 | Pattern: 105 | source: 106 | - com.exampleCorp.PurpleService 107 | detail-type: 108 | - Event2 109 | 110 | # Orange service event bus targe DLQ 111 | OrangeServiceEventBusDlq: 112 | Type: AWS::SQS::Queue 113 | 114 | Outputs: 115 | OrangeServiceEventBusArn: 116 | Description: The ARN of the Orange event bus 117 | Value: !GetAtt OrangeServiceEventBus.Arn 118 | OrangeServicePublisherE3: 119 | Description: Lambda function name for Orange service publishing event 3 120 | Value: !Ref OrangeServicePublisherE3 121 | OrangeServiceSubscriberE2: 122 | Description: Lambda function name for orange service subscriber to event 2 123 | Value: !Ref OrangeServiceSubscriberE2 124 | OrangeServiceEventBusDlqUrl: 125 | Description: URL of the SQS Queue for rules DeadLetterConfig 126 | Value: !Ref OrangeServiceEventBusDlq 127 | OrangeServiceEventBusDlqArn: 128 | Description: ARN of the SQS Queue for rules DeadLetterConfig 129 | Value: !GetAtt OrangeServiceEventBusDlq.Arn -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/blue-service-account/blue-service-app/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode 3 | 4 | ### Linux ### 5 | *~ 6 | 7 | # temporary files which can be created if a process still has a handle open of a deleted file 8 | .fuse_hidden* 9 | 10 | # KDE directory preferences 11 | .directory 12 | 13 | # Linux trash folder which might appear on any partition or disk 14 | .Trash-* 15 | 16 | # .nfs files are created when an open file is removed but is still being accessed 17 | .nfs* 18 | 19 | ### OSX ### 20 | *.DS_Store 21 | .AppleDouble 22 | .LSOverride 23 | 24 | # Icon must end with two \r 25 | Icon 26 | 27 | # Thumbnails 28 | ._* 29 | 30 | # Files that might appear in the root of a volume 31 | .DocumentRevisions-V100 32 | .fseventsd 33 | .Spotlight-V100 34 | .TemporaryItems 35 | .Trashes 36 | .VolumeIcon.icns 37 | .com.apple.timemachine.donotpresent 38 | 39 | # Directories potentially created on remote AFP share 40 | .AppleDB 41 | .AppleDesktop 42 | Network Trash Folder 43 | Temporary Items 44 | .apdisk 45 | 46 | ### PyCharm ### 47 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 48 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 49 | 50 | # User-specific stuff: 51 | .idea/**/workspace.xml 52 | .idea/**/tasks.xml 53 | .idea/dictionaries 54 | 55 | # Sensitive or high-churn files: 56 | .idea/**/dataSources/ 57 | .idea/**/dataSources.ids 58 | .idea/**/dataSources.xml 59 | .idea/**/dataSources.local.xml 60 | .idea/**/sqlDataSources.xml 61 | .idea/**/dynamic.xml 62 | .idea/**/uiDesigner.xml 63 | 64 | # Gradle: 65 | .idea/**/gradle.xml 66 | .idea/**/libraries 67 | 68 | # CMake 69 | cmake-build-debug/ 70 | 71 | # Mongo Explorer plugin: 72 | .idea/**/mongoSettings.xml 73 | 74 | ## File-based project format: 75 | *.iws 76 | 77 | ## Plugin-specific files: 78 | 79 | # IntelliJ 80 | /out/ 81 | 82 | # mpeltonen/sbt-idea plugin 83 | .idea_modules/ 84 | 85 | # JIRA plugin 86 | atlassian-ide-plugin.xml 87 | 88 | # Cursive Clojure plugin 89 | .idea/replstate.xml 90 | 91 | # Ruby plugin and RubyMine 92 | /.rakeTasks 93 | 94 | # Crashlytics plugin (for Android Studio and IntelliJ) 95 | com_crashlytics_export_strings.xml 96 | crashlytics.properties 97 | crashlytics-build.properties 98 | fabric.properties 99 | 100 | ### PyCharm Patch ### 101 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 102 | 103 | # *.iml 104 | # modules.xml 105 | # .idea/misc.xml 106 | # *.ipr 107 | 108 | # Sonarlint plugin 109 | .idea/sonarlint 110 | 111 | ### Python ### 112 | # Byte-compiled / optimized / DLL files 113 | __pycache__/ 114 | *.py[cod] 115 | *$py.class 116 | 117 | # C extensions 118 | *.so 119 | 120 | # Distribution / packaging 121 | .Python 122 | build/ 123 | develop-eggs/ 124 | dist/ 125 | downloads/ 126 | eggs/ 127 | .eggs/ 128 | lib/ 129 | lib64/ 130 | parts/ 131 | sdist/ 132 | var/ 133 | wheels/ 134 | *.egg-info/ 135 | .installed.cfg 136 | *.egg 137 | 138 | # PyInstaller 139 | # Usually these files are written by a python script from a template 140 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 141 | *.manifest 142 | *.spec 143 | 144 | # Installer logs 145 | pip-log.txt 146 | pip-delete-this-directory.txt 147 | 148 | # Unit test / coverage reports 149 | htmlcov/ 150 | .tox/ 151 | .coverage 152 | .coverage.* 153 | .cache 154 | .pytest_cache/ 155 | nosetests.xml 156 | coverage.xml 157 | *.cover 158 | .hypothesis/ 159 | 160 | # Translations 161 | *.mo 162 | *.pot 163 | 164 | # Flask stuff: 165 | instance/ 166 | .webassets-cache 167 | 168 | # Scrapy stuff: 169 | .scrapy 170 | 171 | # Sphinx documentation 172 | docs/_build/ 173 | 174 | # PyBuilder 175 | target/ 176 | 177 | # Jupyter Notebook 178 | .ipynb_checkpoints 179 | 180 | # pyenv 181 | .python-version 182 | 183 | # celery beat schedule file 184 | celerybeat-schedule.* 185 | 186 | # SageMath parsed files 187 | *.sage.py 188 | 189 | # Environments 190 | .env 191 | .venv 192 | env/ 193 | venv/ 194 | ENV/ 195 | env.bak/ 196 | venv.bak/ 197 | 198 | # Spyder project settings 199 | .spyderproject 200 | .spyproject 201 | 202 | # Rope project settings 203 | .ropeproject 204 | 205 | # mkdocs documentation 206 | /site 207 | 208 | # mypy 209 | .mypy_cache/ 210 | 211 | ### VisualStudioCode ### 212 | .vscode/* 213 | !.vscode/settings.json 214 | !.vscode/tasks.json 215 | !.vscode/launch.json 216 | !.vscode/extensions.json 217 | .history 218 | 219 | ### Windows ### 220 | # Windows thumbnail cache files 221 | Thumbs.db 222 | ehthumbs.db 223 | ehthumbs_vista.db 224 | 225 | # Folder config file 226 | Desktop.ini 227 | 228 | # Recycle Bin used on file shares 229 | $RECYCLE.BIN/ 230 | 231 | # Windows Installer files 232 | *.cab 233 | *.msi 234 | *.msm 235 | *.msp 236 | 237 | # Windows shortcuts 238 | *.lnk 239 | 240 | # Build folder 241 | 242 | */build/* 243 | 244 | # End of https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/orange-service-account/orange-service-app/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode 3 | 4 | ### Linux ### 5 | *~ 6 | 7 | # temporary files which can be created if a process still has a handle open of a deleted file 8 | .fuse_hidden* 9 | 10 | # KDE directory preferences 11 | .directory 12 | 13 | # Linux trash folder which might appear on any partition or disk 14 | .Trash-* 15 | 16 | # .nfs files are created when an open file is removed but is still being accessed 17 | .nfs* 18 | 19 | ### OSX ### 20 | *.DS_Store 21 | .AppleDouble 22 | .LSOverride 23 | 24 | # Icon must end with two \r 25 | Icon 26 | 27 | # Thumbnails 28 | ._* 29 | 30 | # Files that might appear in the root of a volume 31 | .DocumentRevisions-V100 32 | .fseventsd 33 | .Spotlight-V100 34 | .TemporaryItems 35 | .Trashes 36 | .VolumeIcon.icns 37 | .com.apple.timemachine.donotpresent 38 | 39 | # Directories potentially created on remote AFP share 40 | .AppleDB 41 | .AppleDesktop 42 | Network Trash Folder 43 | Temporary Items 44 | .apdisk 45 | 46 | ### PyCharm ### 47 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 48 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 49 | 50 | # User-specific stuff: 51 | .idea/**/workspace.xml 52 | .idea/**/tasks.xml 53 | .idea/dictionaries 54 | 55 | # Sensitive or high-churn files: 56 | .idea/**/dataSources/ 57 | .idea/**/dataSources.ids 58 | .idea/**/dataSources.xml 59 | .idea/**/dataSources.local.xml 60 | .idea/**/sqlDataSources.xml 61 | .idea/**/dynamic.xml 62 | .idea/**/uiDesigner.xml 63 | 64 | # Gradle: 65 | .idea/**/gradle.xml 66 | .idea/**/libraries 67 | 68 | # CMake 69 | cmake-build-debug/ 70 | 71 | # Mongo Explorer plugin: 72 | .idea/**/mongoSettings.xml 73 | 74 | ## File-based project format: 75 | *.iws 76 | 77 | ## Plugin-specific files: 78 | 79 | # IntelliJ 80 | /out/ 81 | 82 | # mpeltonen/sbt-idea plugin 83 | .idea_modules/ 84 | 85 | # JIRA plugin 86 | atlassian-ide-plugin.xml 87 | 88 | # Cursive Clojure plugin 89 | .idea/replstate.xml 90 | 91 | # Ruby plugin and RubyMine 92 | /.rakeTasks 93 | 94 | # Crashlytics plugin (for Android Studio and IntelliJ) 95 | com_crashlytics_export_strings.xml 96 | crashlytics.properties 97 | crashlytics-build.properties 98 | fabric.properties 99 | 100 | ### PyCharm Patch ### 101 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 102 | 103 | # *.iml 104 | # modules.xml 105 | # .idea/misc.xml 106 | # *.ipr 107 | 108 | # Sonarlint plugin 109 | .idea/sonarlint 110 | 111 | ### Python ### 112 | # Byte-compiled / optimized / DLL files 113 | __pycache__/ 114 | *.py[cod] 115 | *$py.class 116 | 117 | # C extensions 118 | *.so 119 | 120 | # Distribution / packaging 121 | .Python 122 | build/ 123 | develop-eggs/ 124 | dist/ 125 | downloads/ 126 | eggs/ 127 | .eggs/ 128 | lib/ 129 | lib64/ 130 | parts/ 131 | sdist/ 132 | var/ 133 | wheels/ 134 | *.egg-info/ 135 | .installed.cfg 136 | *.egg 137 | 138 | # PyInstaller 139 | # Usually these files are written by a python script from a template 140 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 141 | *.manifest 142 | *.spec 143 | 144 | # Installer logs 145 | pip-log.txt 146 | pip-delete-this-directory.txt 147 | 148 | # Unit test / coverage reports 149 | htmlcov/ 150 | .tox/ 151 | .coverage 152 | .coverage.* 153 | .cache 154 | .pytest_cache/ 155 | nosetests.xml 156 | coverage.xml 157 | *.cover 158 | .hypothesis/ 159 | 160 | # Translations 161 | *.mo 162 | *.pot 163 | 164 | # Flask stuff: 165 | instance/ 166 | .webassets-cache 167 | 168 | # Scrapy stuff: 169 | .scrapy 170 | 171 | # Sphinx documentation 172 | docs/_build/ 173 | 174 | # PyBuilder 175 | target/ 176 | 177 | # Jupyter Notebook 178 | .ipynb_checkpoints 179 | 180 | # pyenv 181 | .python-version 182 | 183 | # celery beat schedule file 184 | celerybeat-schedule.* 185 | 186 | # SageMath parsed files 187 | *.sage.py 188 | 189 | # Environments 190 | .env 191 | .venv 192 | env/ 193 | venv/ 194 | ENV/ 195 | env.bak/ 196 | venv.bak/ 197 | 198 | # Spyder project settings 199 | .spyderproject 200 | .spyproject 201 | 202 | # Rope project settings 203 | .ropeproject 204 | 205 | # mkdocs documentation 206 | /site 207 | 208 | # mypy 209 | .mypy_cache/ 210 | 211 | ### VisualStudioCode ### 212 | .vscode/* 213 | !.vscode/settings.json 214 | !.vscode/tasks.json 215 | !.vscode/launch.json 216 | !.vscode/extensions.json 217 | .history 218 | 219 | ### Windows ### 220 | # Windows thumbnail cache files 221 | Thumbs.db 222 | ehthumbs.db 223 | ehthumbs_vista.db 224 | 225 | # Folder config file 226 | Desktop.ini 227 | 228 | # Recycle Bin used on file shares 229 | $RECYCLE.BIN/ 230 | 231 | # Windows Installer files 232 | *.cab 233 | *.msi 234 | *.msm 235 | *.msp 236 | 237 | # Windows shortcuts 238 | *.lnk 239 | 240 | # Build folder 241 | 242 | */build/* 243 | 244 | # End of https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode -------------------------------------------------------------------------------- /patterns/multi-bus-multi-account-pattern/purple-service-account/purple-service-app/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode 3 | 4 | ### Linux ### 5 | *~ 6 | 7 | # temporary files which can be created if a process still has a handle open of a deleted file 8 | .fuse_hidden* 9 | 10 | # KDE directory preferences 11 | .directory 12 | 13 | # Linux trash folder which might appear on any partition or disk 14 | .Trash-* 15 | 16 | # .nfs files are created when an open file is removed but is still being accessed 17 | .nfs* 18 | 19 | ### OSX ### 20 | *.DS_Store 21 | .AppleDouble 22 | .LSOverride 23 | 24 | # Icon must end with two \r 25 | Icon 26 | 27 | # Thumbnails 28 | ._* 29 | 30 | # Files that might appear in the root of a volume 31 | .DocumentRevisions-V100 32 | .fseventsd 33 | .Spotlight-V100 34 | .TemporaryItems 35 | .Trashes 36 | .VolumeIcon.icns 37 | .com.apple.timemachine.donotpresent 38 | 39 | # Directories potentially created on remote AFP share 40 | .AppleDB 41 | .AppleDesktop 42 | Network Trash Folder 43 | Temporary Items 44 | .apdisk 45 | 46 | ### PyCharm ### 47 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 48 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 49 | 50 | # User-specific stuff: 51 | .idea/**/workspace.xml 52 | .idea/**/tasks.xml 53 | .idea/dictionaries 54 | 55 | # Sensitive or high-churn files: 56 | .idea/**/dataSources/ 57 | .idea/**/dataSources.ids 58 | .idea/**/dataSources.xml 59 | .idea/**/dataSources.local.xml 60 | .idea/**/sqlDataSources.xml 61 | .idea/**/dynamic.xml 62 | .idea/**/uiDesigner.xml 63 | 64 | # Gradle: 65 | .idea/**/gradle.xml 66 | .idea/**/libraries 67 | 68 | # CMake 69 | cmake-build-debug/ 70 | 71 | # Mongo Explorer plugin: 72 | .idea/**/mongoSettings.xml 73 | 74 | ## File-based project format: 75 | *.iws 76 | 77 | ## Plugin-specific files: 78 | 79 | # IntelliJ 80 | /out/ 81 | 82 | # mpeltonen/sbt-idea plugin 83 | .idea_modules/ 84 | 85 | # JIRA plugin 86 | atlassian-ide-plugin.xml 87 | 88 | # Cursive Clojure plugin 89 | .idea/replstate.xml 90 | 91 | # Ruby plugin and RubyMine 92 | /.rakeTasks 93 | 94 | # Crashlytics plugin (for Android Studio and IntelliJ) 95 | com_crashlytics_export_strings.xml 96 | crashlytics.properties 97 | crashlytics-build.properties 98 | fabric.properties 99 | 100 | ### PyCharm Patch ### 101 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 102 | 103 | # *.iml 104 | # modules.xml 105 | # .idea/misc.xml 106 | # *.ipr 107 | 108 | # Sonarlint plugin 109 | .idea/sonarlint 110 | 111 | ### Python ### 112 | # Byte-compiled / optimized / DLL files 113 | __pycache__/ 114 | *.py[cod] 115 | *$py.class 116 | 117 | # C extensions 118 | *.so 119 | 120 | # Distribution / packaging 121 | .Python 122 | build/ 123 | develop-eggs/ 124 | dist/ 125 | downloads/ 126 | eggs/ 127 | .eggs/ 128 | lib/ 129 | lib64/ 130 | parts/ 131 | sdist/ 132 | var/ 133 | wheels/ 134 | *.egg-info/ 135 | .installed.cfg 136 | *.egg 137 | 138 | # PyInstaller 139 | # Usually these files are written by a python script from a template 140 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 141 | *.manifest 142 | *.spec 143 | 144 | # Installer logs 145 | pip-log.txt 146 | pip-delete-this-directory.txt 147 | 148 | # Unit test / coverage reports 149 | htmlcov/ 150 | .tox/ 151 | .coverage 152 | .coverage.* 153 | .cache 154 | .pytest_cache/ 155 | nosetests.xml 156 | coverage.xml 157 | *.cover 158 | .hypothesis/ 159 | 160 | # Translations 161 | *.mo 162 | *.pot 163 | 164 | # Flask stuff: 165 | instance/ 166 | .webassets-cache 167 | 168 | # Scrapy stuff: 169 | .scrapy 170 | 171 | # Sphinx documentation 172 | docs/_build/ 173 | 174 | # PyBuilder 175 | target/ 176 | 177 | # Jupyter Notebook 178 | .ipynb_checkpoints 179 | 180 | # pyenv 181 | .python-version 182 | 183 | # celery beat schedule file 184 | celerybeat-schedule.* 185 | 186 | # SageMath parsed files 187 | *.sage.py 188 | 189 | # Environments 190 | .env 191 | .venv 192 | env/ 193 | venv/ 194 | ENV/ 195 | env.bak/ 196 | venv.bak/ 197 | 198 | # Spyder project settings 199 | .spyderproject 200 | .spyproject 201 | 202 | # Rope project settings 203 | .ropeproject 204 | 205 | # mkdocs documentation 206 | /site 207 | 208 | # mypy 209 | .mypy_cache/ 210 | 211 | ### VisualStudioCode ### 212 | .vscode/* 213 | !.vscode/settings.json 214 | !.vscode/tasks.json 215 | !.vscode/launch.json 216 | !.vscode/extensions.json 217 | .history 218 | 219 | ### Windows ### 220 | # Windows thumbnail cache files 221 | Thumbs.db 222 | ehthumbs.db 223 | ehthumbs_vista.db 224 | 225 | # Folder config file 226 | Desktop.ini 227 | 228 | # Recycle Bin used on file shares 229 | $RECYCLE.BIN/ 230 | 231 | # Windows Installer files 232 | *.cab 233 | *.msi 234 | *.msm 235 | *.msp 236 | 237 | # Windows shortcuts 238 | *.lnk 239 | 240 | # Build folder 241 | 242 | */build/* 243 | 244 | # End of https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/blue-service-account/blue-service-app/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode 3 | 4 | ### Linux ### 5 | *~ 6 | 7 | # temporary files which can be created if a process still has a handle open of a deleted file 8 | .fuse_hidden* 9 | 10 | # KDE directory preferences 11 | .directory 12 | 13 | # Linux trash folder which might appear on any partition or disk 14 | .Trash-* 15 | 16 | # .nfs files are created when an open file is removed but is still being accessed 17 | .nfs* 18 | 19 | ### OSX ### 20 | *.DS_Store 21 | .AppleDouble 22 | .LSOverride 23 | 24 | # Icon must end with two \r 25 | Icon 26 | 27 | # Thumbnails 28 | ._* 29 | 30 | # Files that might appear in the root of a volume 31 | .DocumentRevisions-V100 32 | .fseventsd 33 | .Spotlight-V100 34 | .TemporaryItems 35 | .Trashes 36 | .VolumeIcon.icns 37 | .com.apple.timemachine.donotpresent 38 | 39 | # Directories potentially created on remote AFP share 40 | .AppleDB 41 | .AppleDesktop 42 | Network Trash Folder 43 | Temporary Items 44 | .apdisk 45 | 46 | ### PyCharm ### 47 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 48 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 49 | 50 | # User-specific stuff: 51 | .idea/**/workspace.xml 52 | .idea/**/tasks.xml 53 | .idea/dictionaries 54 | 55 | # Sensitive or high-churn files: 56 | .idea/**/dataSources/ 57 | .idea/**/dataSources.ids 58 | .idea/**/dataSources.xml 59 | .idea/**/dataSources.local.xml 60 | .idea/**/sqlDataSources.xml 61 | .idea/**/dynamic.xml 62 | .idea/**/uiDesigner.xml 63 | 64 | # Gradle: 65 | .idea/**/gradle.xml 66 | .idea/**/libraries 67 | 68 | # CMake 69 | cmake-build-debug/ 70 | 71 | # Mongo Explorer plugin: 72 | .idea/**/mongoSettings.xml 73 | 74 | ## File-based project format: 75 | *.iws 76 | 77 | ## Plugin-specific files: 78 | 79 | # IntelliJ 80 | /out/ 81 | 82 | # mpeltonen/sbt-idea plugin 83 | .idea_modules/ 84 | 85 | # JIRA plugin 86 | atlassian-ide-plugin.xml 87 | 88 | # Cursive Clojure plugin 89 | .idea/replstate.xml 90 | 91 | # Ruby plugin and RubyMine 92 | /.rakeTasks 93 | 94 | # Crashlytics plugin (for Android Studio and IntelliJ) 95 | com_crashlytics_export_strings.xml 96 | crashlytics.properties 97 | crashlytics-build.properties 98 | fabric.properties 99 | 100 | ### PyCharm Patch ### 101 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 102 | 103 | # *.iml 104 | # modules.xml 105 | # .idea/misc.xml 106 | # *.ipr 107 | 108 | # Sonarlint plugin 109 | .idea/sonarlint 110 | 111 | ### Python ### 112 | # Byte-compiled / optimized / DLL files 113 | __pycache__/ 114 | *.py[cod] 115 | *$py.class 116 | 117 | # C extensions 118 | *.so 119 | 120 | # Distribution / packaging 121 | .Python 122 | build/ 123 | develop-eggs/ 124 | dist/ 125 | downloads/ 126 | eggs/ 127 | .eggs/ 128 | lib/ 129 | lib64/ 130 | parts/ 131 | sdist/ 132 | var/ 133 | wheels/ 134 | *.egg-info/ 135 | .installed.cfg 136 | *.egg 137 | 138 | # PyInstaller 139 | # Usually these files are written by a python script from a template 140 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 141 | *.manifest 142 | *.spec 143 | 144 | # Installer logs 145 | pip-log.txt 146 | pip-delete-this-directory.txt 147 | 148 | # Unit test / coverage reports 149 | htmlcov/ 150 | .tox/ 151 | .coverage 152 | .coverage.* 153 | .cache 154 | .pytest_cache/ 155 | nosetests.xml 156 | coverage.xml 157 | *.cover 158 | .hypothesis/ 159 | 160 | # Translations 161 | *.mo 162 | *.pot 163 | 164 | # Flask stuff: 165 | instance/ 166 | .webassets-cache 167 | 168 | # Scrapy stuff: 169 | .scrapy 170 | 171 | # Sphinx documentation 172 | docs/_build/ 173 | 174 | # PyBuilder 175 | target/ 176 | 177 | # Jupyter Notebook 178 | .ipynb_checkpoints 179 | 180 | # pyenv 181 | .python-version 182 | 183 | # celery beat schedule file 184 | celerybeat-schedule.* 185 | 186 | # SageMath parsed files 187 | *.sage.py 188 | 189 | # Environments 190 | .env 191 | .venv 192 | env/ 193 | venv/ 194 | ENV/ 195 | env.bak/ 196 | venv.bak/ 197 | 198 | # Spyder project settings 199 | .spyderproject 200 | .spyproject 201 | 202 | # Rope project settings 203 | .ropeproject 204 | 205 | # mkdocs documentation 206 | /site 207 | 208 | # mypy 209 | .mypy_cache/ 210 | 211 | ### VisualStudioCode ### 212 | .vscode/* 213 | !.vscode/settings.json 214 | !.vscode/tasks.json 215 | !.vscode/launch.json 216 | !.vscode/extensions.json 217 | .history 218 | 219 | ### Windows ### 220 | # Windows thumbnail cache files 221 | Thumbs.db 222 | ehthumbs.db 223 | ehthumbs_vista.db 224 | 225 | # Folder config file 226 | Desktop.ini 227 | 228 | # Recycle Bin used on file shares 229 | $RECYCLE.BIN/ 230 | 231 | # Windows Installer files 232 | *.cab 233 | *.msi 234 | *.msm 235 | *.msp 236 | 237 | # Windows shortcuts 238 | *.lnk 239 | 240 | # Build folder 241 | 242 | */build/* 243 | 244 | # End of https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/orange-service-account/orange-service-app/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode 3 | 4 | ### Linux ### 5 | *~ 6 | 7 | # temporary files which can be created if a process still has a handle open of a deleted file 8 | .fuse_hidden* 9 | 10 | # KDE directory preferences 11 | .directory 12 | 13 | # Linux trash folder which might appear on any partition or disk 14 | .Trash-* 15 | 16 | # .nfs files are created when an open file is removed but is still being accessed 17 | .nfs* 18 | 19 | ### OSX ### 20 | *.DS_Store 21 | .AppleDouble 22 | .LSOverride 23 | 24 | # Icon must end with two \r 25 | Icon 26 | 27 | # Thumbnails 28 | ._* 29 | 30 | # Files that might appear in the root of a volume 31 | .DocumentRevisions-V100 32 | .fseventsd 33 | .Spotlight-V100 34 | .TemporaryItems 35 | .Trashes 36 | .VolumeIcon.icns 37 | .com.apple.timemachine.donotpresent 38 | 39 | # Directories potentially created on remote AFP share 40 | .AppleDB 41 | .AppleDesktop 42 | Network Trash Folder 43 | Temporary Items 44 | .apdisk 45 | 46 | ### PyCharm ### 47 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 48 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 49 | 50 | # User-specific stuff: 51 | .idea/**/workspace.xml 52 | .idea/**/tasks.xml 53 | .idea/dictionaries 54 | 55 | # Sensitive or high-churn files: 56 | .idea/**/dataSources/ 57 | .idea/**/dataSources.ids 58 | .idea/**/dataSources.xml 59 | .idea/**/dataSources.local.xml 60 | .idea/**/sqlDataSources.xml 61 | .idea/**/dynamic.xml 62 | .idea/**/uiDesigner.xml 63 | 64 | # Gradle: 65 | .idea/**/gradle.xml 66 | .idea/**/libraries 67 | 68 | # CMake 69 | cmake-build-debug/ 70 | 71 | # Mongo Explorer plugin: 72 | .idea/**/mongoSettings.xml 73 | 74 | ## File-based project format: 75 | *.iws 76 | 77 | ## Plugin-specific files: 78 | 79 | # IntelliJ 80 | /out/ 81 | 82 | # mpeltonen/sbt-idea plugin 83 | .idea_modules/ 84 | 85 | # JIRA plugin 86 | atlassian-ide-plugin.xml 87 | 88 | # Cursive Clojure plugin 89 | .idea/replstate.xml 90 | 91 | # Ruby plugin and RubyMine 92 | /.rakeTasks 93 | 94 | # Crashlytics plugin (for Android Studio and IntelliJ) 95 | com_crashlytics_export_strings.xml 96 | crashlytics.properties 97 | crashlytics-build.properties 98 | fabric.properties 99 | 100 | ### PyCharm Patch ### 101 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 102 | 103 | # *.iml 104 | # modules.xml 105 | # .idea/misc.xml 106 | # *.ipr 107 | 108 | # Sonarlint plugin 109 | .idea/sonarlint 110 | 111 | ### Python ### 112 | # Byte-compiled / optimized / DLL files 113 | __pycache__/ 114 | *.py[cod] 115 | *$py.class 116 | 117 | # C extensions 118 | *.so 119 | 120 | # Distribution / packaging 121 | .Python 122 | build/ 123 | develop-eggs/ 124 | dist/ 125 | downloads/ 126 | eggs/ 127 | .eggs/ 128 | lib/ 129 | lib64/ 130 | parts/ 131 | sdist/ 132 | var/ 133 | wheels/ 134 | *.egg-info/ 135 | .installed.cfg 136 | *.egg 137 | 138 | # PyInstaller 139 | # Usually these files are written by a python script from a template 140 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 141 | *.manifest 142 | *.spec 143 | 144 | # Installer logs 145 | pip-log.txt 146 | pip-delete-this-directory.txt 147 | 148 | # Unit test / coverage reports 149 | htmlcov/ 150 | .tox/ 151 | .coverage 152 | .coverage.* 153 | .cache 154 | .pytest_cache/ 155 | nosetests.xml 156 | coverage.xml 157 | *.cover 158 | .hypothesis/ 159 | 160 | # Translations 161 | *.mo 162 | *.pot 163 | 164 | # Flask stuff: 165 | instance/ 166 | .webassets-cache 167 | 168 | # Scrapy stuff: 169 | .scrapy 170 | 171 | # Sphinx documentation 172 | docs/_build/ 173 | 174 | # PyBuilder 175 | target/ 176 | 177 | # Jupyter Notebook 178 | .ipynb_checkpoints 179 | 180 | # pyenv 181 | .python-version 182 | 183 | # celery beat schedule file 184 | celerybeat-schedule.* 185 | 186 | # SageMath parsed files 187 | *.sage.py 188 | 189 | # Environments 190 | .env 191 | .venv 192 | env/ 193 | venv/ 194 | ENV/ 195 | env.bak/ 196 | venv.bak/ 197 | 198 | # Spyder project settings 199 | .spyderproject 200 | .spyproject 201 | 202 | # Rope project settings 203 | .ropeproject 204 | 205 | # mkdocs documentation 206 | /site 207 | 208 | # mypy 209 | .mypy_cache/ 210 | 211 | ### VisualStudioCode ### 212 | .vscode/* 213 | !.vscode/settings.json 214 | !.vscode/tasks.json 215 | !.vscode/launch.json 216 | !.vscode/extensions.json 217 | .history 218 | 219 | ### Windows ### 220 | # Windows thumbnail cache files 221 | Thumbs.db 222 | ehthumbs.db 223 | ehthumbs_vista.db 224 | 225 | # Folder config file 226 | Desktop.ini 227 | 228 | # Recycle Bin used on file shares 229 | $RECYCLE.BIN/ 230 | 231 | # Windows Installer files 232 | *.cab 233 | *.msi 234 | *.msm 235 | *.msp 236 | 237 | # Windows shortcuts 238 | *.lnk 239 | 240 | # Build folder 241 | 242 | */build/* 243 | 244 | # End of https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/purple-service-account/purple-service-app/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode 3 | 4 | ### Linux ### 5 | *~ 6 | 7 | # temporary files which can be created if a process still has a handle open of a deleted file 8 | .fuse_hidden* 9 | 10 | # KDE directory preferences 11 | .directory 12 | 13 | # Linux trash folder which might appear on any partition or disk 14 | .Trash-* 15 | 16 | # .nfs files are created when an open file is removed but is still being accessed 17 | .nfs* 18 | 19 | ### OSX ### 20 | *.DS_Store 21 | .AppleDouble 22 | .LSOverride 23 | 24 | # Icon must end with two \r 25 | Icon 26 | 27 | # Thumbnails 28 | ._* 29 | 30 | # Files that might appear in the root of a volume 31 | .DocumentRevisions-V100 32 | .fseventsd 33 | .Spotlight-V100 34 | .TemporaryItems 35 | .Trashes 36 | .VolumeIcon.icns 37 | .com.apple.timemachine.donotpresent 38 | 39 | # Directories potentially created on remote AFP share 40 | .AppleDB 41 | .AppleDesktop 42 | Network Trash Folder 43 | Temporary Items 44 | .apdisk 45 | 46 | ### PyCharm ### 47 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 48 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 49 | 50 | # User-specific stuff: 51 | .idea/**/workspace.xml 52 | .idea/**/tasks.xml 53 | .idea/dictionaries 54 | 55 | # Sensitive or high-churn files: 56 | .idea/**/dataSources/ 57 | .idea/**/dataSources.ids 58 | .idea/**/dataSources.xml 59 | .idea/**/dataSources.local.xml 60 | .idea/**/sqlDataSources.xml 61 | .idea/**/dynamic.xml 62 | .idea/**/uiDesigner.xml 63 | 64 | # Gradle: 65 | .idea/**/gradle.xml 66 | .idea/**/libraries 67 | 68 | # CMake 69 | cmake-build-debug/ 70 | 71 | # Mongo Explorer plugin: 72 | .idea/**/mongoSettings.xml 73 | 74 | ## File-based project format: 75 | *.iws 76 | 77 | ## Plugin-specific files: 78 | 79 | # IntelliJ 80 | /out/ 81 | 82 | # mpeltonen/sbt-idea plugin 83 | .idea_modules/ 84 | 85 | # JIRA plugin 86 | atlassian-ide-plugin.xml 87 | 88 | # Cursive Clojure plugin 89 | .idea/replstate.xml 90 | 91 | # Ruby plugin and RubyMine 92 | /.rakeTasks 93 | 94 | # Crashlytics plugin (for Android Studio and IntelliJ) 95 | com_crashlytics_export_strings.xml 96 | crashlytics.properties 97 | crashlytics-build.properties 98 | fabric.properties 99 | 100 | ### PyCharm Patch ### 101 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 102 | 103 | # *.iml 104 | # modules.xml 105 | # .idea/misc.xml 106 | # *.ipr 107 | 108 | # Sonarlint plugin 109 | .idea/sonarlint 110 | 111 | ### Python ### 112 | # Byte-compiled / optimized / DLL files 113 | __pycache__/ 114 | *.py[cod] 115 | *$py.class 116 | 117 | # C extensions 118 | *.so 119 | 120 | # Distribution / packaging 121 | .Python 122 | build/ 123 | develop-eggs/ 124 | dist/ 125 | downloads/ 126 | eggs/ 127 | .eggs/ 128 | lib/ 129 | lib64/ 130 | parts/ 131 | sdist/ 132 | var/ 133 | wheels/ 134 | *.egg-info/ 135 | .installed.cfg 136 | *.egg 137 | 138 | # PyInstaller 139 | # Usually these files are written by a python script from a template 140 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 141 | *.manifest 142 | *.spec 143 | 144 | # Installer logs 145 | pip-log.txt 146 | pip-delete-this-directory.txt 147 | 148 | # Unit test / coverage reports 149 | htmlcov/ 150 | .tox/ 151 | .coverage 152 | .coverage.* 153 | .cache 154 | .pytest_cache/ 155 | nosetests.xml 156 | coverage.xml 157 | *.cover 158 | .hypothesis/ 159 | 160 | # Translations 161 | *.mo 162 | *.pot 163 | 164 | # Flask stuff: 165 | instance/ 166 | .webassets-cache 167 | 168 | # Scrapy stuff: 169 | .scrapy 170 | 171 | # Sphinx documentation 172 | docs/_build/ 173 | 174 | # PyBuilder 175 | target/ 176 | 177 | # Jupyter Notebook 178 | .ipynb_checkpoints 179 | 180 | # pyenv 181 | .python-version 182 | 183 | # celery beat schedule file 184 | celerybeat-schedule.* 185 | 186 | # SageMath parsed files 187 | *.sage.py 188 | 189 | # Environments 190 | .env 191 | .venv 192 | env/ 193 | venv/ 194 | ENV/ 195 | env.bak/ 196 | venv.bak/ 197 | 198 | # Spyder project settings 199 | .spyderproject 200 | .spyproject 201 | 202 | # Rope project settings 203 | .ropeproject 204 | 205 | # mkdocs documentation 206 | /site 207 | 208 | # mypy 209 | .mypy_cache/ 210 | 211 | ### VisualStudioCode ### 212 | .vscode/* 213 | !.vscode/settings.json 214 | !.vscode/tasks.json 215 | !.vscode/launch.json 216 | !.vscode/extensions.json 217 | .history 218 | 219 | ### Windows ### 220 | # Windows thumbnail cache files 221 | Thumbs.db 222 | ehthumbs.db 223 | ehthumbs_vista.db 224 | 225 | # Folder config file 226 | Desktop.ini 227 | 228 | # Recycle Bin used on file shares 229 | $RECYCLE.BIN/ 230 | 231 | # Windows Installer files 232 | *.cab 233 | *.msi 234 | *.msm 235 | *.msp 236 | 237 | # Windows shortcuts 238 | *.lnk 239 | 240 | # Build folder 241 | 242 | */build/* 243 | 244 | # End of https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/.aws-sam 2 | .vscode 3 | .vscode/settings.json 4 | **/samconfig.toml 5 | 6 | # Created by https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode 7 | 8 | ### Linux ### 9 | *~ 10 | 11 | # temporary files which can be created if a process still has a handle open of a deleted file 12 | .fuse_hidden* 13 | 14 | # KDE directory preferences 15 | .directory 16 | 17 | # Linux trash folder which might appear on any partition or disk 18 | .Trash-* 19 | 20 | # .nfs files are created when an open file is removed but is still being accessed 21 | .nfs* 22 | 23 | ### OSX ### 24 | *.DS_Store 25 | .AppleDouble 26 | .LSOverride 27 | 28 | # Icon must end with two \r 29 | Icon 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | .com.apple.timemachine.donotpresent 42 | 43 | # Directories potentially created on remote AFP share 44 | .AppleDB 45 | .AppleDesktop 46 | Network Trash Folder 47 | Temporary Items 48 | .apdisk 49 | 50 | ### PyCharm ### 51 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 52 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 53 | 54 | # User-specific stuff: 55 | .idea/**/workspace.xml 56 | .idea/**/tasks.xml 57 | .idea/dictionaries 58 | 59 | # Sensitive or high-churn files: 60 | .idea/**/dataSources/ 61 | .idea/**/dataSources.ids 62 | .idea/**/dataSources.xml 63 | .idea/**/dataSources.local.xml 64 | .idea/**/sqlDataSources.xml 65 | .idea/**/dynamic.xml 66 | .idea/**/uiDesigner.xml 67 | 68 | # Gradle: 69 | .idea/**/gradle.xml 70 | .idea/**/libraries 71 | 72 | # CMake 73 | cmake-build-debug/ 74 | 75 | # Mongo Explorer plugin: 76 | .idea/**/mongoSettings.xml 77 | 78 | ## File-based project format: 79 | *.iws 80 | 81 | ## Plugin-specific files: 82 | 83 | # IntelliJ 84 | /out/ 85 | 86 | # mpeltonen/sbt-idea plugin 87 | .idea_modules/ 88 | 89 | # JIRA plugin 90 | atlassian-ide-plugin.xml 91 | 92 | # Cursive Clojure plugin 93 | .idea/replstate.xml 94 | 95 | # Ruby plugin and RubyMine 96 | /.rakeTasks 97 | 98 | # Crashlytics plugin (for Android Studio and IntelliJ) 99 | com_crashlytics_export_strings.xml 100 | crashlytics.properties 101 | crashlytics-build.properties 102 | fabric.properties 103 | 104 | ### PyCharm Patch ### 105 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 106 | 107 | # *.iml 108 | # modules.xml 109 | # .idea/misc.xml 110 | # *.ipr 111 | 112 | # Sonarlint plugin 113 | .idea/sonarlint 114 | 115 | ### Python ### 116 | # Byte-compiled / optimized / DLL files 117 | __pycache__/ 118 | *.py[cod] 119 | *$py.class 120 | 121 | # C extensions 122 | *.so 123 | 124 | # Distribution / packaging 125 | .Python 126 | build/ 127 | develop-eggs/ 128 | dist/ 129 | downloads/ 130 | eggs/ 131 | .eggs/ 132 | lib/ 133 | lib64/ 134 | parts/ 135 | sdist/ 136 | var/ 137 | wheels/ 138 | *.egg-info/ 139 | .installed.cfg 140 | *.egg 141 | 142 | # PyInstaller 143 | # Usually these files are written by a python script from a template 144 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 145 | *.manifest 146 | *.spec 147 | 148 | # Installer logs 149 | pip-log.txt 150 | pip-delete-this-directory.txt 151 | 152 | # Unit test / coverage reports 153 | htmlcov/ 154 | .tox/ 155 | .coverage 156 | .coverage.* 157 | .cache 158 | .pytest_cache/ 159 | nosetests.xml 160 | coverage.xml 161 | *.cover 162 | .hypothesis/ 163 | 164 | # Translations 165 | *.mo 166 | *.pot 167 | 168 | # Flask stuff: 169 | instance/ 170 | .webassets-cache 171 | 172 | # Scrapy stuff: 173 | .scrapy 174 | 175 | # Sphinx documentation 176 | docs/_build/ 177 | 178 | # PyBuilder 179 | target/ 180 | 181 | # Jupyter Notebook 182 | .ipynb_checkpoints 183 | 184 | # pyenv 185 | .python-version 186 | 187 | # celery beat schedule file 188 | celerybeat-schedule.* 189 | 190 | # SageMath parsed files 191 | *.sage.py 192 | 193 | # Environments 194 | .env 195 | .venv 196 | env/ 197 | venv/ 198 | ENV/ 199 | env.bak/ 200 | venv.bak/ 201 | 202 | # Spyder project settings 203 | .spyderproject 204 | .spyproject 205 | 206 | # Rope project settings 207 | .ropeproject 208 | 209 | # mkdocs documentation 210 | /site 211 | 212 | # mypy 213 | .mypy_cache/ 214 | 215 | ### VisualStudioCode ### 216 | .vscode/* 217 | !.vscode/settings.json 218 | !.vscode/tasks.json 219 | !.vscode/launch.json 220 | !.vscode/extensions.json 221 | .history 222 | 223 | ### Windows ### 224 | # Windows thumbnail cache files 225 | Thumbs.db 226 | ehthumbs.db 227 | ehthumbs_vista.db 228 | 229 | # Folder config file 230 | Desktop.ini 231 | 232 | # Recycle Bin used on file shares 233 | $RECYCLE.BIN/ 234 | 235 | # Windows Installer files 236 | *.cab 237 | *.msi 238 | *.msm 239 | *.msp 240 | 241 | # Windows shortcuts 242 | *.lnk 243 | 244 | # Build folder 245 | 246 | */build/* 247 | 248 | # End of https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode 249 | 250 | 251 | -------------------------------------------------------------------------------- /patterns/single-bus-multi-account-pattern/blue-service-account/blue-service-app/template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: > 4 | Blue service app for for single bus, multi-account-pattern 5 | 6 | 7 | Globals: 8 | Function: 9 | Timeout: 3 10 | Handler: app.lambda_handler 11 | Runtime: python3.12 12 | 13 | 14 | Parameters: 15 | EventBusName: 16 | Description: Name of the blue service app event bus 17 | Type: String 18 | Default: blue-service-event-bus 19 | 20 | DevOpsEventBusArn: 21 | Description: The ARN of the devops event bus # e.g. arn:aws:events:us-east-1:[DEVOPS-ACCOUNT]:event-bus/devops-event-bus 22 | Type: String 23 | 24 | 25 | Resources: 26 | BlueServicePublisherE1: 27 | Type: AWS::Serverless::Function 28 | Properties: 29 | CodeUri: blue_p_e1/ 30 | Policies: 31 | - Version: '2012-10-17' 32 | Statement: 33 | - Effect: Allow 34 | Action: 35 | - events:PutEvents 36 | Resource: "*" 37 | Environment: 38 | Variables: 39 | DEVOPS_EVENT_BUS_ARN: !Ref DevOpsEventBusArn 40 | 41 | 42 | # Event bus for blue service. In single bus topology 43 | # this is the target for the devops event bus rule 44 | BlueServiceEventBus: 45 | Type: AWS::Events::EventBus 46 | Properties: 47 | Name: !Ref EventBusName 48 | 49 | BlueServiceSubscriberE2: 50 | Type: AWS::Serverless::Function 51 | Properties: 52 | CodeUri: blue_s_e2/ 53 | Events: 54 | BlueE2Rule: 55 | Type: EventBridgeRule 56 | Properties: 57 | EventBusName: !Ref BlueServiceEventBus 58 | Pattern: 59 | source: 60 | - com.exampleCorp.PurpleService 61 | detail-type: 62 | - Event2 63 | 64 | # Rule that is placed on the DevOps event bus for Event 2 65 | BlueServiceEvent2SubscriptionRule: 66 | Type: AWS::Events::Rule 67 | Properties: 68 | Name: BlueE2Subscription 69 | Description: Cross account rule created by Blue service for event 2 70 | EventBusName: !Ref DevOpsEventBusArn # ARN of the devops event bus 71 | EventPattern: 72 | source: 73 | - com.exampleCorp.PurpleService 74 | detail-type: 75 | - Event2 76 | State: ENABLED 77 | Targets: 78 | - Id: SendEvent2ToBlueServiceEventBus 79 | Arn: !GetAtt BlueServiceEventBus.Arn 80 | RoleArn: !GetAtt DevOpsEventBusToBlueServiceEventBusRole.Arn 81 | DeadLetterConfig: 82 | Arn: !GetAtt BlueServiceEventBusDlq.Arn 83 | 84 | # This IAM role allows EventBridge to assume the permissions necessary to send events 85 | # from the DevOps event bus to the Blue service event bus. No resource policy is required 86 | # on the Blue service event bus. 87 | DevOpsEventBusToBlueServiceEventBusRole: 88 | Type: 'AWS::IAM::Role' 89 | Properties: 90 | AssumeRolePolicyDocument: 91 | Version: 2012-10-17 92 | Statement: 93 | - Effect: Allow 94 | Principal: 95 | Service: 96 | - events.amazonaws.com 97 | Action: 98 | - 'sts:AssumeRole' 99 | Path: / 100 | Policies: 101 | - PolicyName: PutEventsOnBlueServiceEventBus 102 | PolicyDocument: 103 | Version: 2012-10-17 104 | Statement: 105 | - Effect: Allow 106 | Action: 'events:PutEvents' 107 | Resource: !GetAtt BlueServiceEventBus.Arn 108 | 109 | # Blue service event bus targe DLQ 110 | BlueServiceEventBusDlq: 111 | Type: AWS::SQS::Queue 112 | 113 | # SQS resource policy required to allow target on devops bus to send failed messages to target DLQ 114 | BlueServiceEventBusDlqPolicy: 115 | Type: AWS::SQS::QueuePolicy 116 | Properties: 117 | Queues: 118 | - !Ref BlueServiceEventBusDlq 119 | PolicyDocument: 120 | Statement: 121 | - Action: 122 | - "SQS:SendMessage" 123 | Effect: "Allow" 124 | Resource: !GetAtt BlueServiceEventBusDlq.Arn 125 | Principal: 126 | Service: "events.amazonaws.com" 127 | Condition: 128 | ArnEquals: 129 | "aws:SourceArn": !GetAtt BlueServiceEvent2SubscriptionRule.Arn 130 | 131 | Outputs: 132 | BlueServicePublisherE1: 133 | Description: Lambda function name for blue service publishing event 1 134 | Value: !Ref BlueServicePublisherE1 135 | BlueServiceSubscriberE2: 136 | Description: Lambda function name for purple service subscriber to event 2 137 | Value: !Ref BlueServiceSubscriberE2 138 | BlueServiceEventBusDlqUrl: 139 | Description: URL of the SQS Queue for rules DeadLetterConfig 140 | Value: !Ref BlueServiceEventBusDlq 141 | BlueServiceEventBusDlqArn: 142 | Description: ARN of the SQS Queue for rules DeadLetterConfig 143 | Value: !GetAtt BlueServiceEventBusDlq.Arn -------------------------------------------------------------------------------- /patterns/cross-region-cross-account-pattern/README.md: -------------------------------------------------------------------------------- 1 | # Cross-region event routing with Amazon EventBridge 2 | 3 | In this scenario, a company has their base of operations located in Asia Pacific (Singapore) with applications distributed across two additional Regions in US East (N. Virginia) and Europe (Frankfurt). The applications in US East (N. Virginia) and Europe (Frankfurt) are using Amazon EventBridge for their respective applications and services. The security team in Asia Pacific (Singapore) wishes to analyze events from the respective applications as well as receive AWS CloudTrail events for specific API calls made to specific operations to monitor infrastructure security. 4 | 5 | ![Cross-Region](../../docs/images/cross-region.png "Cross-Region") 6 | 7 | ## Setup 8 | 9 | This sample uses the Serverless Application Model Command Line Interface (AWS SAM CLI). To use the AWS SAM CLI, you need the following tools. 10 | 11 | * AWS SAM CLI - [Install the AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) 12 | * [Python 3 installed](https://www.python.org/downloads/) 13 | * Docker - [Install Docker community edition](https://hub.docker.com/search/?type=edition&offering=community) 14 | 15 | To run this demo you need to have to have access to three AWS accounts. The account numbers in the demo map to: 16 | 17 | * account_1 -> your first account number (used for the security event bus in region ap-southeast-1, and the default event bus in region us-east-1) 18 | * account_2 -> your second account number (used for the custom event bus in account 2) 19 | * account_3 -> your thirst account number (used for the custom event bus in account 3) 20 | 21 | Create AWS CLI Profiles for these accounts. For information on how to create named profiles visit 22 | 23 | Once you have the profiles created open the `Makefile` and replace the variables at the top of the file with your profile names 24 | 25 | ```Makefile 26 | # Add your profile names here 27 | PROFILE1 := "profile_for_account_1" 28 | PROFILE2 := "profile_for_account_2" 29 | PROFILE3 := "profile_for_account_3" 30 | ``` 31 | 32 | Optionally you can pass these as parameters as required, for example: 33 | 34 | ```bash 35 | make deploy-security-bus PROFILE1=default 36 | ``` 37 | 38 | ## Step 1. Deploy applications accounts 39 | 40 | The first step is to set up the event buses in the source "application" accounts. These are the accounts that will be publishing events to the security event bus in Singapore (ap-southeast-1). The following command will create an `AWS::Events::EventBusPolicy` on event buses in the three accounts. Remember to pass in the PROFILE names if you haven;t hard coded them into the make file. 41 | 42 | ```bash 43 | make deploy-source SECURITY_ACCOUNT_NO=[account number mapped to account_1] 44 | ``` 45 | 46 | **IMPORTANT:** Record the ARN numbers of the event buses that were just created in Account 2 (us-east-1) and 3 (eu-central-1), including the default event bus in Account 1 (us-east-1). 47 | 48 | ### Step 2. Deploy security event bus 49 | 50 | ```bash 51 | make deploy-security-bus PROFILE1="profile_for_account_1" 52 | ``` 53 | 54 | ### Step 3. Deploy the rules 55 | 56 | Because you cannot create AWS CloudFormation resources across Regions you need to define the rules in separate templates – this also gives the ability to easily expand to other regions. Once the template has been deployed to the cross-Region accounts, you can make use of the EventBridge resource policies to propagate rule definitions across account in the same Region. Note, the security account needs to have permission to create CloudFormation resources in the cross-Region accounts to deploy the rule templates. 57 | 58 | ![Cross-Region](../../docs/images/cross-region-rules.png "Cross-Region") 59 | 60 | ```bash 61 | make deploy-rules PROFILE1=[profile_for_account_1] PROFILE3=[profile_for_account_3] SECURITYEVENTBUSARN=[ARN] EVENTBUSARNACCOUNT1=[ARN] EVENTBUSARNACCOUNT2=[ARN] EVENTBUSARNACCOUNT3=[ARN] 62 | ``` 63 | 64 | ### Step 4. Test the rules 65 | 66 | Navigate to the applications/account_2 directory. Here you will find an events.json file which you will use as input for your put-events API call. Execute he following command using the AWS CLI. This will send messages to the event bus in us-east-1 which will be routed to the security event bus in Account 1 (ap-southeast-1). 67 | 68 | ```bash 69 | aws events put-events \ 70 | --region us-east-1 \ 71 | --profile [NAMED PROFILE FOR ACCOUNT 2] \ 72 | --entries file://events.json 73 | ``` 74 | 75 | If you have executed this successfully, you should see output like this: 76 | 77 | ```bash 78 | Entries: 79 | - EventId: a423b35e-3df0-e5dc-b854-db9c42144fa2 80 | - EventId: 5f22aea8-51ea-371f-7a5f-8300f1c93973 81 | - EventId: 7279fa46-11a6-7495-d7bb-436e391cfcab 82 | - EventId: b1e1ecc1-03f7-e3ef-9aa4-5ac3c8625cc7 83 | - EventId: b68cea94-28e2-bfb9-7b1f-9b2c5089f430 84 | - EventId: fc48a303-a1b2-bda8-8488-32daa5f809d8 85 | 86 | FailedEntryCount: 0 87 | ``` 88 | 89 | Next, open your AWS Console you used to deploy the security event bus. Navigate to AWS CloudWatch console you should see a collection of log entries with the events you just published Log Group for `/aws/events/SecurityAnalysisRule` --------------------------------------------------------------------------------