【问题标题】:AWS Cloudformation can not create stack when AWS::Cognito::IdentityPoolRoleAttachment resource has RoleMappings attribute当 AWS::Cognito::IdentityPoolRoleAttachment 资源具有 RoleMappings 属性时,AWS Cloudformation 无法创建堆栈
【发布时间】:2019-04-07 10:26:13
【问题描述】:

我正在尝试通过 cloudformation 创建我的认知资源。下面的模板工作得很好;

AWSTemplateFormatVersion: 2010-09-09
Resources:
  CognitoAuthRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Federated: cognito-identity.amazonaws.com
            Action:
              - 'sts:AssumeRoleWithWebIdentity'
            Condition:
              StringEquals:
                'cognito-identity.amazonaws.com:aud':
                  Ref: CognitoIdentityPool
              'ForAnyValue:StringLike':
                'cognito-identity.amazonaws.com:amr': authenticated
  CognitoUserPool:
    Type: 'AWS::Cognito::UserPool'
    Properties:
      UsernameAttributes:
        - email
      AutoVerifiedAttributes:
        - email
  CognitoUserPoolClient:
    Type: 'AWS::Cognito::UserPoolClient'
    Properties:
      UserPoolId:
        Ref: CognitoUserPool
      ExplicitAuthFlows:
        - ADMIN_NO_SRP_AUTH
      GenerateSecret: false
  CognitoIdentityPool:
    Type: 'AWS::Cognito::IdentityPool'
    Properties:
      AllowUnauthenticatedIdentities: true
      CognitoIdentityProviders:
        - ClientId:
            Ref: CognitoUserPoolClient
          ProviderName:
            'Fn::GetAtt':
              - CognitoUserPool
              - ProviderName
  CognitoIdentityPoolRoles:
    Type: 'AWS::Cognito::IdentityPoolRoleAttachment'
    Properties:
      IdentityPoolId:
        Ref: CognitoIdentityPool
      Roles:
        authenticated:
          'Fn::GetAtt':
            - CognitoAuthRole
            - Arn

但是当我将 RoleMappings 属性添加到 CognitoIdentityPoolRoles 资源时,Cloudformation 返回错误并且无法创建堆栈。修改后的资源如下;

  CognitoIdentityPoolRoles:
    Type: 'AWS::Cognito::IdentityPoolRoleAttachment'
    Properties:
      IdentityPoolId:
        Ref: CognitoIdentityPool
      Roles:
        authenticated:
          'Fn::GetAtt':
            - CognitoAuthRole
            - Arn
      RoleMappings:
        AmbiguousRoleResolution: Deny
        Type: Rules
        RulesConfiguration:
          Rules:
            - Claim: 'custom:role'
              MatchType: Equals
              Value: viewer
              RoleARN:
                'Fn::GetAtt':
                  - CognitoAuthRole
                  - Arn
            - Claim: 'custom:role'
              MatchType: Equals
              Value: editor
              RoleARN:
                'Fn::GetAtt':
                  - CognitoAuthRole
                  - Arn

正如您在上面看到的 RoleMappings 类型是规则。您可以尝试使用 Token 参数,结果不会改变。

  CognitoIdentityPoolRoles:
    Type: 'AWS::Cognito::IdentityPoolRoleAttachment'
    Properties:
      IdentityPoolId:
        Ref: CognitoIdentityPool
      Roles:
        authenticated:
          'Fn::GetAtt':
            - CognitoAuthRole
            - Arn
      RoleMappings:
        AmbiguousRoleResolution: Deny
        Type: Token

不幸的是错误消息没有给出任何线索,我无法取得任何进展并卡在这个阶段。

Status  Type    Logical ID  Status Reason
CREATE_FAILED   AWS::Cognito::IdentityPoolRoleAttachment    CognitoIdentityPoolRoles    Internal Failure

如何使 IdentityPoolRoleAttachment 与 RoleMappings 工作?

【问题讨论】:

  • 我认为 RoleMappings 应该是 RoleMapping 对象映射的一组字符串。您刚刚提到了一个 RoleMapping 对象。在此处查看示例角色映射:forums.aws.amazon.com/message.jspa?messageID=790437#790437
  • 另外,看看关于动态映射的问题。也许您的问题与此有关
  • @Özgür İnce 你搞定了吗?

标签: amazon-web-services amazon-cloudformation amazon-cognito


【解决方案1】:

我遇到了同样的问题,不幸的是,我看到 CloudFormation 尚不支持 RoleMappings,因此我们将遇到此“内部故障”。 但是您可以采取一些变通方法来解决您的问题。在我的例子中,我使用 boto3 library 在 Lambda 函数 中调用 IdentityPool 更新,并且我使用了 Severless Framework,但同样的目的也可以用于SAM 或其他 CloudFormation 堆栈框架。 因此,我使用 2 个单独的堆栈完成了这些步骤:

  1. 创建第一个堆栈,包括您将分配的所有 Cognito 资源(UserPool、UserPoolClient、IdentityPool)和 IamRoles,并在 Outputs 部分,Export 必要的 IDs 和 ARNs 用于下一个堆栈的资源。

service: cognito-template

provider:
  name: aws
  stage: dev
  region: us-east-1
  stackName: cognito-template-${self:provider.stage}-resources

custom:
  system:
    name: myapp
    cognitoclientname: MyAppClient

resources:
  Resources:
    # ## ## ## ## ## ## ## ## ## ## ## ## ## Definicao de Usuários Cognito UserPool ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## # 
    UserPool:
      Type: AWS::Cognito::UserPool
      Properties:
        UserPoolName: ${self:custom.system.name}userpool
        AdminCreateUserConfig: 
          AllowAdminCreateUserOnly: True
          UnusedAccountValidityDays: 30
        EmailVerificationMessage: Clique no link abaixo para verificar seu endereço de e-mail. {####}
        EmailVerificationSubject: Seu link de verificação
        MfaConfiguration: OFF
        Policies: 
          PasswordPolicy:
            MinimumLength: 8
            RequireLowercase: false
            RequireNumbers: false
            RequireSymbols: false
            RequireUppercase: false
        Schema: 
          - AttributeDataType: String
            DeveloperOnlyAttribute: false
            Mutable: true
            Name: name
            Required: true
          - AttributeDataType: String
            DeveloperOnlyAttribute: false
            Mutable: true
            Name: family_name
            Required: true
          - AttributeDataType: String
            DeveloperOnlyAttribute: false
            Mutable: true
            Name: email
            Required: true
          - AttributeDataType: String
            DeveloperOnlyAttribute: false
            Mutable: true
            Name: phone_number
            Required: true
          - AttributeDataType: String
            DeveloperOnlyAttribute: false
            Mutable: true
            Name: gender
            Required: true
          - AttributeDataType: String
            DeveloperOnlyAttribute: false
            Mutable: true
            Name: permission
            Required: false
        UsernameAttributes: 
          - email
          - phone_number
    # ## ## ## ## ## ## ## ## ## ## ## ## ## Client Cognito ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## # 
    AppUserPoolClient:
      Type: AWS::Cognito::UserPoolClient
      Properties:
          ClientName: ${self:custom.system.cognitoclientname}
          ExplicitAuthFlows: 
            - ADMIN_NO_SRP_AUTH
            - USER_PASSWORD_AUTH
          GenerateSecret: false
          RefreshTokenValidity: 1
          UserPoolId: !Ref UserPool
    # ## ## ## ## ## ## ## ## ## ## ## ## ## Provedor de Identidade Cognito ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## # 
    AppIdentityPool:
      Type: AWS::Cognito::IdentityPool
      Properties:
        IdentityPoolName: ${self:custom.system.name}identitypool
        AllowUnauthenticatedIdentities: false
        CognitoIdentityProviders: 
          - ClientId: !Ref AppUserPoolClient
            ProviderName: !GetAtt UserPool.ProviderName
    AppIdentitiesRolesAttachment:
      Type: AWS::Cognito::IdentityPoolRoleAttachment
      DependsOn:
        - AppIdentityPool
        - CognitoAuthorizedRole
        - CognitoUnAuthorizedRole
      Properties:
        IdentityPoolId: !Ref AppIdentityPool
        Roles: 
          authenticated: !GetAtt CognitoAuthorizedRole.Arn
          unauthenticated: !GetAtt CognitoUnAuthorizedRole.Arn
    CognitoAuthorizedRole:
      Type: "AWS::IAM::Role"
      Properties:
        AssumeRolePolicyDocument: 
          Version: "2012-10-17"
          Statement:
            - Effect: "Allow"
              Principal: 
                Federated: "cognito-identity.amazonaws.com"
              Action: 
                - "sts:AssumeRoleWithWebIdentity"
              Condition:
                StringEquals: 
                  "cognito-identity.amazonaws.com:aud": !Ref AppIdentityPool
                "ForAnyValue:StringLike":
                  "cognito-identity.amazonaws.com:amr": authenticated
        Policies:
          - PolicyName: "CognitoAuthorizedPolicy"
            PolicyDocument: 
              Version: "2012-10-17"
              Statement: 
                - Effect: "Allow"
                  Action:
                    - "mobileanalytics:PutEvents"
                    - "cognito-sync:*"
                    - "cognito-identity:*"
                  Resource: "*"
                - Effect: "Allow"
                  Action:
                    - "lambda:InvokeFunction"
                  Resource: "*"
    CognitoUnAuthorizedRole:
      Type: "AWS::IAM::Role"
      Properties:
        AssumeRolePolicyDocument: 
          Version: "2012-10-17"
          Statement:
            - Effect: "Allow"
              Principal: 
                Federated: "cognito-identity.amazonaws.com"
              Action: 
                - "sts:AssumeRoleWithWebIdentity"
              Condition:
                StringEquals: 
                  "cognito-identity.amazonaws.com:aud": !Ref AppIdentityPool
                "ForAnyValue:StringLike":
                  "cognito-identity.amazonaws.com:amr": unauthenticated
        Policies:
          - PolicyName: "CognitoUnauthorizedPolicy"
            PolicyDocument: 
              Version: "2012-10-17"
              Statement: 
                - Effect: "Allow"
                  Action:
                    - "mobileanalytics:PutEvents"
                    - "cognito-sync:*"
                  Resource: "*"
    AdministradorRole:
      Type: "AWS::IAM::Role"
      Properties:
        AssumeRolePolicyDocument: 
          Version: "2012-10-17"
          Statement:
            - Effect: "Allow"
              Principal: 
                Federated: "cognito-identity.amazonaws.com"
              Action: 
                - "sts:AssumeRoleWithWebIdentity"
              Condition:
                StringEquals: 
                  "cognito-identity.amazonaws.com:aud": !Ref AppIdentityPool
                "ForAnyValue:StringLike":
                  "cognito-identity.amazonaws.com:amr": authenticated
        Policies:
          - PolicyName: "CognitoAdministradorPolicy"
            PolicyDocument: 
              Version: "2012-10-17"
              Statement: 
                - Effect: "Allow"
                  Action:
                    - "mobileanalytics:PutEvents"
                    - "cognito-sync:*"
                  Resource: "*"
    GerenciadorRole:
      Type: "AWS::IAM::Role"
      Properties:
        AssumeRolePolicyDocument: 
          Version: "2012-10-17"
          Statement:
            - Effect: "Allow"
              Principal: 
                Federated: "cognito-identity.amazonaws.com"
              Action: 
                - "sts:AssumeRoleWithWebIdentity"
              Condition:
                StringEquals: 
                  "cognito-identity.amazonaws.com:aud": !Ref AppIdentityPool
                "ForAnyValue:StringLike":
                  "cognito-identity.amazonaws.com:amr": authenticated
        Policies:
          - PolicyName: "CognitoAdministradorPolicy"
            PolicyDocument: 
              Version: "2012-10-17"
              Statement: 
                - Effect: "Allow"
                  Action:
                    - "mobileanalytics:PutEvents"
                    - "cognito-sync:*"
                  Resource: "*"
                - Effect: "Allow"
                  Action:
                    - "s3:GetObject"
                    - "s3:PutObject"
                  Resource: 
                    - "arn:aws:s3:::${self:custom.system.name}/public/*"
  # ## ## ## ## ## ## ## ## ## ## ## ## ## IAM Permission to lambda script execute update into IdentityPoolRoleMappings ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #                   
    MigrationScriptRole:
      Type: AWS::IAM::Role
      Properties:
        AssumeRolePolicyDocument: 
          Version: "2012-10-17"
          Statement:
            - Effect: "Allow"
              Principal: 
                Service: 
                  - lambda.amazonaws.com
              Action: 
                - "sts:AssumeRole"
        Policies:
          - PolicyName: "MigrationScriptPolicy"
            PolicyDocument: 
              Version: "2012-10-17"
              Statement: 
                - Effect: "Allow"
                  Action: 
                    - "cognito-idp:*"
                    - "cognito-identity:*"
                    - "iam:*"
                  Resource: "*"
  Outputs:
    UserPoolId:
      Value: !Ref UserPool
      Export:
        Name: "UserPool::Id"
    UserPoolArn:
      Value: !GetAtt UserPool.Arn
      Export:
        Name: "UserPool::Arn"
    UserPoolClientId:
      Value: !Ref AppUserPoolClient
      Export:
        Name: "AppUserPoolClient::Id"
    AppIdentityPoolId:
      Value: !Ref AppIdentityPool
      Export:
        Name: "AppIdentityPool::Id"
    AdministradorRoleArn:
      Value: !GetAtt AdministradorRole.Arn
      Export:
        Name: "AdministradorRole::Arn"
    GerenciadorRoleArn:
      Value: !GetAtt GerenciadorRole.Arn
      Export:
        Name: "GerenciadorRole::Arn"
    MigrationScriptRoleArn:
      Value: !GetAtt MigrationScriptRole.Arn
      Export:
        Name: "MigrationScriptRole::Arn"
  1. 创建第二个堆栈,包括将从 boto3 库调用 update_user_pool 的 lambda 函数。此函数必须接收第一个堆栈的导出值,并将它们附加到 环境变量,以便在函数调用时使用。

service: cognito-template

provider:
  name: aws
  stage: dev
  region: us-east-1
  stackName: cognito-template-${self:provider.stage}-functions

functions:
  migration-script:
    handler: lambda_function.handler
    runtime: python3.6
    role: 
      Fn::ImportValue: !Sub MigrationScriptRole::Arn
    environment:
      USER_POOL_REGION: us-east-1 # here you can change to you preferred region if you want
      USER_POOL_ID: 
        Fn::ImportValue: !Sub UserPool::Id
      USER_POOL_CLIENT_ID:
        Fn::ImportValue: !Sub AppUserPoolClient::Id
      IDENTITY_POOL_ID:
        Fn::ImportValue: !Sub AppIdentityPool::Id
      ADMINISTRADOR_ROLE_ARN:
        Fn::ImportValue: !Sub AdministradorRole::Arn
      GERENCIADOR_ROLE_ARN:
        Fn::ImportValue: !Sub GerenciadorRole::Arn
  1. 最后,通过 boto3 调用执行更新的 lambda 函数的代码,为此,我使用了 python3.6,但可以使用 节点(must see the boto3 docs for Node)

    
    import boto3
    import os
    
    

    def handler(event, context): setup_cognito() return event def setup_cognito(): define_cognito_attributes() create_cognito_identity_roles() def create_cognito_identity_roles(): user_pool_region = os.environ['USER_POOL_REGION'] user_pool_id = os.environ['USER_POOL_ID'] user_pool_client_id = os.environ['USER_POOL_CLIENT_ID'] identity_pool_id = os.environ['IDENTITY_POOL_ID']
    administrador_role = os.environ['ADMINISTRADOR_ROLE_ARN'] gerenciador_role = os.environ['GERENCIADOR_ROLE_ARN'] client_identity = boto3.client('cognito-identity') client_idp = boto3.client('cognito-idp') response = client_identity.get_identity_pool_roles(IdentityPoolId=identity_pool_id) identity_provider = "cognito-idp.{}.amazonaws.com/{}:{}".format(user_pool_region, user_pool_id, user_pool_client_id) options = { 'IdentityPoolId': response['IdentityPoolId'], 'Roles': response['Roles'], 'RoleMappings': { identity_provider: { 'Type': 'Rules', 'AmbiguousRoleResolution': 'AuthenticatedRole', 'RulesConfiguration': { 'Rules': [ { 'Claim': 'custom:permission', 'MatchType': 'Equals', 'Value': 'ADMNISTRADOR', 'RoleARN': administrador_role }, { 'Claim': 'custom:permission', 'MatchType': 'Equals', 'Value': 'GERENCIADOR', 'RoleARN': gerenciador_role } ] } } } } response = client_identity.set_identity_pool_roles(IdentityPoolId=options['IdentityPoolId'], Roles=options['Roles'], RoleMappings=options['RoleMappings']) def define_cognito_attributes(): user_pool_id = os.environ['USER_POOL_ID'] user_pool_client_id = os.environ['USER_POOL_CLIENT_ID'] client = boto3.client('cognito-idp') response = client.update_user_pool_client( UserPoolId=user_pool_id, ClientId=user_pool_client_id, WriteAttributes=[ 'custom:permission', 'phone_number', 'email', 'name', 'family_name', 'gender' ] )

创建后,可以通过 CLI 或 WEB 'Test'Button 调用 lambda 函数,然后您的角色映射将根据需要分配给您的 IdentityPool。

希望对你有帮助! (Y)

【讨论】:

  • 这是我使用规则的 RoleMappings 示例,您可以根据需要进行修改,使用规则或令牌,无论...
猜你喜欢
  • 2019-12-30
  • 2021-04-22
  • 2021-07-06
  • 2016-03-23
  • 2019-05-07
  • 2018-12-17
  • 2020-08-30
  • 2016-08-13
  • 2017-01-31
相关资源
最近更新 更多