Skip to content

Instantly share code, notes, and snippets.

@carceneaux
Created March 21, 2019 15:07
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carceneaux/7a5ef7439a7dc514b8da61fe929df5ca to your computer and use it in GitHub Desktop.
Save carceneaux/7a5ef7439a7dc514b8da61fe929df5ca to your computer and use it in GitHub Desktop.
CloudFormation Template - API Gateway acting as Lambda Proxy with Custom Authorizer and CORS enabled.
---
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS CloudFormation deployment for Veeam Parameter Retrieval solution.
Resources:
# API Gateway Configuration
ApiGateway:
Type: AWS::ApiGateway::RestApi
Properties:
Name: !Sub ${AWS::StackName}-API
Description: !Sub API for the ${AWS::StackName} CloudFormation stack.
ApiKey:
Type: AWS::ApiGateway::ApiKey
Properties:
Name: !Sub ${AWS::StackName}-ApiKey
Description: CloudFormation API Key V1
Enabled: true
GenerateDistinctId: false
ApiUsagePlan:
Type: AWS::ApiGateway::UsagePlan
Properties:
ApiStages:
- ApiId: !Ref ApiGateway
Stage: !Ref ApiStage
Description: !Sub ${AWS::StackName} usage plan
Quota:
Limit: 2000
Period: MONTH
Throttle:
BurstLimit: 10
RateLimit: 10
UsagePlanName: !Sub ${AWS::StackName}-usage-plan
ApiUsagePlanKey:
Type: AWS::ApiGateway::UsagePlanKey
Properties:
KeyId: !Ref ApiKey
KeyType: API_KEY
UsagePlanId: !Ref ApiUsagePlan
ApiStage:
Type: AWS::ApiGateway::Stage
Properties:
DeploymentId: !Ref ApiDeployment
RestApiId: !Ref ApiGateway
StageName: veeam
ApiDeployment:
Type: AWS::ApiGateway::Deployment
DependsOn:
- ApiProxyResourceGET
Properties:
RestApiId: !Ref ApiGateway
ApiProxyResourceROOT:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref ApiGateway
ParentId: !GetAtt ApiGateway.RootResourceId
PathPart: parameter-store-retrieval
ApiProxyResourceGET:
Type: AWS::ApiGateway::Method
Properties:
RestApiId: !Ref ApiGateway
ResourceId: !Ref ApiProxyResourceROOT
HttpMethod: GET
ApiKeyRequired: true
AuthorizationType: CUSTOM
AuthorizerId: !Ref ApiAuthorizer
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaRetriever.Arn}/invocations
ApiProxyResourceOPTIONS:
Type: AWS::ApiGateway::Method
Properties:
RestApiId: !Ref ApiGateway
ResourceId: !Ref ApiProxyResourceROOT
HttpMethod: OPTIONS
AuthorizationType: NONE
Integration:
IntegrationResponses:
- StatusCode: '200'
ResponseParameters:
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,authorizationtoken'"
method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS'"
method.response.header.Access-Control-Allow-Origin: "'*'"
ResponseTemplates:
application/json: ''
PassthroughBehavior: WHEN_NO_MATCH
RequestTemplates:
application/json: '{"statusCode": 200}'
Type: MOCK
MethodResponses:
- StatusCode: '200'
ResponseModels:
application/json: 'Empty'
ResponseParameters:
method.response.header.Access-Control-Allow-Headers: false
method.response.header.Access-Control-Allow-Methods: false
method.response.header.Access-Control-Allow-Origin: false
ApiAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Name: !Sub ${AWS::StackName}-LambdaAuthorizer
RestApiId: !Ref ApiGateway
Type: REQUEST
AuthorizerUri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaAuthorizer.Arn}/invocations
AuthorizerResultTtlInSeconds: 0
IdentitySource: 'method.request.header.authorizationtoken, method.request.header.origin'
# Lambda Configuration
LambdaRetriever:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.7
Code:
S3Bucket: cf-test-sis
S3Key: cloudformation/lambda-parameter-retrieval.zip
Role: !GetAtt LambdaRetrieverIAMRole.Arn
Handler: lambda-parameter-retrieval.lambda_handler
FunctionName: !Sub ${AWS::StackName}-retriever
Description: Retrieves the specified SSM Parameter Store
MemorySize: 128
Timeout: 3
LambdaAuthorizer:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.7
Code:
S3Bucket: cf-test-sis
S3Key: cloudformation/lambda-authorizer-vcd-plugins.zip
Role: !GetAtt LambdaAuthorizerIAMRole.Arn
Handler: lambda-authorizer-vcd-plugins.lambda_handler
FunctionName: !Sub ${AWS::StackName}-authorizer
Description: API Gateway custom authorizer - Validates incoming source has required
permissions to make API request.
MemorySize: 256
Timeout: 5
# Permissions Configuration
LambdaRetrieverIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: !Sub ${AWS::StackName}-logs
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${AWS::StackName}-retriever:*
- PolicyName: !Sub ${AWS::StackName}-kms
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- kms:Decrypt
Resource:
- !Sub arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/alias/aws/ssm
- Effect: Allow
Action:
- ssm:GetParameter
Resource:
- !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/veeam/*
LambdaAuthorizerIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: !Sub ${AWS::StackName}-logs
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${AWS::StackName}-authorizer:*
ApiGatewayInvokeRetriever:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt LambdaRetriever.Arn
Principal: apigateway.amazonaws.com
SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGateway}/*/*/*
ApiGatewayInvokeAuhorizer:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt LambdaAuthorizer.Arn
Principal: apigateway.amazonaws.com
SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGateway}/*/*
ApiGatewayLogsIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- apigateway.amazonaws.com
Action:
- sts:AssumeRole
Path: /
Policies:
- PolicyName: AmazonAPIGatewayPushToCloudWatchLogs
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:DescribeLogGroups
- logs:DescribeLogStreams
- logs:PutLogEvents
- logs:GetLogEvents
- logs:FilterLogEvents
Resource: '*'
# API Gateway CloudWatch Logs Initial Configuration
ApiGatewayLogs:
Type: AWS::ApiGateway::Account
Properties:
CloudWatchRoleArn: !GetAtt ApiGatewayLogsIAMRole.Arn
Outputs:
ApiUrl:
Value:
!Join
- ''
- - 'https://'
- !Ref ApiGateway
- '.execute-api.'
- !Sub ${AWS::Region}
- '.amazonaws.com/veeam/parameter-store-retrieval'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment