handlers/identity-retention/cfn.yaml (214 lines of code) (raw):

AWSTemplateFormatVersion: "2010-09-09" Description: Performs a reader revenue check to determine whether an identity account should be retained Parameters: Stage: Description: Stage name Type: String AllowedValues: - PROD - CODE Default: CODE Conditions: CreateProdMonitoring: !Equals [ !Ref Stage, PROD ] Mappings: StageMap: CODE: ApiName: identity-retention-api-CODE DomainName: supporter-relationship-code.membership.guardianapis.com CertificateId: e4e6431e-08b9-4315-b997-75f2f9569d6c ApiGatewayTargetDomainName: d-zjtpjur7zj.execute-api.eu-west-1.amazonaws.com PROD: ApiName: identity-retention-api-PROD DomainName: supporter-relationship-prod.membership.guardianapis.com CertificateId: c1e85179-09e3-4222-adee-e4ee77e73304 ApiGatewayTargetDomainName: d-1lv8q5nggh.execute-api.eu-west-1.amazonaws.com Resources: IdentityRetentionRole: 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/identity-retention-${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}/bigQuery-${Stage}.*.json - !Sub arn:aws:s3:::gu-reader-revenue-private/membership/support-service-lambdas/${Stage}/trustedApi-${Stage}.*.json IdentityRetentionLambda: Type: AWS::Lambda::Function Properties: Description: Check whether an identity account is attached to an active billing account in Zuora FunctionName: !Sub identity-retention-${Stage} Code: S3Bucket: support-service-lambdas-dist S3Key: !Sub membership/${Stage}/identity-retention/identity-retention.jar Handler: com.gu.identityRetention.Handler::apply Environment: Variables: Stage: !Ref Stage Role: Fn::GetAtt: - "IdentityRetentionRole" - Arn MemorySize: 1536 Runtime: java21 Timeout: 300 Architectures: - arm64 DependsOn: - "IdentityRetentionRole" IdentityRetentionAPIPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:invokeFunction FunctionName: !Sub identity-retention-${Stage} Principal: apigateway.amazonaws.com DependsOn: IdentityRetentionLambda IdentityRetentionProxyResource: Type: AWS::ApiGateway::Resource Properties: RestApiId: !Ref IdentityRetentionAPI ParentId: !GetAtt [IdentityRetentionAPI, RootResourceId] PathPart: retention-status DependsOn: IdentityRetentionAPI IdentityRetentionMethod: Type: AWS::ApiGateway::Method Properties: AuthorizationType: NONE ApiKeyRequired: true RestApiId: !Ref IdentityRetentionAPI ResourceId: !Ref IdentityRetentionProxyResource HttpMethod: GET RequestParameters: method.request.querystring.identityId: 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/${IdentityRetentionLambda.Arn}/invocations DependsOn: - IdentityRetentionAPI - IdentityRetentionLambda - IdentityRetentionProxyResource IdentityRetentionAPI: Type: "AWS::ApiGateway::RestApi" Properties: Description: Identity call this API as part of a clean-up process for dormant identity accounts Name: !FindInMap [StageMap, !Ref Stage, ApiName] IdentityRetentionAPIStage: Type: AWS::ApiGateway::Stage Properties: Description: Stage for identity-retention-api RestApiId: !Ref IdentityRetentionAPI DeploymentId: !Ref IdentityRetentionAPIDeployment StageName: !Sub ${Stage} DependsOn: IdentityRetentionMethod IdentityRetentionAPIDeployment: Type: AWS::ApiGateway::Deployment Properties: Description: Deploys identity-retention-api into an environment/stage RestApiId: !Ref IdentityRetentionAPI DependsOn: IdentityRetentionMethod IdentityRetentionAPIKey: Type: AWS::ApiGateway::ApiKey Properties: Description: Key required to call identity retention API Enabled: true Name: !Sub identity-retention-api-key-${Stage} StageKeys: - RestApiId: !Ref IdentityRetentionAPI StageName: !Sub ${Stage} DependsOn: - IdentityRetentionAPI - IdentityRetentionAPIStage IdentityRetentionUsagePlan: Type: "AWS::ApiGateway::UsagePlan" Properties: UsagePlanName: !Sub identity-retention-api-usage-plan-${Stage} ApiStages: - ApiId: !Ref IdentityRetentionAPI Stage: !Ref IdentityRetentionAPIStage DependsOn: - IdentityRetentionAPI - IdentityRetentionAPIStage IdentityRetentionUsagePlanKey: Type: "AWS::ApiGateway::UsagePlanKey" Properties: KeyId: !Ref IdentityRetentionAPIKey KeyType: API_KEY UsagePlanId: !Ref IdentityRetentionUsagePlan DependsOn: - IdentityRetentionAPIKey - IdentityRetentionUsagePlan IdentityRetentionDomainName: Type: "AWS::ApiGateway::DomainName" Properties: RegionalCertificateArn: !Sub - arn:aws:acm:${AWS::Region}:${AWS::AccountId}:certificate/${CertificateId} - { CertificateId: !FindInMap [ StageMap, !Ref Stage, CertificateId ] } DomainName: !FindInMap [ StageMap, !Ref Stage, DomainName ] EndpointConfiguration: Types: - REGIONAL IdentityRetentionBasePathMapping: Type: "AWS::ApiGateway::BasePathMapping" Properties: RestApiId: !Ref IdentityRetentionAPI DomainName: !Ref IdentityRetentionDomainName Stage: !Sub ${Stage} DependsOn: - IdentityRetentionAPI - IdentityRetentionDomainName IdentityRetentionDNSRecord: Type: AWS::Route53::RecordSet Properties: HostedZoneName: membership.guardianapis.com. Name: !FindInMap [ StageMap, !Ref Stage, DomainName ] Comment: !Sub CNAME for identity-retention API ${Stage} Type: CNAME TTL: '120' ResourceRecords: - !FindInMap [ StageMap, !Ref Stage, ApiGatewayTargetDomainName ] 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] } 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: 10 TreatMissingData: notBreaching