Skip to content

Commit 5b1b42e

Browse files
Add Crosswalk API Gateway multi-language examples (pulumi#1122)
* Draft TS API Gateway example * Fix up example from testing * First draft of python API gateway example * Fix a bunch of python issues * Fix provider errors * Draft API Gateway Go example * Fix bugs found in testing * Add testing of Cognito token * Implement Cognito testing * Fix line break * Fix lint errors * Spike pure Go example * Fix go handler setup * Add copyright notices * Move go lambdas into own file - Remove unused TS import * Remove lambdas suffix * Draft API Key examples * Outline swagger route - Need to create lambda permission but depends on pulumi/pulumi-aws-apigateway#12 * Tidy up API Key examples * Simplify swagger route example - Remove need for manual lambda permission. * Fix comments * Add full-api swagger examples * Enable Typescript API Key example - Tested again pre-release of package. * Add TS custom domain * Draft Python and Go DNS setup * Final tweaks & formatting in line with docs changes - Add DNS testing to all READMEs * Fix TS lint errors * Upgrade to aws-apigateway v0.0.5 - Re-tested all examples work with fixed provider version. - Fix missing regional provider in python DNS setup. - Fix Go zone lookup and applies.
1 parent a24d02f commit 5b1b42e

31 files changed

+1897
-0
lines changed

aws-apigateway-go-routes/Makefile

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
all: build_authorizer build_handler
2+
3+
build_authorizer:
4+
GOOS=linux GOARCH=amd64 go build -o ./bin/authorizer ./authorizer/handler.go
5+
zip -j ./bin/authorizer.zip ./bin/authorizer
6+
7+
build_handler:
8+
GOOS=linux GOARCH=amd64 go build -o ./bin/handler ./handler/handler.go
9+
zip -j ./bin/handler.zip ./bin/handler

aws-apigateway-go-routes/Pulumi.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name: aws-apigateway-go-routes
2+
runtime: go
3+
description: Demonstration of API Gateway routes
4+
template:
5+
config:
6+
aws:region:
7+
description: The AWS region to deploy into
8+
default: us-east-2

aws-apigateway-go-routes/README.md

+178
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
[![Deploy](https://get.pulumi.com/new/button.svg)](https://app.pulumi.com/new)
2+
3+
# Routes in API Gateway
4+
5+
This example create an API Gateway which responds to requests using different sources:
6+
7+
1. Static files from a directory
8+
2. Lambda Function
9+
3. HTTP Proxy
10+
11+
When you're finished, you'll be familiar with how to configure routes in API Gateway using the RestAPI.
12+
13+
## Prerequisites
14+
15+
1. [Install Pulumi](https://www.pulumi.com/docs/get-started/install/)
16+
2. [Configure AWS Credentials](https://www.pulumi.com/docs/intro/cloud-providers/aws/setup/)
17+
3. [Install Go](https://www.pulumi.com/docs/intro/languages/go/)
18+
19+
## Deploy the App
20+
21+
### Step 1: Create a directory and cd into it
22+
23+
For Pulumi examples, we typically start by creating a directory and changing into it. Then, we create a new Pulumi project from a template. For example, `azure-javascript`.
24+
25+
1. Install prerequisites:
26+
27+
```bash
28+
go install
29+
```
30+
31+
2. Make Lambda handlers:
32+
33+
```bash
34+
make
35+
```
36+
37+
3. Create a new Pulumi stack:
38+
39+
```bash
40+
pulumi stack init
41+
```
42+
43+
4. Configure the AWS region to deploy into:
44+
45+
```bash
46+
pulumi config set aws:region us-east-2
47+
```
48+
49+
5. Deploy the Pulumi stack:
50+
51+
```bash
52+
pulumi up
53+
```
54+
55+
### Step 2: Test your API
56+
57+
Use the example CURL commands to test the API responses.
58+
59+
```bash
60+
$ curl -w '\n' "$(pulumi stack output url)static"
61+
<h1>Hello Pulumi!</h1>
62+
63+
$ curl -w '\n' "$(pulumi stack output url)lambda"
64+
Hello, API Gateway!
65+
66+
$ python3 -m webbrowser "$(pulumi stack output url)proxy"
67+
# Opens a page looking like Google in your browser
68+
69+
$ curl -w '\n' "$(pulumi stack output url)swagger"
70+
{
71+
"uuid": ...
72+
}
73+
74+
$ curl -w '\n' -H "Authorization: HEADER.PAYLOAD.SIGNATURE" "$(pulumi stack output url)cognito-authorized"
75+
{"message":"Unauthorized"}
76+
77+
$ curl -w '\n' -H "Authorization: goodToken" "$(pulumi stack output url)lambda-authorized"
78+
Hello, API Gateway!
79+
80+
$ curl -w '\n' -H "Authorization: badToken" "$(pulumi stack output url)lambda-authorized"
81+
{"message": "404 Not found" }
82+
83+
$ curl -w '\n' "$(pulumi stack output url)lambda-authorized" # No token
84+
{"message":"Unauthorized"}
85+
86+
$ curl -w '\n' "$(pulumi stack output swagger-url)"
87+
{
88+
"uuid": ...
89+
}
90+
91+
$ curl -w '\n' -H "x-api-key: $(pulumi stack output apiKeyValue --show-secrets)" "$(pulumi stack output url)key-authorized"
92+
Hello, API Gateway!
93+
```
94+
95+
Testing a valid Cognito token is a little more involved.
96+
97+
1. Create a random password
98+
99+
```bash
100+
PASSWORD=$(curl -s https://www.passwordrandom.com/query?command=password&scheme=Llnn%23rrrrrrrrrr)
101+
```
102+
103+
2. Create a user
104+
105+
```bash
106+
aws cognito-idp sign-up --region $(pulumi config get aws:region) --client-id $(pulumi stack output user-pool-client-id) --username "[email protected]" --password "$PASSWORD"
107+
```
108+
109+
3. Confirm the user's account
110+
111+
```bash
112+
aws cognito-idp admin-confirm-sign-up --region $(pulumi config get aws:region) --user-pool-id $(pulumi stack output user-pool-id) --username "[email protected]"
113+
```
114+
115+
4. Authenticate to create a new session:
116+
117+
```bash
118+
TOKEN=$(aws cognito-idp admin-initiate-auth --region $(pulumi config get aws:region) --user-pool-id $(pulumi stack output user-pool-id) --client-id $(pulumi stack output user-pool-client-id) --auth-flow ADMIN_NO_SRP_AUTH --auth-parameters "{\"USERNAME\":\"[email protected]\",\"PASSWORD\":\"$PASSWORD\"}")
119+
```
120+
121+
5. Perform authenticated request
122+
123+
```bash
124+
$ curl -w '\n' -H "Authorization: $(echo $TOKEN | jq '.AuthenticationResult.IdToken' -r)" "$(pulumi stack output url)cognito-authorized"
125+
Hello, API Gateway!
126+
```
127+
128+
Fetch and review the logs from the Lambda executions:
129+
130+
```bash
131+
pulumi logs
132+
```
133+
134+
### Set Up Custom DNS
135+
136+
Before you can set up a custom domain you must [register a domain name with Route 53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/registrar.html).
137+
138+
Configure the stack with your custom DNS information:
139+
140+
```bash
141+
pulumi config set domain subdomain.acmecorp.example
142+
pulumi config set dns-zone acmecorp.example
143+
```
144+
145+
Deploy your stack:
146+
147+
```bash
148+
$ pulumi up
149+
...
150+
Type Name Plan
151+
pulumi:pulumi:Stack aws-apigateway-ts-routes-dev
152+
+ ├─ pulumi:providers:aws usEast1 create
153+
+ ├─ aws:acm:Certificate ssl-cert create
154+
+ ├─ aws:route53:Record ssl-cert-validation-dns-record create
155+
+ ├─ aws:acm:CertificateValidation ssl-cert-validation create
156+
+ ├─ aws:apigateway:DomainName api-domain-name create
157+
+ ├─ aws:route53:Record api-dns create
158+
+ └─ aws:apigateway:BasePathMapping api-domain-mapping create
159+
```
160+
161+
Test your API is now available on your custom domain:
162+
163+
```bash
164+
curl -w '\n' "$(pulumi stack output customUrl)static"
165+
```
166+
167+
## Clean Up
168+
169+
Once you're finished experimenting, you can destroy your stack and remove it to avoid incurring any additional cost:
170+
171+
```bash
172+
pulumi destroy
173+
pulumi stack rm
174+
```
175+
176+
## Summary
177+
178+
In this tutorial, you deployed an API with different route configurations. Now you can use these patterns to build real APIs which connect to other services.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2016-2021, Pulumi Corporation.
2+
package main
3+
4+
import (
5+
"github.com/aws/aws-lambda-go/events"
6+
"github.com/aws/aws-lambda-go/lambda"
7+
)
8+
9+
func handler(request events.APIGatewayCustomAuthorizerRequestTypeRequest) (events.APIGatewayCustomAuthorizerResponse, error) {
10+
var effect string
11+
if request.Headers["Authorization"] == "goodToken" {
12+
effect = "Allow"
13+
} else {
14+
effect = "Deny"
15+
}
16+
return events.APIGatewayCustomAuthorizerResponse{
17+
PrincipalID: "my-user",
18+
PolicyDocument: events.APIGatewayCustomAuthorizerPolicy{
19+
Version: "2012-10-17",
20+
Statement: []events.IAMPolicyStatement{
21+
{
22+
Action: []string{"execute-api:Invoke"},
23+
Effect: effect,
24+
Resource: []string{request.MethodArn},
25+
},
26+
},
27+
},
28+
}, nil
29+
}
30+
31+
func main() {
32+
lambda.Start(handler)
33+
}

aws-apigateway-go-routes/dns.go

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright 2016-2021, Pulumi Corporation.
2+
package main
3+
4+
import (
5+
"github.com/pulumi/pulumi-aws/sdk/v4/go/aws"
6+
"github.com/pulumi/pulumi-aws/sdk/v4/go/aws/acm"
7+
"github.com/pulumi/pulumi-aws/sdk/v4/go/aws/apigateway"
8+
"github.com/pulumi/pulumi-aws/sdk/v4/go/aws/route53"
9+
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
10+
)
11+
12+
func configureDns(ctx *pulumi.Context, domain string, zoneId string) (*apigateway.DomainName, error) {
13+
// SSL Cert must be created in us-east-1 unrelated to where the API is deployed.
14+
awsUsEast1, err := aws.NewProvider(ctx, "aws-provider-us-east-1", &aws.ProviderArgs{Region: pulumi.String("us-east-1")})
15+
if err != nil {
16+
return nil, err
17+
}
18+
// Request ACM certificate
19+
sslCertificate, err := acm.NewCertificate(ctx,
20+
"ssl-cert",
21+
&acm.CertificateArgs{
22+
DomainName: pulumi.String(domain),
23+
ValidationMethod: pulumi.String("DNS"),
24+
},
25+
pulumi.Provider(awsUsEast1),
26+
)
27+
if err != nil {
28+
return nil, err
29+
}
30+
domainValidationOption := sslCertificate.DomainValidationOptions.ApplyT(func(options []acm.CertificateDomainValidationOption) interface{} {
31+
return options[0]
32+
})
33+
// Create DNS record to prove to ACM that we own the domain
34+
sslCertificateValidationDnsRecord, err := route53.NewRecord(ctx,
35+
"ssl-cert-validation-dns-record",
36+
&route53.RecordArgs{
37+
ZoneId: pulumi.String(zoneId),
38+
Name: domainValidationOption.ApplyT(func(option interface{}) string {
39+
return *option.(acm.CertificateDomainValidationOption).ResourceRecordName
40+
}).(pulumi.StringOutput),
41+
Type: domainValidationOption.ApplyT(func(option interface{}) string {
42+
return *option.(acm.CertificateDomainValidationOption).ResourceRecordType
43+
}).(pulumi.StringOutput),
44+
Records: pulumi.StringArray{
45+
domainValidationOption.ApplyT(func(option interface{}) string {
46+
return *option.(acm.CertificateDomainValidationOption).ResourceRecordValue
47+
}).(pulumi.StringOutput),
48+
},
49+
Ttl: pulumi.Int(10 * 60), // 10 minutes
50+
},
51+
)
52+
if err != nil {
53+
return nil, err
54+
}
55+
// Wait for the certificate validation to succeed
56+
validatedSslCertificate, err := acm.NewCertificateValidation(ctx,
57+
"ssl-cert-validation",
58+
&acm.CertificateValidationArgs{
59+
CertificateArn: sslCertificate.Arn,
60+
ValidationRecordFqdns: pulumi.StringArray{sslCertificateValidationDnsRecord.Fqdn},
61+
},
62+
pulumi.Provider(awsUsEast1),
63+
)
64+
if err != nil {
65+
return nil, err
66+
}
67+
// Configure API Gateway to be able to use domain name & certificate
68+
apiDomainName, err := apigateway.NewDomainName(ctx, "api-domain-name",
69+
&apigateway.DomainNameArgs{
70+
CertificateArn: validatedSslCertificate.CertificateArn,
71+
DomainName: pulumi.String(domain),
72+
},
73+
)
74+
if err != nil {
75+
return nil, err
76+
}
77+
// Create DNS record
78+
_, err = route53.NewRecord(ctx, "api-dns",
79+
&route53.RecordArgs{
80+
ZoneId: pulumi.String(zoneId),
81+
Type: pulumi.String("A"),
82+
Name: pulumi.String(domain),
83+
Aliases: route53.RecordAliasArray{
84+
route53.RecordAliasArgs{
85+
Name: apiDomainName.CloudfrontDomainName,
86+
EvaluateTargetHealth: pulumi.Bool(false),
87+
ZoneId: apiDomainName.CloudfrontZoneId,
88+
},
89+
},
90+
})
91+
if err != nil {
92+
return nil, err
93+
}
94+
return apiDomainName, nil
95+
}

aws-apigateway-go-routes/go.mod

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module github.com/pulumi/examples/aws-apigateway-go-routes
2+
3+
go 1.13
4+
5+
require (
6+
github.com/aws/aws-lambda-go v1.27.0
7+
github.com/pulumi/pulumi-aws-apigateway/sdk v0.0.5
8+
github.com/pulumi/pulumi-aws/sdk/v4 v4.30.0
9+
github.com/pulumi/pulumi/sdk/v3 v3.18.1
10+
)

0 commit comments

Comments
 (0)