handlers/holiday-stop-api/cfn.yaml (406 lines of code) (raw):
AWSTemplateFormatVersion: "2010-09-09"
Description: CRUD API for Holiday Stop Requests (stored in SalesForce)
Parameters:
Stage:
Description: Stage name
Type: String
AllowedValues:
- PROD
- CODE
Default: CODE
Conditions:
CreateProdMonitoring: !Equals [ !Ref Stage, PROD ]
Mappings:
StageMap:
CODE:
ApiName: holiday-stop-api-CODE
FulfilmentDatesBucketUrn: "arn:aws:s3:::fulfilment-date-calculator-code/*"
DomainName: holiday-stop-api-code.support.guardianapis.com
PROD:
ApiName: holiday-stop-api-PROD
FulfilmentDatesBucketUrn: "arn:aws:s3:::fulfilment-date-calculator-prod/*"
DomainName: holiday-stop-api.support.guardianapis.com
Resources:
HolidayStopApiRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: /
Policies:
- PolicyName: LambdaPolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- lambda:InvokeFunction
Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/holiday-stop-api-${Stage}:log-stream:*"
- PolicyName: ReadPrivateCredentials
PolicyDocument:
Statement:
- Effect: Allow
Action: s3:GetObject
Resource: !Sub arn:aws:s3:::gu-reader-revenue-private/membership/support-service-lambdas/${Stage}/*
- PolicyName: FulfilmentDatesCalculatorBucket
PolicyDocument:
Statement:
- Effect: Allow
Action: s3:GetObject
Resource:
- !FindInMap [StageMap, !Ref Stage, FulfilmentDatesBucketUrn]
HolidayStopApi:
Type: "AWS::ApiGateway::RestApi"
Properties:
Description: manage-frontend (self-service MMA) uses to create/update/delete Holiday Stop Requests (stored in SalesForce)
Name: !FindInMap [StageMap, !Ref Stage, ApiName]
HolidayStopApiPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:invokeFunction
FunctionName: !Sub holiday-stop-api-${Stage}
Principal: apigateway.amazonaws.com
DependsOn: HolidayStopApiLambda
HolidayStopApiLambda:
Type: AWS::Lambda::Function
Properties:
Description: manage-frontend (self-service MMA) uses to create/update/delete Holiday Stop Requests (stored in SalesForce)
FunctionName:
!Sub holiday-stop-api-${Stage}
Code:
S3Bucket: support-service-lambdas-dist
S3Key: !Sub membership/${Stage}/holiday-stop-api/holiday-stop-api.jar
Handler: com.gu.holiday_stops.Handler::apply
Environment:
Variables:
Stage: !Ref Stage
Role:
Fn::GetAtt:
- HolidayStopApiRole
- Arn
MemorySize: 1536
Runtime: java21
Timeout: 300
Architectures:
- arm64
DependsOn:
- HolidayStopApiRole
HolidayStopApiUsagePlan:
Type: AWS::ApiGateway::UsagePlan
Properties:
UsagePlanName: holiday-stop-api
ApiStages:
- ApiId: !Ref HolidayStopApi
Stage: !Ref Stage
DependsOn:
- HolidayStopApi
- HolidayStopApiStage
HolidayStopApiKey:
Type: AWS::ApiGateway::ApiKey
Properties:
Description: Used by manage-frontend
Enabled: true
Name: !Sub holiday-stop-api-key-${Stage}
StageKeys:
- RestApiId: !Ref HolidayStopApi
StageName: !Ref Stage
DependsOn:
- HolidayStopApi
- HolidayStopApiStage
HolidayStopApiUsagePlanKey:
Type: AWS::ApiGateway::UsagePlanKey
Properties:
KeyId: !Ref HolidayStopApiKey
KeyType: API_KEY
UsagePlanId: !Ref HolidayStopApiUsagePlan
DependsOn:
- HolidayStopApiKey
- HolidayStopApiUsagePlan
HolidayStopApiPotentialProxyResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref HolidayStopApi
ParentId: !GetAtt [HolidayStopApi, RootResourceId]
PathPart: "potential"
DependsOn: HolidayStopApi
HolidayStopApiPotentialBySubscriptionNameProxyResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref HolidayStopApi
ParentId: !Ref HolidayStopApiPotentialProxyResource
PathPart: "{subscriptionName}"
DependsOn:
- HolidayStopApi
- HolidayStopApiPotentialProxyResource
HolidayStopApiPotentialBySubscriptionNameGetMethod:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
ApiKeyRequired: true
RestApiId: !Ref HolidayStopApi
ResourceId: !Ref HolidayStopApiPotentialBySubscriptionNameProxyResource
HttpMethod: GET
RequestParameters:
method.request.path.subscriptionName: true
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST # this for the interaction between API Gateway and Lambda and MUST be POST
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HolidayStopApiLambda.Arn}/invocations
DependsOn:
- HolidayStopApi
- HolidayStopApiLambda
- HolidayStopApiPotentialBySubscriptionNameProxyResource
HolidayStopApiGetAllAndCreateProxyResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref HolidayStopApi
ParentId: !GetAtt [HolidayStopApi, RootResourceId]
PathPart: "hsr"
DependsOn: HolidayStopApi
BulkHolidayStopApiCreateProxyResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref HolidayStopApi
ParentId: !GetAtt [HolidayStopApi, RootResourceId]
PathPart: "bulk-hsr"
DependsOn: HolidayStopApi
HolidayStopApiCreateMethod:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
ApiKeyRequired: true
RestApiId: !Ref HolidayStopApi
ResourceId: !Ref HolidayStopApiGetAllAndCreateProxyResource
HttpMethod: POST
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST # this for the interaction between API Gateway and Lambda and MUST be POST
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HolidayStopApiLambda.Arn}/invocations
DependsOn:
- HolidayStopApi
- HolidayStopApiLambda
- HolidayStopApiGetAllAndCreateProxyResource
BulkHolidayStopApiCreateMethod:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
ApiKeyRequired: true
RestApiId: !Ref HolidayStopApi
ResourceId: !Ref BulkHolidayStopApiCreateProxyResource
HttpMethod: POST
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST # this for the interaction between API Gateway and Lambda and MUST be POST
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HolidayStopApiLambda.Arn}/invocations
DependsOn:
- HolidayStopApi
- HolidayStopApiLambda
- BulkHolidayStopApiCreateProxyResource
HolidayStopApiBySubscriptionNameProxyResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref HolidayStopApi
ParentId: !Ref HolidayStopApiGetAllAndCreateProxyResource
PathPart: "{subscriptionName}"
DependsOn:
- HolidayStopApi
- HolidayStopApiGetAllAndCreateProxyResource
HolidayStopApiGetBySubscriptionNameMethod:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
ApiKeyRequired: true
RestApiId: !Ref HolidayStopApi
ResourceId: !Ref HolidayStopApiBySubscriptionNameProxyResource
HttpMethod: GET
RequestParameters:
method.request.path.subscriptionName: true
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST # this for the interaction between API Gateway and Lambda and MUST be POST
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HolidayStopApiLambda.Arn}/invocations
DependsOn:
- HolidayStopApi
- HolidayStopApiLambda
- HolidayStopApiBySubscriptionNameProxyResource
HolidayStopApiDeleteAndEditResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref HolidayStopApi
ParentId: !Ref HolidayStopApiBySubscriptionNameProxyResource
PathPart: "{holidayStopRequestId}"
DependsOn:
- HolidayStopApi
- HolidayStopApiBySubscriptionNameProxyResource
HolidayStopApiDeleteMethod:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
ApiKeyRequired: true
RestApiId: !Ref HolidayStopApi
ResourceId: !Ref HolidayStopApiDeleteAndEditResource
HttpMethod: DELETE
RequestParameters:
method.request.path.subscriptionName: true
method.request.path.holidayStopRequestId: true
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST # this for the interaction between API Gateway and Lambda and MUST be POST
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HolidayStopApiLambda.Arn}/invocations
DependsOn:
- HolidayStopApi
- HolidayStopApiLambda
- HolidayStopApiDeleteAndEditResource
HolidayStopApiCancelResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref HolidayStopApi
ParentId: !Ref HolidayStopApiBySubscriptionNameProxyResource
PathPart: "cancel"
DependsOn:
- HolidayStopApi
- HolidayStopApiBySubscriptionNameProxyResource
HolidayStopApiCancelPostMethod:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
ApiKeyRequired: true
RestApiId: !Ref HolidayStopApi
ResourceId: !Ref HolidayStopApiCancelResource
HttpMethod: POST
RequestParameters:
method.request.path.subscriptionName: true
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST # this for the interaction between API Gateway and Lambda and MUST be POST
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HolidayStopApiLambda.Arn}/invocations
DependsOn:
- HolidayStopApi
- HolidayStopApiLambda
- HolidayStopApiCancelResource
HolidayStopApiCancelGetMethod:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
ApiKeyRequired: true
RestApiId: !Ref HolidayStopApi
ResourceId: !Ref HolidayStopApiCancelResource
HttpMethod: GET
RequestParameters:
method.request.path.subscriptionName: true
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST # this for the interaction between API Gateway and Lambda and MUST be POST
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HolidayStopApiLambda.Arn}/invocations
DependsOn:
- HolidayStopApi
- HolidayStopApiLambda
- HolidayStopApiCancelResource
HolidayStopApiEditMethod:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
ApiKeyRequired: true
RestApiId: !Ref HolidayStopApi
ResourceId: !Ref HolidayStopApiDeleteAndEditResource
HttpMethod: PATCH
RequestParameters:
method.request.path.subscriptionName: true
method.request.path.holidayStopRequestId: true
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST # this for the interaction between API Gateway and Lambda and MUST be POST
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HolidayStopApiLambda.Arn}/invocations
DependsOn:
- HolidayStopApi
- HolidayStopApiLambda
- HolidayStopApiDeleteAndEditResource
HolidayStopApiStage:
Type: AWS::ApiGateway::Stage
Properties:
Description: Stage for holiday-stop-api
RestApiId: !Ref HolidayStopApi
DeploymentId: !Ref HolidayStopApiDeployment2
StageName: !Sub ${Stage}
DependsOn:
- HolidayStopApiPotentialBySubscriptionNameGetMethod
- HolidayStopApiGetBySubscriptionNameMethod
- HolidayStopApiCreateMethod
- BulkHolidayStopApiCreateMethod
- HolidayStopApiDeleteMethod
- HolidayStopApiEditMethod
- HolidayStopApiCancelPostMethod
- HolidayStopApiCancelGetMethod
# Bizarrely you have to update the deployment to include new endpoints in each stage
HolidayStopApiDeployment2:
Type: AWS::ApiGateway::Deployment
Properties:
Description: Deploys holiday-stop-api into an environment/stage
RestApiId: !Ref HolidayStopApi
DependsOn:
- HolidayStopApiPotentialBySubscriptionNameGetMethod
- HolidayStopApiGetBySubscriptionNameMethod
- HolidayStopApiCreateMethod
- BulkHolidayStopApiCreateMethod
- HolidayStopApiDeleteMethod
- HolidayStopApiEditMethod
- HolidayStopApiCancelPostMethod
5xxApiAlarm:
Type: AWS::CloudWatch::Alarm
Condition: CreateProdMonitoring
Properties:
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:alarms-handler-topic-PROD
AlarmName:
!Sub
- 5XX rate from ${ApiName}
- { ApiName: !FindInMap [StageMap, !Ref Stage, ApiName] }
AlarmDescription: Holiday stop API exceeded the allowed 5XX error rate
ComparisonOperator: GreaterThanThreshold
Dimensions:
- Name: ApiName
Value: !FindInMap [StageMap, !Ref Stage, ApiName]
- Name: Stage
Value: !Sub ${Stage}
EvaluationPeriods: 1
MetricName: 5XXError
Namespace: AWS/ApiGateway
Period: 3600
Statistic: Sum
Threshold: 5
TreatMissingData: notBreaching
HolidayStopApiDomainName:
Type: "AWS::ApiGateway::DomainName"
Properties:
RegionalCertificateArn: # only for *.support.guardianapis.com
!Sub arn:aws:acm:${AWS::Region}:${AWS::AccountId}:certificate/b384a6a0-2f54-4874-b99b-96eeff96c009
DomainName: !FindInMap [ StageMap, !Ref Stage, DomainName ]
EndpointConfiguration:
Types:
- REGIONAL
HolidayStopApiBasePathMapping:
Type: "AWS::ApiGateway::BasePathMapping"
Properties:
RestApiId: !Ref HolidayStopApi
DomainName: !Ref HolidayStopApiDomainName
Stage: !Sub ${Stage}
DependsOn:
- HolidayStopApi
- HolidayStopApiDomainName
- HolidayStopApiStage
HolidayStopApiDNSRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneName: support.guardianapis.com.
Name: !FindInMap [ StageMap, !Ref Stage, DomainName ]
Type: CNAME
TTL: '120'
ResourceRecords:
- !GetAtt HolidayStopApiDomainName.RegionalDomainName