Skip to content

Instantly share code, notes, and snippets.

@carceneaux
Created March 21, 2019 15:07
Show Gist options
  • Save carceneaux/7a5ef7439a7dc514b8da61fe929df5ca to your computer and use it in GitHub Desktop.
Save carceneaux/7a5ef7439a7dc514b8da61fe929df5ca to your computer and use it in GitHub Desktop.

Revisions

  1. Chris Arceneaux created this gist Mar 21, 2019.
    263 changes: 263 additions & 0 deletions cf-veeam-parameter-retrieval.yaml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,263 @@
    ---
    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'