Skip to content

Commit 091390f

Browse files
Add API Gateway-EventBridge examples (#1149)
* Add the TypeScript example * Add the Python example * Add API Gateway v1 example * Apply suggestions from code review Co-authored-by: Laura Santamaria <[email protected]>
1 parent ccfed98 commit 091390f

File tree

18 files changed

+794
-0
lines changed

18 files changed

+794
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.pyc
2+
venv/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: aws-py-apigatewayv2-eventbridge
2+
runtime:
3+
name: python
4+
options:
5+
virtualenv: venv
6+
description: An example that integrates API Gateway, EventBridge, and Lambda.
7+
template:
8+
config:
9+
aws:region:
10+
description: The AWS region to deploy into
11+
default: us-east-2
+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# API Gateway V2 to EventBridge
2+
3+
[![Deploy with Pulumi](https://get.pulumi.com/new/button.svg)](https://app.pulumi.com/new?template=https://github.com/pulumi/examples/tree/master/aws-py-apigatewayv2-eventbridge)
4+
5+
This example creates an AWS API Gateway proxy integration with EventBridge and Lambda. It defines a single API Gateway endpoint that publishes events to an EventBridge event bus and an accompanying event rule that matches those events and invokes a Lambda function.
6+
7+
## Prerequisites
8+
9+
1. [Install Pulumi](https://www.pulumi.com/docs/get-started/install/).
10+
1. [Install Python](https://www.pulumi.com/docs/intro/languages/python/).
11+
1. Configure your [AWS credentials](https://www.pulumi.com/docs/intro/cloud-providers/aws/setup/).
12+
13+
### Deploying the App
14+
15+
1. Clone this repo, change to this directory, then create a new [stack](https://www.pulumi.com/docs/intro/concepts/stack/) for the project:
16+
17+
```bash
18+
pulumi stack init
19+
```
20+
21+
1. Specify an AWS region to deploy into:
22+
23+
```bash
24+
pulumi config set aws:region us-west-2
25+
```
26+
27+
1. Install Python dependencies and run Pulumi:
28+
29+
```bash
30+
python3 -m venv venv
31+
source venv/bin/activate
32+
pip install -r requirements.txt
33+
34+
pulumi up
35+
```
36+
37+
1. In a few moments, the API Gateway instance service will be up and running and its public URL emitted as a Pulumi [stack output](https://www.pulumi.com/docs/intro/concepts/stack/#outputs).
38+
39+
```bash
40+
...
41+
Outputs:
42+
url: "https://andchh8hg8.execute-api.us-west-2.amazonaws.com/dev"
43+
```
44+
45+
1. Verify the deployment with `curl` and `pulumi logs`:
46+
47+
```bash
48+
curl --data '{"some-key": "some-value"}' --header "Content-Type: application/json" "$(pulumi stack output url)/uploads"
49+
50+
{"Entries":[{"EventId":"cdc44763-6976-286c-9378-7cce674dff81"}],"FailedEntryCount":0}
51+
```
52+
53+
```bash
54+
pulumi logs --follow
55+
56+
Collecting logs for stack dev since 2022-01-06T16:18:48.000-08:00.
57+
...
58+
59+
{
60+
source: 'my-event-source',
61+
detail: { 'some-key': 'some-value' }
62+
}
63+
```
64+
65+
1. When you're ready, destroy your stack and remove it:
66+
67+
```bash
68+
pulumi destroy --yes
69+
pulumi stack rm --yes
70+
```
+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Copyright 2016-2022, Pulumi Corporation. All rights reserved.
2+
3+
import json
4+
import pulumi
5+
import pulumi_aws as aws
6+
7+
# Create an HTTP API.
8+
api = aws.apigatewayv2.Api("example",
9+
protocol_type="HTTP"
10+
)
11+
12+
# Create a stage and set it to deploy automatically.
13+
stage = aws.apigatewayv2.Stage("stage",
14+
api_id=api.id,
15+
name=pulumi.get_stack(),
16+
auto_deploy=True
17+
)
18+
19+
# Create an event bus.
20+
bus = aws.cloudwatch.EventBus("bus")
21+
22+
# Create an event rule to watch for events.
23+
rule = aws.cloudwatch.EventRule("rule",
24+
event_bus_name=bus.name,
25+
event_pattern=json.dumps({"source": ["my-event-source"]})
26+
)
27+
28+
# Define a policy granting API Gateway permission to publish to EventBridge.
29+
api_gateway_role = aws.iam.Role("api-gateway-role",
30+
assume_role_policy=json.dumps({
31+
"Version": "2012-10-17",
32+
"Statement": [
33+
{
34+
"Action": "sts:AssumeRole",
35+
"Effect": "Allow",
36+
"Principal": {
37+
"Service": "apigateway.amazonaws.com",
38+
},
39+
},
40+
],
41+
}),
42+
managed_policy_arns=[
43+
"arn:aws:iam::aws:policy/AmazonEventBridgeFullAccess",
44+
],
45+
)
46+
47+
# Create an API Gateway integration to forward requests to EventBridge.
48+
integration = aws.apigatewayv2.Integration("integration",
49+
api_id=api.id,
50+
51+
# The integration type and subtype.
52+
integration_type="AWS_PROXY",
53+
integration_subtype="EventBridge-PutEvents",
54+
credentials_arn=api_gateway_role.arn,
55+
56+
# The body of the request to be sent to EventBridge. Note the
57+
# event source matches pattern defined on the EventRule, and the
58+
# Detail expression, which just forwards the body of the original
59+
# API Gateway request (i.e., the uploaded document).
60+
request_parameters={
61+
"EventBusName": bus.name.apply(lambda name: name),
62+
"Source": "my-event-source",
63+
"DetailType": "my-detail-type",
64+
"Detail": "$request.body",
65+
},
66+
)
67+
68+
# Finally, define the route.
69+
route = aws.apigatewayv2.Route("route",
70+
api_id=api.id,
71+
route_key="POST /uploads",
72+
target=integration.id.apply(lambda id: f"integrations/{id}"),
73+
)
74+
75+
# Define a role and policy allowing Lambda functions to log to CloudWatch.
76+
lambda_role = aws.iam.Role("lambda-role",
77+
assume_role_policy=json.dumps({
78+
"Version": "2012-10-17",
79+
"Statement": [
80+
{
81+
"Action": "sts:AssumeRole",
82+
"Principal": {
83+
"Service": "lambda.amazonaws.com"
84+
},
85+
"Effect": "Allow"
86+
}
87+
]
88+
})
89+
)
90+
lambda_role_policy = aws.iam.RolePolicy("lambda-role-policy",
91+
role=lambda_role.id,
92+
policy=json.dumps({
93+
"Version": "2012-10-17",
94+
"Statement": [{
95+
"Effect": "Allow",
96+
"Action": [
97+
"logs:CreateLogGroup",
98+
"logs:CreateLogStream",
99+
"logs:PutLogEvents"
100+
],
101+
"Resource": "arn:aws:logs:*:*:*"
102+
}]
103+
})
104+
)
105+
106+
# Create a Lambda function handler.
107+
lambda_function = aws.lambda_.Function("lambda",
108+
role=lambda_role.arn,
109+
runtime="python3.7",
110+
handler="handlers.capture_order",
111+
code=pulumi.AssetArchive({
112+
".": pulumi.FileArchive('./api')
113+
})
114+
)
115+
116+
# Create an EventBridge target associating the event rule with the function.
117+
lambda_target = aws.cloudwatch.EventTarget("lambda-target",
118+
arn=lambda_function.arn,
119+
rule=rule.name,
120+
event_bus_name=bus.name,
121+
)
122+
123+
# Give EventBridge permission to invoke the function.
124+
lambda_permission = aws.lambda_.Permission("lambda-permission",
125+
action="lambda:InvokeFunction",
126+
principal="events.amazonaws.com",
127+
function=lambda_function.arn,
128+
source_arn=rule.arn,
129+
)
130+
131+
# Export the API Gateway URL to give us something to POST to.
132+
pulumi.export("url", pulumi.Output.concat(api.api_endpoint, "/", stage.name))
133+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright 2016-2022, Pulumi Corporation. All rights reserved.
2+
3+
import json
4+
5+
def capture_order(event, context):
6+
# For now, just log the event, including the uploaded document.
7+
# That'll be enough to verify everything's working.
8+
print(json.dumps({"source": event["source"], "detail": event["detail"]}))
9+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pulumi>=3.0.0,<4.0.0
2+
pulumi-aws>=4.0.0,<5.0.0
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/bin/
2+
/node_modules/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
name: aws-ts-apigateway-eventbridge
2+
runtime: nodejs
3+
description: A minimal AWS TypeScript Pulumi program
+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# API Gateway V1 to EventBridge
2+
3+
[![Deploy with Pulumi](https://get.pulumi.com/new/button.svg)](https://app.pulumi.com/new?template=https://github.com/pulumi/examples/tree/master/aws-ts-apigateway-eventbridge)
4+
5+
This example demonstrates an API Gateway V1 integration with EventBridge and Lambda that also validates request bodies (using an API Gateway model) and returns a custom HTTP response.
6+
7+
## Prerequisites
8+
9+
1. [Install Pulumi](https://www.pulumi.com/docs/get-started/install/).
10+
1. [Install Node.js](https://www.pulumi.com/docs/intro/languages/javascript/).
11+
1. Configure your [AWS credentials](https://www.pulumi.com/docs/intro/cloud-providers/aws/setup/).
12+
13+
### Deploying the App
14+
15+
1. Clone this repo, change to this directory, then create a new [stack](https://www.pulumi.com/docs/intro/concepts/stack/) for the project:
16+
17+
```bash
18+
pulumi stack init
19+
```
20+
21+
1. Specify an AWS region to deploy into:
22+
23+
```bash
24+
pulumi config set aws:region us-west-2
25+
```
26+
27+
1. Install Node dependencies and run Pulumi:
28+
29+
```bash
30+
npm install
31+
pulumi up
32+
```
33+
34+
1. In a few moments, the API Gateway instance service will be up and running and its public URL emitted as a Pulumi [stack output](https://www.pulumi.com/docs/intro/concepts/stack/#outputs).
35+
36+
```bash
37+
...
38+
Outputs:
39+
url: "https://andchh8hg8.execute-api.us-west-2.amazonaws.com/dev"
40+
```
41+
42+
1. Verify the deployment with `curl`:
43+
44+
With invalid POST data:
45+
46+
```bash
47+
curl --data '{"some-invalid-property-name": "Chris"}' --header "Content-Type: application/json" "$(pulumi stack output url)/uploads"
48+
49+
HTTP/2 400
50+
{"message": "Invalid request body"}
51+
```
52+
53+
With valid POST data:
54+
55+
```bash
56+
curl --data '{"name": "Chris"}' --header "Content-Type: application/json" "$(pulumi stack output url)/uploads"
57+
58+
HTTP/2 201
59+
{"accepted":true}
60+
```
61+
62+
1. Verify the Lambda was invoked with `pulumi logs`:
63+
64+
```bash
65+
pulumi logs --follow
66+
67+
Collecting logs for stack dev since 2022-01-06T16:18:48.000-08:00.
68+
...
69+
70+
{
71+
source: 'my-event-source',
72+
detail: { 'name': 'Chris' }
73+
}
74+
```
75+
76+
1. When you're ready, destroy your stack and remove it:
77+
78+
```bash
79+
pulumi destroy --yes
80+
pulumi stack rm --yes
81+
```

0 commit comments

Comments
 (0)