AWS Cloudformation не может создать стек, если ресурс AWS :: Cognito :: IdentityPoolRoleAttachment имеет атрибут RoleMappings - PullRequest
0 голосов
/ 03 ноября 2018

Я пытаюсь создать свои когнитивные ресурсы с помощью облачной информации. Ниже шаблон работает просто отлично;

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?

1 Ответ

0 голосов
/ 17 апреля 2019

У меня такая же проблема, и, к сожалению, как я понял, RoleMappings еще не поддерживаются в CloudFormation, поэтому мы когда-нибудь обнаружим этот «Внутренний сбой». Но есть некоторые обходные пути, которые вы можете сделать, чтобы решить свою проблему. В моем случае я использовал библиотеку boto3 для вызова обновлений IdentityPool внутри лямбда-функции и использовал Severless Framework, но ту же самую цель можно было бы сделать с помощью SAM или другой платформы стека CloudFormation. Итак, я сделал эти шаги, используя 2 отдельных стека:

  1. Создать первый стек, включая все ваши ресурсы Cognito (UserPool, UserPoolClient, IdentityPool) и IamRoles, которые вы назначите им, и в разделе Выходы , Экспорт необходимые идентификаторы и ARN ваших ресурсов для использования в следующем стеке.

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. Создайте второй стек, включая лямбда-функцию, которая будет вызывать update_user_pool из boto3 библиотеки. Эта функция должна получить экспортированные значения первого стека и присоединить их к переменным среды , которые будут использоваться при вызове функции.

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 , для этого я использовал python3.6 , но могу использовать Node ( должен видеть документы boto3 для Node )

    <code>
    import boto3
    import os</p>
    
    <p>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']<br>
        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 , и затем ваши сопоставления ролей будут назначены вам IdentityPool, как вы пожелаете.

Надеюсь, это поможет вам! (Y)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...