Странное поведение с CloudFormation, обновляющим темы SNS - PullRequest
3 голосов
/ 20 февраля 2020

Извиняюсь за долгое чтение, но я включил только необходимые части. Я унаследовал некоторый код и сценарии CloudFormation для проекта, и предыдущий разработчик оставил крипт c примечание:

Вы должны обновить конечную дату для следующих элементов в app-deploy.cfn.yaml чтобы изменения вступили в силу.

Он давно ушел, и я нигде не могу спросить его о его инструкциях. Вот элементы, которые должны быть обновлены:

ApiDeployment20200214:
    Type: AWS::ApiGateway::Deployment
    Properties:
      RestApiId: !Ref NaasRestApi

RestApiStage:
    Type: AWS::ApiGateway::Stage
    Properties:
      DeploymentId: !Ref ApiDeployment20200214
      RestApiId: !Ref NaasRestApi
      StageName: !Sub ${Environment}

ApiBasePathMapping:
    Type: AWS::ApiGateway::BasePathMapping
    Condition: IsMainPipeline
    DependsOn: ApiDeployment20200214
    Properties:
      BasePath: ''
      DomainName: !Ref ApiGatewayDomainName
      RestApiId: !Ref NaasRestApi
      Stage: !Sub ${Environment}

Честно говоря, это кажется необычным. Похоже, он применяет методы кеширования к API-шлюзу. Это, насколько я знаю, никогда не должно было случиться.

Мальчик, я был неправ.

Недавно мне нужно было внести одно простое изменение в подписку SNS, добавив только - redirect в качестве источника для конкретной подписки Lambda. Вот этот ресурс с добавленным новым источником:

BHIEventLambdaSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      Endpoint: !GetAtt BHIEventLambdaFunction.Arn
      Protocol: lambda
      TopicArn: !Ref EventTopicArn
      FilterPolicy:
        domain:
          - payments
        source:
          - recycling
          - processor
          - paas
          - redirect
        type:
          - payment.approved
          - payment.declined
        brand_id:
          - '40'

Я развернул сценарии и стал свидетелем обновления. Я проверил консоль на правильность JSON, открыв это:

{
  "source": [
    "recycling",
    "processor",
    "paas",
    "redirect"
  ],
  "type": [
    "payment.approved",
    "payment.declined"
  ],
  "domain": [
    "payments"
  ],
  "brand_id": [
    "40"

Все хорошо! Я должен быть хорош для go, но когда я отправил соответствующее сообщение для проверки источника, я получил сообщение об ошибке:

@ message 2020-02-14 19:11:02 <071acec7- 096b-4c45-996a-5ed996df7c23> ОШИБКА AbstractEventHandler: 66 - java .lang.IllegalArgumentException: невозможно обработать сообщение, неверный формат.

И в моем пользовательском интерфейсе

{"message": "Invalid request body"}

Проверка журналов CloudWatch. Я вижу, как правильно выполняется запрос с этим источником:

@ message 2020-02-14 19:13:41 INFO BHIEventHandler: 23 - Обработчик BHI получен: {[{ sns: {messageAttributes: {domain = {тип: строка, значение: платежи}, source = {тип: строка, значение: перенаправление} , тип = {тип: строка, значение: payment.approved}, brand_id = {type: String, value: 40}}, ....


Внезапно я вспомнил сообщение crypti c от предыдущего разработчика, но я не мог понять, как это будет применяться для внесения изменений в SNS, тем более что это обновление, по-видимому, правильно развернуто в AWS. Другой разработчик, с которым я обсуждал это, сказал: «Вы можете просто доказать, что старый Брюс неправ, попробовав это, вам нечего терять в этой точке, и мы можем устранить это как отвлечение».

Мы go, мы меняем даты, назначенные / добавленные / помеченные для ресурсов API, и повторно внедряем. Я вижу обновления в консоли, CodePipeline сообщает, что развертывание успешно завершено. Мы отправляем тест ...

... и черт возьми сработало!

Мой вопрос

Почему внесение изменений в полностью (по-видимому) несвязанная часть CF сделать эту работу? Мы сделали что-то не так? Если да, то как мне исправить это?

По запросу

Вот полный шаблон:

Transform: AWS::Serverless-2016-10-31
Parameters:
  DeveloperPrefix:
    Type: String
    Default: ''
  AppName:
    Type: String
    Description: The application name
  Environment:
    Type: String
    Description: The environment name
  AppVersion:
    Type: String
    Description: The application version
  SharedBucketName:
    Type: String
    Description: Shared bucket name containing the deployable artifact
  WorkspacePrefix:
    Type: String
    Description: App workspace in shared bucket
  DeployPhase:
    Type: String
  CustomResourceLambdaS3Version:
    Type: String
    Description: The Custom Resource Lambda S3 version of the artifact
  S3Version:
    Type: String
    Description: The S3 Version
  HGEventLambdaS3Version:
    Type: String
    Description: The HG Event Lambda S3 version of the artifact
  HGEventRetryLambdaS3Version:
    Type: String
    Description: HG Event Retry Lambda S3 Version artifact
  SBEventLambdaS3Version:
    Type: String
    Description: The SB Event Lambda S3 version of the artifact
  SBEventRetryLambdaS3Version:
    Type: String
    Description: SB Event Retry Lambda S3 Version artifact
  BHEventLambdaS3Version:
    Type: String
    Description: The BH Event Lambda S3 version of the artifact
  BHEventRetryLambdaS3Version:
    Type: String
    Description: BH Event Retry Lambda S3 Version artifact
  BHIEventLambdaS3Version:
    Type: String
    Description: The BHI Event Lambda S3 version of the artifact
  BHIEventRetryLambdaS3Version:
    Type: String
    Description: BHI Event Retry Lambda S3 Version artifact
  AsoEventLambdaS3Version:
    Type: String
    Description: The ASO Event Lambda S3 version of the artifact
  AsoEventRetryLambdaS3Version:
    Type: String
    Description: ASO Event Retry Lambda S3 Version artifact
  CTEventLambdaS3Version:
    Type: String
    Description: The CT Event Lambda S3 version of the artifact
  CTEventRetryLambdaS3Version:
    Type: String
    Description: The CT Event Retry Lambda S3 Version artifact
  HZ:
    Type: String
    Description: The hosted zone in Route53
    Default: "notifications.svcs.example.com"
  CloudFrontHZ:
    Type: String
    Default: Z2FDTNDATAQYW2
  VPCStackName:
    Type: String
    Description: "The Stack containing the VPC you wish to attach the VPN to"

Mappings:
  EnvironmentMap:
    dev:
      EnvironmentName: 'dev.'
      CertificateId: ''
      HostedZoneId: ''
      VpcStackName: VPC-QA
    qa:
      EnvironmentName: 'qa.'
      CertificateId: 'xxxxxxxxxxxx'
      HostedZoneId: 'xxxxxxxxxxxx'
      VpcStackName: VPC-QA
    stage:
      EnvironmentName: 'stage.'
      CertificateId: 'xxxxxxxxxxxx'
      HostedZoneId: 'xxxxxxxxxxxx'
      VpcStackName: VPC-Stage
    prod:
      EnvironmentName: ''
      CertificateId: 'xxxxxxxxxxxx'
      HostedZoneId: 'xxxxxxxxxxxx'
      VpcStackName: VPC-Prod

Conditions:
  IsMainPipeline: !And
    - !Equals [ !Ref DeveloperPrefix, '' ]
    - !Equals [ !Ref DeployPhase, rel ]

Resources:
  #####################
  # HostedZone Config #
  #####################
  HostedZoneResource:
    Type: "AWS::CloudFormation::Stack"
    Condition: IsMainPipeline
    Properties:
      Parameters:
        DeveloperPrefix: !Ref DeveloperPrefix
        Environment: !Ref Environment
        DeployPhase: !Ref DeployPhase
      TemplateURL: !Sub "https://s3.amazonaws.com/${SharedBucketName}/${DeveloperPrefix}${AppName}/${Environment}/cf/nested/${S3Version}/hosted-zone.cfn.yaml"

  ####################
  # Lambda Resources #
  ####################
  CustomResource:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      Parameters:
        AppName: !Ref AppName
        Environment: !Ref Environment
        DeveloperPrefix: !Ref DeveloperPrefix
        DeployPhase: !Ref DeployPhase
        AppVersion: !Ref AppVersion
        SharedBucketName: !Ref SharedBucketName
        WorkspacePrefix: !Ref WorkspacePrefix
        CustomResourceLambdaS3Version: !Ref CustomResourceLambdaS3Version
        #VPCStackName: !Ref VPCStackName
        VPCStackName: !FindInMap
          - EnvironmentMap
          - !Ref Environment
          - VpcStackName
      TemplateURL: !Sub "https://s3.amazonaws.com/${SharedBucketName}/${DeveloperPrefix}${AppName}/${Environment}/cf/nested/${S3Version}/custom-resource.cfn.yaml"

  HGResources:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      Parameters:
        AppName: !Ref AppName
        Environment: !Ref Environment
        DeveloperPrefix: !Ref DeveloperPrefix
        DeployPhase: !Ref DeployPhase
        AppVersion: !Ref AppVersion
        SharedBucketName: !Ref SharedBucketName
        WorkspacePrefix: !Ref WorkspacePrefix
        HGEventLambdaS3Version: !Ref HGEventLambdaS3Version
        HGEventRetryLambdaS3Version: !Ref HGEventRetryLambdaS3Version
        EventTopicArn: !Ref EventTopic
        #VPCStackName: !Ref VPCStackName
        VPCStackName: !FindInMap
          - EnvironmentMap
          - !Ref Environment
          - VpcStackName
      TemplateURL: !Sub "https://s3.amazonaws.com/${SharedBucketName}/${DeveloperPrefix}${AppName}/${Environment}/cf/nested/${S3Version}/HG-subscriber.cfn.yaml"

  SBResources:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      Parameters:
        AppName: !Ref AppName
        Environment: !Ref Environment
        DeveloperPrefix: !Ref DeveloperPrefix
        DeployPhase: !Ref DeployPhase
        AppVersion: !Ref AppVersion
        SharedBucketName: !Ref SharedBucketName
        WorkspacePrefix: !Ref WorkspacePrefix
        SBEventLambdaS3Version: !Ref SBEventLambdaS3Version
        SBEventRetryLambdaS3Version: !Ref SBEventRetryLambdaS3Version
        EventTopicArn: !Ref EventTopic
        #VPCStackName: !Ref VPCStackName
        VPCStackName: !FindInMap
          - EnvironmentMap
          - !Ref Environment
          - VpcStackName
      TemplateURL: !Sub "https://s3.amazonaws.com/${SharedBucketName}/${DeveloperPrefix}${AppName}/${Environment}/cf/nested/${S3Version}/SB-subscriber.cfn.yaml"

  BHResources:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      Parameters:
        AppName: !Ref AppName
        Environment: !Ref Environment
        DeveloperPrefix: !Ref DeveloperPrefix
        DeployPhase: !Ref DeployPhase
        AppVersion: !Ref AppVersion
        SharedBucketName: !Ref SharedBucketName
        WorkspacePrefix: !Ref WorkspacePrefix
        BHEventLambdaS3Version: !Ref BHEventLambdaS3Version
        BHEventRetryLambdaS3Version: !Ref BHEventRetryLambdaS3Version
        EventTopicArn: !Ref EventTopic
        #VPCStackName: !Ref VPCStackName
        VPCStackName: !FindInMap
        - EnvironmentMap
        - !Ref Environment
        - VpcStackName
      TemplateURL: !Sub "https://s3.amazonaws.com/${SharedBucketName}/${DeveloperPrefix}${AppName}/${Environment}/cf/nested/${S3Version}/BH-subscriber.cfn.yaml"

  BHIResources:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      Parameters:
        AppName: !Ref AppName
        Environment: !Ref Environment
        DeveloperPrefix: !Ref DeveloperPrefix
        DeployPhase: !Ref DeployPhase
        AppVersion: !Ref AppVersion
        SharedBucketName: !Ref SharedBucketName
        WorkspacePrefix: !Ref WorkspacePrefix
        BHIEventLambdaS3Version: !Ref BHIEventLambdaS3Version
        BHIEventRetryLambdaS3Version: !Ref BHIEventRetryLambdaS3Version
        EventTopicArn: !Ref EventTopic
        #VPCStackName: !Ref VPCStackName
        VPCStackName: !FindInMap
          - EnvironmentMap
          - !Ref Environment
          - VpcStackName
      TemplateURL: !Sub "https://s3.amazonaws.com/${SharedBucketName}/${DeveloperPrefix}${AppName}/${Environment}/cf/nested/${S3Version}/BHI-subscriber.cfn.yaml"

  AsoResources:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      Parameters:
        AppName: !Ref AppName
        Environment: !Ref Environment
        DeveloperPrefix: !Ref DeveloperPrefix
        DeployPhase: !Ref DeployPhase
        AppVersion: !Ref AppVersion
        SharedBucketName: !Ref SharedBucketName
        WorkspacePrefix: !Ref WorkspacePrefix
        AsoEventLambdaS3Version: !Ref AsoEventLambdaS3Version
        AsoEventRetryLambdaS3Version: !Ref AsoEventRetryLambdaS3Version
        EventTopicArn: !Ref EventTopic
        #VPCStackName: !Ref VPCStackName
        VPCStackName: !FindInMap
        - EnvironmentMap
        - !Ref Environment
        - VpcStackName
      TemplateURL: !Sub "https://s3.amazonaws.com/${SharedBucketName}/${DeveloperPrefix}${AppName}/${Environment}/cf/nested/${S3Version}/aso-subscriber.cfn.yaml"

  CTResources:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      Parameters:
        AppName: !Ref AppName
        Environment: !Ref Environment
        DeveloperPrefix: !Ref DeveloperPrefix
        DeployPhase: !Ref DeployPhase
        AppVersion: !Ref AppVersion
        SharedBucketName: !Ref SharedBucketName
        WorkspacePrefix: !Ref WorkspacePrefix
        CTEventLambdaS3Version: !Ref CTEventLambdaS3Version
        CTEventRetryLambdaS3Version: !Ref CTEventRetryLambdaS3Version
        EventTopicArn: !Ref EventTopic
        #VPCStackName: !Ref VPCStackName
        VPCStackName: !FindInMap
          - EnvironmentMap
          - !Ref Environment
          - VpcStackName
      TemplateURL: !Sub "https://s3.amazonaws.com/${SharedBucketName}/${DeveloperPrefix}${AppName}/${Environment}/cf/nested/${S3Version}/CT-subscriber.cfn.yaml"

  #########################
  # API Gateway Resources #
  #########################
  ApiGatewayDomainName:
    Type: AWS::ApiGateway::DomainName
    Condition: IsMainPipeline
    Properties:
      CertificateArn: !Join ["", ['arn:aws:acm:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':certificate/', !FindInMap [ EnvironmentMap, !Ref Environment, CertificateId ] ] ]
      DomainName: !Join [ '', [ !FindInMap [ EnvironmentMap, !Ref Environment, EnvironmentName ], !Ref HZ ] ]

  ApiBasePathMapping:
    Type: AWS::ApiGateway::BasePathMapping
    Condition: IsMainPipeline
    DependsOn: ApiDeployment20200214
    Properties:
      BasePath: ''
      DomainName: !Ref ApiGatewayDomainName
      RestApiId: !Ref NaasRestApi
      Stage: !Sub ${Environment}

  ApiGatewayARecord:
    Type: AWS::Route53::RecordSetGroup
    Condition: IsMainPipeline
    Properties:
      HostedZoneId: !FindInMap [ EnvironmentMap, !Ref Environment, HostedZoneId ]
      RecordSets:
        - Type: A
          Name: !Join  [ "", [ !FindInMap [ EnvironmentMap, !Ref Environment, EnvironmentName ], !Ref HZ, "." ] ]
          AliasTarget:
            HostedZoneId: !Ref CloudFrontHZ
            DNSName: !GetAtt ApiGatewayDomainName.DistributionDomainName

  NaasRestApi:
    Type: AWS::ApiGateway::RestApi
    DependsOn: EventTopic
    Properties:
      Body:
        Fn::Transform:
          Name: 'AWS::Include'
          Parameters:
            Location: !Join ['/', [ 's3:/', !Ref SharedBucketName, !Ref WorkspacePrefix, 'naas.yaml' ]]

  RestApiStage:
    Type: AWS::ApiGateway::Stage
    Properties:
      DeploymentId: !Ref ApiDeployment20200214
      RestApiId: !Ref NaasRestApi
      StageName: !Sub ${Environment}

  ApiDeployment20200214:
    Type: AWS::ApiGateway::Deployment
    Properties:
      RestApiId: !Ref NaasRestApi

  TESTApiGatewayUsagePlan:
    Type: AWS::ApiGateway::UsagePlan
    DependsOn: RestApiStage
    Properties:
      UsagePlanName: !Sub TEST-${DeveloperPrefix}${AppName}-${Environment}-${DeployPhase}-UsagePlan
      Description: !Sub 'TEST-${DeveloperPrefix}${AppName}-${Environment}-${DeployPhase} Usage plan for Testing ONLY.'
      ApiStages:
        - ApiId: !Ref NaasRestApi
          Stage: !Sub ${Environment}
      Quota:
        Limit: 5000
        Offset: 0
        Period: DAY
      Throttle:
        BurstLimit: 150
        RateLimit: 100

  DefaultUsagePlan:
    Type: AWS::ApiGateway::UsagePlan
    Condition: IsMainPipeline
    DependsOn: RestApiStage
    Properties:
      UsagePlanName: !Sub ${DeveloperPrefix}${AppName}-${Environment}-Default-UsagePlan
      Description: !Sub '${DeveloperPrefix}${AppName}-${Environment} Default Usage plan for Brands'
      ApiStages:
        - ApiId: !Ref NaasRestApi
          Stage: !Sub ${Environment}
      Quota:
        Limit: 50000
        Offset: 0
        Period: DAY
      Throttle:
        BurstLimit: 1500
        RateLimit: 1000

  ApiGatewayNaasSNSRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${DeveloperPrefix}${AppName}-${Environment}-${DeployPhase}-ApiGatewayNaasSNSRole
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - apigateway.amazonaws.com
            Action: ['sts:AssumeRole']
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSNSFullAccess

  TESTApiKey:
    Type: AWS::ApiGateway::ApiKey
    DependsOn: RestApiStage
    Properties:
      Name: !Sub "TEST-${DeveloperPrefix}${Environment}-${DeployPhase}"
      Description: "TEST API Key"
      Enabled: true
      StageKeys:
        - RestApiId: !Ref NaasRestApi
          StageName: !Sub ${Environment}

  CTApiKey:
    Type: AWS::ApiGateway::ApiKey
    Condition: IsMainPipeline
    DependsOn: RestApiStage
    Properties:
      Name: !Sub "${DeveloperPrefix}CT-${Environment}"
      Description: !Sub "CT API Key"
      Enabled: true
      StageKeys:
        - RestApiId: !Ref NaasRestApi
          StageName: !Sub ${Environment}

  TESTUsagePlanKey:
    Type: AWS::ApiGateway::UsagePlanKey
    Properties:
      KeyId: !Ref TESTApiKey
      KeyType: API_KEY
      UsagePlanId: !Ref TESTApiGatewayUsagePlan

  CTUsagePlanKey:
    Type: AWS::ApiGateway::UsagePlanKey
    Condition: IsMainPipeline
    Properties:
      KeyId: !Ref CTApiKey
      KeyType: API_KEY
      UsagePlanId: !Ref DefaultUsagePlan

  ################################
  # Cognito User Pools Resources #
  ################################
  NaasUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: !Sub ${DeveloperPrefix}${AppName}-${Environment}-${DeployPhase}

  TESTUserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      ClientName: 'TEST Brand'
      GenerateSecret: true
      UserPoolId: !Ref NaasUserPool

  CTUserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Condition: IsMainPipeline
    Properties:
      ClientName: 'CT'
      GenerateSecret: true
      UserPoolId: !Ref NaasUserPool

  UserPoolResourceServer:
    Type: Custom::CognitoUserPoolResourceServer
    DependsOn:
      - NaasRestApi
      - CustomResource
    Properties:
      ServiceToken: !Sub ${CustomResource.Outputs.CustomResourceLambdaFunctionArn}
      RequestTypes:
        Create:
          Service: 'com.example.naas.lambda.cloudformation.service.CognitoService'
          Method: createResourceServer
          Model: 'com.amazonaws.services.cognitoidp.model.CreateResourceServerRequest'
          Parameters:
            userPoolId: !Ref NaasUserPool
            name: NaaS
            identifier: naas
            scopes:
              - scopeName: "fraud.publish"
                scopeDescription: "Fraud Decision Change Event"
        Delete:
          Service: 'com.example.naas.lambda.cloudformation.service.CognitoService'
          Method: deleteResourceServer
          Model: 'com.amazonaws.services.cognitoidp.model.DeleteResourceServerRequest'
          Parameters:
            userPoolId: !Ref NaasUserPool
            identifier: naas
        Update:
          Service: 'com.example.naas.lambda.cloudformation.service.CognitoService'
          Method: updateResourceServer
          Model: 'com.amazonaws.services.cognitoidp.model.UpdateResourceServerRequest'

  TESTBrandUserPoolClientSettings:
    Type: Custom::CognitoUserPoolClientSettings
    DependsOn: UserPoolResourceServer
    Properties:
      ServiceToken: !Sub ${CustomResource.Outputs.CustomResourceLambdaFunctionArn}
      RequestTypes:
        Create:
          Service: 'com.example.naas.lambda.cloudformation.service.CognitoService'
          Method: updateUserPoolClientSettings
          Model: 'com.amazonaws.services.cognitoidp.model.UpdateUserPoolClientRequest'
          Parameters:
            userPoolId: !Ref NaasUserPool
            clientId: !Ref TESTUserPoolClient
            allowedOAuthFlowsUserPoolClient: true
            explicitAuthFlows:
              - 'ADMIN_NO_SRP_AUTH'
            supportedIdentityProviders:
              - COGNITO
            allowedOAuthFlows:
              - client_credentials
            allowedOAuthScopes:
              - 'naas/fraud.publish'
        Delete:
          Service: 'com.example.naas.lambda.cloudformation.service.CognitoService'
          Method: deleteUserPoolClientSettings
          Model: 'com.amazonaws.services.cognitoidp.model.DeleteUserPoolClientRequest'
          Parameters:
            userPoolId: !Ref NaasUserPool
            clientId: !Ref TESTUserPoolClient
        Update:
          Service: 'com.example.naas.lambda.cloudformation.service.CognitoService'
          Method: updateUserPoolClientSettings
          Model: 'com.amazonaws.services.cognitoidp.model.UpdateUserPoolClientRequest'

  CTUserPoolClientSettings:
    Type: Custom::CognitoUserPoolClientSettings
    Condition: IsMainPipeline
    DependsOn: UserPoolResourceServer
    Properties:
      ServiceToken: !Sub ${CustomResource.Outputs.CustomResourceLambdaFunctionArn}
      RequestTypes:
        Create:
          Service: 'com.example.naas.lambda.cloudformation.service.CognitoService'
          Method: updateUserPoolClientSettings
          Model: 'com.amazonaws.services.cognitoidp.model.UpdateUserPoolClientRequest'
          Parameters:
            userPoolId: !Ref NaasUserPool
            clientId: !Ref CTUserPoolClient
            allowedOAuthFlowsUserPoolClient: true
            explicitAuthFlows:
              - 'ADMIN_NO_SRP_AUTH'
            supportedIdentityProviders:
              - COGNITO
            allowedOAuthFlows:
              - client_credentials
            allowedOAuthScopes:
              - 'naas/fraud.publish'
        Delete:
          Service: 'com.example.naas.lambda.cloudformation.service.CognitoService'
          Method: deleteUserPoolClientSettings
          Model: 'com.amazonaws.services.cognitoidp.model.DeleteUserPoolClientRequest'
          Parameters:
            userPoolId: !Ref NaasUserPool
            clientId: !Ref CTUserPoolClient
        Update:
          Service: 'com.example.naas.lambda.cloudformation.service.CognitoService'
          Method: updateUserPoolClientSettings
          Model: 'com.amazonaws.services.cognitoidp.model.UpdateUserPoolClientRequest'

  CognitoUserPoolDomain:
    Type: Custom::CreateCognitoUserPoolDomain
    DependsOn: CustomResource
    Properties:
      ServiceToken: !Sub ${CustomResource.Outputs.CustomResourceLambdaFunctionArn}
      RequestTypes:
        Create:
          Service: 'com.example.naas.lambda.cloudformation.service.CognitoService'
          Method: createUserPoolDomain
          Model: 'com.amazonaws.services.cognitoidp.model.CreateUserPoolDomainRequest'
          Parameters:
            domain: !Sub ${DeveloperPrefix}${AppName}-${Environment}-${DeployPhase}
            userPoolId: !Ref NaasUserPool
        Delete:
          Service: 'com.example.naas.lambda.cloudformation.service.CognitoService'
          Method: deleteUserPoolDomain
          Model: 'com.amazonaws.services.cognitoidp.model.DeleteUserPoolDomainRequest'
          Parameters:
            domain: !Sub ${DeveloperPrefix}${AppName}-${Environment}-${DeployPhase}
            userPoolId: !Ref NaasUserPool

  #################
  # SNS Resources #
  #################
  EventTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: !Sub '${DeveloperPrefix}event-${Environment}-${DeployPhase}'

  ##############################
  # Third-party Role Resources #
  ##############################
  SSMRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${DeveloperPrefix}3rdPartySSMRole-${Environment}
      AssumeRolePolicyDocument:
        Statement:
          - Sid: ''
            Effect: Allow
            Principal:
              AWS: arn:aws:iam::431055993173:root
            Action: sts:AssumeRole
            Condition:
              Bool:
                aws:MultiFactorAuthPresent: 'true'
      Path: /
      Policies:
        - PolicyName: !Sub 3rdPartySSMRole-${Environment}
          PolicyDocument:
            Statement:
              - Sid: SSMPermissions
                Effect: Allow
                Action:
                  - ssm:DescribeDocument
                  - ssm:GetDocument
                  - ssm:GetParameter
                  - ssm:GetParameters
                  - ssm:GetParametersByPath
                  - ssm:ListCommands
                  - ssm:ListDocuments
                  - ssm:CancelCommand
                  - ssm:PutParameter
                  - ssm:DeleteParameter
                  - ssm:SendCommand
                  - ssm:AddTagsToResource
                  - ssm:RemoveTagsFromResource
                Resource: !Join ['', ['arn:aws:ssm:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', 'parameter/', 'third-party', '/', !Ref Environment,'/', '*']]
              - Sid: SSMDescribePermissions
                Effect: Allow
                Action:
                  - ssm:DescribeParameters
                Resource: '*'
              - Sid: KMSPermissions
                Effect: Allow
                Action:
                  - kms:ListAliases
                Resource: '*'


Outputs:
  SSMRoleName:
    Value: !Ref SSMRole
  SSMRoleNameArn:
    Value: !GetAtt SSMRole.Arn
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...