-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 546f51e
Showing
4 changed files
with
283 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
"text/template" | ||
) | ||
|
||
type TmplData struct { | ||
ApiProtocol string | ||
ApiEndpoints string | ||
LambdaFunctionName string | ||
ApiProjectName string | ||
} | ||
|
||
var allowedAPIProtocols = []string{"rest", "websocket"} | ||
var allowedRestAPIEndpoints = []string{"regional", "edge", "private"} | ||
|
||
func main() { | ||
apiTmpl := TmplData{ | ||
ApiProtocol: "rest", | ||
ApiEndpoints: "regional", | ||
LambdaFunctionName: "helloworld", | ||
ApiProjectName: "Hello-World-API", | ||
} | ||
|
||
t := template.Must(template.New("apigw").Parse(apiGWConf)) | ||
err := t.Execute(os.Stdout, apiTmpl) | ||
if err != nil { | ||
panic(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
package main | ||
|
||
const apiGWConf = ` | ||
--- | ||
AWSTemplateFormatVersion: '2010-09-09' | ||
Transform: AWS::Serverless-2016-10-31 | ||
{{ if and (eq .ApiEndpoints "private") }} | ||
Parameters: | ||
VPCId: | ||
Description: ID of the VPC ID | ||
Type: AWS::EC2::VPC::Id | ||
SubnetIDs: | ||
Description: A list/array of Subnet IDs | ||
Type: List<AWS::EC2::Subnet::Id> | ||
Environment: | ||
Description: name of the environment | ||
Type: String | ||
AllowedValues: [test, prod] | ||
{{ else }} | ||
Parameters: | ||
Environment: | ||
Description: name of the environment | ||
Type: String | ||
AllowedValues: [test, prod] | ||
{{ end}} | ||
Conditions: | ||
IsProd: | ||
!Equals [!Ref Environment, "prod"] | ||
Resources: | ||
{{ if and (eq .ApiEndpoints "private") }} | ||
######################## | ||
# Infra stuff | ||
######################## | ||
LambdaSecurityGroup: | ||
Type: AWS::EC2::SecurityGroup | ||
Properties: | ||
GroupDescription: SG for private lambfa functions | ||
GroupName: vpc-lambda | ||
VpcId: !Ref VPCId | ||
SecurityGroupIngress: | ||
- IpProtocol: tcp | ||
CidrIp: 172.31.190.0/24 | ||
FromPort: 0 | ||
ToPort: 65535 | ||
- IpProtocol: tcp | ||
CidrIp: 172.31.178.0/23 | ||
FromPort: 0 | ||
ToPort: 65535 | ||
- IpProtocol: tcp | ||
CidrIp: 10.168.58.0/24 | ||
FromPort: 0 | ||
ToPort: 65535 | ||
- IpProtocol: tcp | ||
CidrIp: 172.31.176.0/23 | ||
FromPort: 0 | ||
ToPort: 65535 | ||
ApiGwVpcEndpoint: | ||
Type: AWS::EC2::VPCEndpoint | ||
Properties: | ||
ServiceName: !Sub "com.amazonaws.${AWS::Region}.execute-api" | ||
PrivateDnsEnabled: true | ||
VpcEndpointType: Interface | ||
VpcId: !Ref VPCId | ||
SubnetIds: !Ref SubnetIDs | ||
{{ end }} | ||
######################## | ||
# API GW Conf | ||
######################## | ||
AnalyticsApi: | ||
Type: AWS::Serverless::Api | ||
Properties: | ||
StageName: !Ref Environment | ||
TracingEnabled: true # Enable X-Ray for distributed tracing to help debugging | ||
{{ if and (eq .ApiEndpoints "private")}}EndpointConfiguration: PRIVATE{{ end }}{{ if and (eq .ApiEndpoints "regional")}}EndpointConfiguration: REGIONAL{{ end }}{{ if and (eq .ApiEndpoints "edge")}}EndpointConfiguration: EDGE{{ end }} | ||
# Use DefinitionBody for swagger file so that we can use CloudFormation functions within the swagger file | ||
DefinitionBody: | ||
'Fn::Transform': | ||
Name: 'AWS::Include' | ||
Parameters: | ||
Location: ./swagger-api.yml | ||
MethodSettings: | ||
- ResourcePath: '/*' | ||
HttpMethod: '*' | ||
LoggingLevel: INFO | ||
MetricsEnabled: true # Enable detailed metrics | ||
DataTraceEnabled: true # Put logs into cloudwatch | ||
AccessLogSetting: | ||
DestinationArn: !Sub "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:${ApiAccessLogGroup}" | ||
Format: '$context.identity.sourceIp $context.authorizer.claims.sub [$context.requestTime] "$context.httpMethod $context.resourcePath $context.protocol" $context.status $context.requestId $context.awsEndpointRequestId $context.xrayTraceId $context.responseLatency $context.integrationLatency "$context.error.message"' | ||
Cors: | ||
AllowOrigin: "'*'" | ||
AllowHeaders: "'content-type'" | ||
######################## | ||
# IAM for API GW | ||
######################## | ||
# This role allows API Gateway to push execution and access logs to CloudWatch logs | ||
ApiGatewayPushToCloudWatchRole: | ||
Type: "AWS::IAM::Role" | ||
Properties: | ||
Description: "Push logs to CloudWatch logs from API Gateway" | ||
AssumeRolePolicyDocument: | ||
Version: "2012-10-17" | ||
Statement: | ||
- Effect: Allow | ||
Principal: | ||
Service: apigateway.amazonaws.com | ||
Action: "sts:AssumeRole" | ||
ManagedPolicyArns: | ||
- !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" | ||
ApiAccount: | ||
Type: "AWS::ApiGateway::Account" | ||
Properties: | ||
CloudWatchRoleArn: !GetAtt ApiGatewayPushToCloudWatchRole.Arn | ||
ApiAccessLogGroup: | ||
Type: AWS::Logs::LogGroup | ||
Properties: | ||
LogGroupName: !Sub "/aws/apigateway/AccessLog-${AnalyticsApi}" | ||
RetentionInDays: 365 | ||
######################## | ||
# Functions Goes Here | ||
######################## | ||
RecommendationsFunction: | ||
Type: AWS::Serverless::Function | ||
Properties: | ||
CodeUri: src/recommendations/app/ | ||
Handler: recommendations.lambda_handler | ||
Runtime: python3.7 | ||
MemorySize: 512 | ||
Timeout: 5 | ||
Tracing: Active | ||
Policies: | ||
- AWSLambdaExecute | ||
Layers: | ||
- !Ref RecommendationsLayer | ||
Events: | ||
AnyApi: | ||
Type: Api | ||
Properties: | ||
RestApiId: !Ref AnalyticsApi | ||
Path: '/recommendations/{userId}' | ||
Method: GET | ||
RecommendationsLayer: | ||
Type: AWS::Serverless::LayerVersion | ||
Properties: | ||
LayerName: recommendations-deps | ||
Description: Dependencies for RecommendationsFunction | ||
ContentUri: src/recommendations/dependencies/ | ||
CompatibleRuntimes: | ||
- python3.7 | ||
RetentionPolicy: Retain | ||
Outputs: | ||
ApiURL: | ||
Description: {{ .ApiProjectName }} | ||
Value: !Sub 'https://${AnalyticsApi}.execute-api.${AWS::Region}.amazonaws.com/${Environment}/' | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package main | ||
|
||
const swagger = ` | ||
--- | ||
openapi: "3.0.1" | ||
{{ if and (eq .apiEndpoints "private") }} | ||
x-amazon-apigateway-policy: | ||
Version: '2012-10-17' | ||
Statement: | ||
- Effect: Allow | ||
Principal: "*" | ||
Action: | ||
- "execute-api:Invoke" | ||
Resource: "execute-api:/*" | ||
Condition: | ||
StringEquals: | ||
aws:SourceVpc: | ||
Ref: VPCId | ||
{{ else }} | ||
{{ end }} | ||
info: | ||
title: {{ .apiProjectName }} | ||
description: your awesome description here | ||
version: "v1.0" | ||
servers: | ||
- url: https://apigw-url.example.com/prod | ||
description: Test environment URL | ||
- url: http://apigw-url.example.com/test | ||
description: Production environment URL | ||
paths: | ||
/v1/{{ .lambdaFunctionName }}/{userId}: | ||
get: | ||
summary: hello world endpoint | ||
description: outputs hello world | ||
parameters: | ||
- in: path | ||
name: userId | ||
schema: | ||
type: integer | ||
required: true | ||
responses: | ||
200: | ||
description: "OK" | ||
content: | ||
application/json: | ||
schema: | ||
type: array | ||
items: | ||
$ref: "#/components/schemas/ArticleObj" | ||
500: | ||
description: "Internal Server Error" | ||
content: {} | ||
x-amazon-apigateway-integration: | ||
uri: | ||
Fn::Sub: "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloWorldFunction.Arn}/invocations" | ||
httpMethod: POST | ||
passthroughBehavior: "when_no_match" | ||
type: aws_proxy | ||
components: | ||
schemas: | ||
ArticleObj: | ||
properties: | ||
rowValues: | ||
type: "array" | ||
items: | ||
type: "object" | ||
properties: | ||
modelId: | ||
type: "number" | ||
Article_Id: | ||
type: "string" | ||
MU_UOM_Cd: | ||
type: "string" | ||
rank: | ||
type: "number" | ||
` |