Skip to content

Commit

Permalink
init. incomplete poc
Browse files Browse the repository at this point in the history
  • Loading branch information
rogerwelin committed Feb 10, 2020
0 parents commit 546f51e
Show file tree
Hide file tree
Showing 4 changed files with 283 additions and 0 deletions.
31 changes: 31 additions & 0 deletions main.go
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)
}
}
1 change: 1 addition & 0 deletions tmpl-readme.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package main
172 changes: 172 additions & 0 deletions tmpl-sam.go
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}/'
`
79 changes: 79 additions & 0 deletions tmpl-swagger.go
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"
`

0 comments on commit 546f51e

Please sign in to comment.