Skip to content

Commit 20020e5

Browse files
author
Aboushady
committed
Adding API Gateway HTTP EventBridge in Terraform
1 parent d286ede commit 20020e5

File tree

3 files changed

+297
-0
lines changed

3 files changed

+297
-0
lines changed
+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Amazon API Gateway HTTP API to Amazon EventBridge
2+
3+
This pattern creates an HTTP API endpoint that directly integrates with Amazon EventBridge
4+
5+
Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/apigateway-http-eventbridge-terraform
6+
7+
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example.
8+
9+
## Requirements
10+
11+
* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources.
12+
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured
13+
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
14+
* [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started) installed
15+
16+
## Deployment Instructions
17+
18+
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
19+
```
20+
git clone https://github.com/aws-samples/serverless-patterns
21+
```
22+
1. Change directory to the pattern directory:
23+
```
24+
cd serverless-patterns/apigw-http-eventbridge-terraform
25+
```
26+
1. From the command line, initialize terraform to to downloads and installs the providers defined in the configuration:
27+
```
28+
terraform init
29+
```
30+
1. From the command line, apply the configuration in the main.tf file:
31+
```
32+
terraform apply
33+
```
34+
1. During the prompts:
35+
* Enter yes
36+
1. Note the outputs from the deployment process. These contain the resource names and/or ARNs which are used for testing.
37+
38+
## How it works
39+
40+
This pattern creates an Amazon API gateway HTTP API endpoint. The endpoint uses service integrations to directly connect to Amazon EventBridge.
41+
42+
## Testing
43+
44+
To test the endpoint first send data using the following command. Be sure to update the endpoint with endpoint of your stack.
45+
46+
```
47+
curl --location --request POST '<your api endpoint>' --header 'Content-Type: application/json' \
48+
--data-raw '{
49+
"Detail":{
50+
"message": "Hello From API Gateway"
51+
}
52+
}'
53+
```
54+
55+
Then check the logs for the Lambda function from the Lambda console.
56+
57+
## Cleanup
58+
59+
1. Change directory to the pattern directory:
60+
```
61+
cd serverless-patterns/apigw-http-eventbridge-terraform
62+
```
63+
1. Delete all created resources
64+
```bash
65+
terraform destroy
66+
```
67+
1. During the prompts:
68+
* Enter yes
69+
1. Confirm all created resources has been deleted
70+
```bash
71+
terraform show
72+
```
73+
----
74+
Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
75+
76+
SPDX-License-Identifier: MIT-0
+211
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
terraform {
2+
required_providers {
3+
aws = {
4+
source = "hashicorp/aws"
5+
version = "~> 3.27"
6+
}
7+
}
8+
9+
required_version = ">= 0.14.9"
10+
}
11+
12+
provider "aws" {
13+
profile = "default"
14+
region = "us-east-1"
15+
}
16+
17+
data "aws_caller_identity" "current" {}
18+
19+
data "aws_region" "current" {}
20+
21+
# Create a zip file from the Lambda source code
22+
data "archive_file" "LambdaZipFile" {
23+
type = "zip"
24+
source_file = "${path.module}/src/LambdaFunction.py"
25+
output_path = "${path.module}/LambdaFunction.zip"
26+
}
27+
28+
# Create an IAM role for API Gateway
29+
resource "aws_iam_role" "APIGWRole" {
30+
assume_role_policy = <<POLICY1
31+
{
32+
"Version" : "2012-10-17",
33+
"Statement" : [
34+
{
35+
"Effect" : "Allow",
36+
"Principal" : {
37+
"Service" : "apigateway.amazonaws.com"
38+
},
39+
"Action" : "sts:AssumeRole"
40+
}
41+
]
42+
}
43+
POLICY1
44+
}
45+
46+
# Create an IAM policy for API Gateway to write to create an EventBridge event
47+
resource "aws_iam_policy" "APIGWPolicy" {
48+
policy = <<POLICY2
49+
{
50+
"Version" : "2012-10-17",
51+
"Statement" : [
52+
{
53+
"Effect" : "Allow",
54+
"Action" : [
55+
"events:PutEvents"
56+
],
57+
"Resource" : "arn:aws:events:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:event-bus/default"
58+
}
59+
]
60+
}
61+
POLICY2
62+
}
63+
64+
# Attach the IAM policies to the equivalent rule
65+
resource "aws_iam_role_policy_attachment" "APIGWPolicyAttachment" {
66+
role = aws_iam_role.APIGWRole.name
67+
policy_arn = aws_iam_policy.APIGWPolicy.arn
68+
}
69+
70+
# Create an IAM role for Lambda
71+
resource "aws_iam_role" "LambdaRole" {
72+
assume_role_policy = <<POLICY3
73+
{
74+
"Version" : "2012-10-17",
75+
"Statement" : [
76+
{
77+
"Effect" : "Allow",
78+
"Principal" : {
79+
"Service" : "lambda.amazonaws.com"
80+
},
81+
"Action" : "sts:AssumeRole"
82+
}
83+
]
84+
}
85+
POLICY3
86+
}
87+
88+
# Create an IAM policy for Lambda to push CloudWatch Logs
89+
resource "aws_iam_policy" "LambdaPolicy" {
90+
policy = <<POLICY4
91+
{
92+
"Version" : "2012-10-17",
93+
"Statement" : [
94+
{
95+
"Effect" : "Allow",
96+
"Action" : [
97+
"logs:CreateLogStream",
98+
"logs:PutLogEvents"
99+
],
100+
"Resource" : "arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:/aws/lambda/${aws_lambda_function.MyLambdaFunction.function_name}:*:*"
101+
}
102+
]
103+
}
104+
POLICY4
105+
}
106+
107+
# Attach the IAM policies to the equivalent rule
108+
resource "aws_iam_role_policy_attachment" "LambdaPolicyAttachment" {
109+
role = aws_iam_role.LambdaRole.name
110+
policy_arn = aws_iam_policy.LambdaPolicy.arn
111+
}
112+
113+
# Create an API Gateway HTTP with integration with EventBridge
114+
resource "aws_apigatewayv2_api" "MyApiGatewayHTTPApi" {
115+
name = "Terraform API Gateway HTTP API to EventBridge"
116+
protocol_type = "HTTP"
117+
body = jsonencode(
118+
{
119+
"openapi" : "3.0.1",
120+
"info" : {
121+
"title" : "API Gateway HTTP API to EventBridge"
122+
},
123+
"paths" : {
124+
"/" : {
125+
"post" : {
126+
"responses" : {
127+
"default" : {
128+
"description" : "EventBridge response"
129+
}
130+
},
131+
"x-amazon-apigateway-integration" : {
132+
"integrationSubtype" : "EventBridge-PutEvents",
133+
"credentials" : "${aws_iam_role.APIGWRole.arn}",
134+
"requestParameters" : {
135+
"Detail" : "$request.body.Detail",
136+
"DetailType" : "MyDetailType",
137+
"Source" : "demo.apigw"
138+
},
139+
"payloadFormatVersion" : "1.0",
140+
"type" : "aws_proxy",
141+
"connectionType" : "INTERNET"
142+
}
143+
}
144+
}
145+
}
146+
})
147+
}
148+
149+
# Create an API Gateway Stage with automatic deployment
150+
resource "aws_apigatewayv2_stage" "MyApiGatewayHTTPApiStage" {
151+
api_id = aws_apigatewayv2_api.MyApiGatewayHTTPApi.id
152+
name = "$default"
153+
auto_deploy = true
154+
}
155+
156+
# Create a new Event Rule
157+
resource "aws_cloudwatch_event_rule" "MyEventRule" {
158+
event_pattern = <<PATTERN
159+
{
160+
"account": ["${data.aws_caller_identity.current.account_id}"],
161+
"source": ["demo.apigw"]
162+
}
163+
PATTERN
164+
}
165+
166+
# Set the Lambda Function as a CloudWatch event target
167+
resource "aws_cloudwatch_event_target" "MyRuleTarget" {
168+
arn = aws_lambda_function.MyLambdaFunction.arn
169+
rule = aws_cloudwatch_event_rule.MyEventRule.id
170+
}
171+
172+
# Create a log group for the Lambda function with 60 days retention period
173+
resource "aws_cloudwatch_log_group" "MyLogGroup" {
174+
name = "/aws/lambda/${aws_lambda_function.MyLambdaFunction.function_name}"
175+
retention_in_days = 60
176+
}
177+
178+
# Create the Lambda function with the created Zip file of the source code
179+
resource "aws_lambda_function" "MyLambdaFunction" {
180+
function_name = "apigw-http-eventbridge-terraform-demo-${data.aws_caller_identity.current.account_id}"
181+
filename = data.archive_file.LambdaZipFile.output_path
182+
source_code_hash = filebase64sha256(data.archive_file.LambdaZipFile.output_path)
183+
role = aws_iam_role.LambdaRole.arn
184+
handler = "LambdaFunction.lambda_handler"
185+
runtime = "python3.9"
186+
layers = ["arn:aws:lambda:${data.aws_region.current.name}:017000801446:layer:AWSLambdaPowertoolsPython:15"]
187+
}
188+
189+
# Allow the EventBridge rule created to invoke the Lambda function
190+
resource "aws_lambda_permission" "EventBridgeLambdaPermission" {
191+
statement_id = "AllowExecutionFromCloudWatch"
192+
action = "lambda:InvokeFunction"
193+
function_name = aws_lambda_function.MyLambdaFunction.function_name
194+
principal = "events.amazonaws.com"
195+
source_arn = aws_cloudwatch_event_rule.MyEventRule.arn
196+
}
197+
198+
output "APIGW-URL" {
199+
value = aws_apigatewayv2_stage.MyApiGatewayHTTPApiStage.invoke_url
200+
description = "The API Gateway Invocation URL Queue URL"
201+
}
202+
203+
output "LambdaFunctionName" {
204+
value = aws_lambda_function.MyLambdaFunction.function_name
205+
description = "The Lambda Function name"
206+
}
207+
208+
output "CloudWatchLogName" {
209+
value = "/aws/lambda/${aws_lambda_function.MyLambdaFunction.function_name}"
210+
description = "The Lambda Function Log Group"
211+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: MIT-0
3+
4+
import json
5+
from aws_lambda_powertools import Logger
6+
7+
logger = Logger()
8+
9+
def lambda_handler(event, context):
10+
logger.info(f"Received event: {event}")

0 commit comments

Comments
 (0)