Skip to content

¿Cómo soluciono el error de rol de IAM que se muestra en Amazon Redshift cuando uso CloudFormation?

7 minutos de lectura
0

Quiero crear un clúster de Amazon Redshift o una acción programada en AWS CloudFormation. Sin embargo, se muestra el error de rol de AWS Identity and Access Management (IAM) «El rol de IAM debe delegar el acceso a una cuenta de Amazon Redshift».

Descripción corta

Cuando intenta crear un clúster de Amazon Redshift o una acción programada en CloudFormation, se muestra el siguiente mensaje de error:

«El rol de IAM no es válido. El rol de IAM debe delegar el acceso a una cuenta de Amazon Redshift».

Para resolver este problema, debe definir el rol de IAM en los parámetros de la plantilla de CloudFormation para que el clúster pueda acceder a otros servicios de AWS.

Resolución

Actualización de los parámetros de la plantilla de CloudFormation en YAML

Para actualizar los parámetros de la plantilla de CloudFormation en YAML, siga estos pasos:

  1. Defina sus parámetros para crear una pila:

    AWSTemplateFormatVersion: 2010-09-09
    Description: Create Redshift Stack.
    Parameters:
      Environment:
        Description: Environment of the resources.
        Type: String
        Default: staging
        AllowedValues:
          - production
          - staging
          - testing
      Name:
        Description: Cluster name.
        Type: String
        Default: 'mycluster'
      Service:
        Description: Service name.
        Type: String
        Default: redshift
        AllowedValues:
          - redshift
      DatabaseName:
        Description:  Database name.
        Type: String
        Default: dev
        AllowedPattern: "([a-z]|[0-9])+"
      ClusterType:
        Description: The type of cluster
        Type: String
        Default: multi-node
        AllowedValues:
        - single-node
        - multi-node
      NumberOfNodes:
        Description: Compute nodes count. For multi-node clusters,
          the NumberOfNodes parameter must be greater than 1
        Type: Number
        Default: '2'
      NodeType:
        Description: The type of node to be provisioned
        Type: String
        Default: dc2.large
        AllowedValues:
        - dc2.large
        - dc2.8xlarge
        - ra3.4xlarge
        - ra3.16xlarge
      MasterUsername:
        Description: Master user name.
        Type: String
        Default: awsuser
        AllowedPattern: "([a-z])([a-z]|[0-9])*"
      MasterUserPassword:
        Description: Master user password. Must have a length of 8-64 characters, contain one uppercase letter, one lowercase letter, and one number. Also only contain printable ASCII characters except for '/', '@', '"', ' ', '\' and '\'.
        Type: String
        NoEcho: 'true'
      PortNumber:
        Description: The port number on which the cluster accepts incoming connections.
        Type: Number
        Default: '5439'
    Conditions:
      IsMultiNodeCluster:
        Fn::Equals:
        - Ref: ClusterType
        - multi-node

    Nota: Se recomienda utilizar referencias dinámicas en la plantilla de la pila. Para obtener más información sobre las prácticas recomendadas, consulte Prácticas recomendadas de seguridad para CloudFormation.

  2. Utilice la siguiente plantilla para crear un rol de IAM para que Amazon RedShift lo asuma cuando acceda a otros servicios de AWS:

    Resources:
      RedshiftRole:
        Type: AWS::IAM::Role
        Properties:
          RoleName: !Sub ${Environment}-${Name}-${Service}
          AssumeRolePolicyDocument:
            Version: '2012-10-17'
            Statement:
            - Effect: Allow
              Principal:
                Service:
                  - redshift.amazonaws.com
              Action:
                - sts:AssumeRole
              Condition:
                StringEquals:
                  sts:ExternalId: !Sub 'arn:aws:redshift:${AWS::Region}:${AWS::AccountId}:dbuser:${Environment}-${Name}-${Service}/awsuser'
          Path: "/"
  3. En Políticas, especifique las políticas de IAM que desea adjuntar al rol de IAM:

    Policies:  
      - PolicyName: policy-s3
        PolicyDocument:
        Version: 2012-10-17
        Statement:
        - Effect: Allow
        Action:
          - 's3:AbortMultipartUpload'
          - 's3:GetBucketLocation'
          - 's3:ListBucket'
          - 's3:ListBucketMultipartUploads'
          - 's3:GetObject'
          - 's3:PutObject'
        Resource:
          - !Sub "arn:aws:s3:::${Environment}-${Name}-tier1"
          - !Sub "arn:aws:s3:::${Environment}-${Name}-tier1/log-internal-${Service}/*"
          - !Sub "arn:aws:s3:::${Environment}-${Name}-tier2"
          - !Sub "arn:aws:s3:::${Environment}-${Name}-tier2/*"
        - Effect: Allow
        Action:
          - 's3:DeleteObject'
        Resource:
          - !Sub "arn:aws:s3:::${Environment}-${Name}-tier1/log-internal-${Service}/*"
          - !Sub "arn:aws:s3:::${Environment}-${Name}-tier2/*"
      - PolicyName: policy-cloudwatch
        PolicyDocument:
        Version: 2012-10-17
        Statement:
        - Effect: Allow
        Action:
          - 'logs:CreateLogGroup'
          - 'logs:CreateLogStream'
          - 'logs:PutLogEvents'
        Resource: "*"
  4. Utilice la siguiente plantilla con la función Fn::GetAtt para crear el clúster de Amazon Redshift e incluir el RedshiftRole:

    RedshiftCluster:
      Type: AWS::Redshift::Cluster
      Properties:
    
        IamRoles:
        - Fn::GetAtt: [ RedshiftRole, Arn ]
    
        AllowVersionUpgrade: true
        AutomatedSnapshotRetentionPeriod: 7
        ClusterIdentifier: !Sub ${Environment}-${Name}-${Service}
        ClusterVersion: 1.0
        ClusterType:
        Ref: ClusterType
        NumberOfNodes:
        Fn::If:
        - IsMultiNodeCluster
        - Ref: NumberOfNodes
        - Ref: AWS::NoValue
        NodeType:
        Ref: NodeType
        DBName:
        Ref: DatabaseName
        MasterUsername:
        Ref: MasterUsername
        MasterUserPassword:
        Ref: MasterUserPassword
        Port:
        Ref: PortNumber
        PreferredMaintenanceWindow: Sun:18:30-Sun:19:30
        PubliclyAccessible: yes
        AvailabilityZone: !Select [0, !GetAZs ""]

    Nota: Una referencia de rol de IAM incorrecta, como Ref, provoca un error.

Actualización de los parámetros de su plantilla de CloudFormation en JSON

Para actualizar los parámetros de la plantilla de CloudFormation en JSON, siga estos pasos:

  1. Defina sus parámetros para crear una pila:

    {
      "AWSTemplateFormatVersion": "2010-09-09",
      "Description": "Create Redshift Stack.",
      "Parameters": {
        "Environment": {
          "Description": "Environment of the resources.",
          "Type": "String",
          "Default": "staging",
          "AllowedValues": [
            "production",
            "staging",
            "testing"
          ]
        },
        "Name": {
          "Description": "Cluster name.",
          "Type": "String",
          "Default": "mycluster"
        },
        "Service": {
          "Description": "Service name.",
          "Type": "String",
          "Default": "redshift",
          "AllowedValues": [
            "redshift"
          ]
        },
        "DatabaseName": {
          "Description": "Database name.",
          "Type": "String",
          "Default": "dev",
          "AllowedPattern": "([a-z]|[0-9])+"
        },
        "ClusterType": {
          "Description": "The type of cluster",
          "Type": "String",
          "Default": "multi-node",
          "AllowedValues": [
            "single-node",
            "multi-node"
          ]
        },
        "NumberOfNodes": {
          "Description": "Compute nodes count. For multi-node clusters, the NumberOfNodes parameter must be greater than 1",
          "Type": "Number",
          "Default": "2"
        },
        "NodeType": {
          "Description": "The type of node to be provisioned",
          "Type": "String",
          "Default": "dc2.large",
          "AllowedValues": [
            "dc2.large",
            "dc2.8xlarge",
            "ra3.4xlarge",
            "ra3.16xlarge"
          ]
        },
        "MasterUsername": {
          "Description": "Master user name.",
          "Type": "String",
          "Default": "awsuser",
          "AllowedPattern": "([a-z])([a-z]|[0-9])*"
        },
        "MasterUserPassword": {
          "Description": "Master user password. Must have a length of 8-64 characters, contain one uppercase letter, one lowercase letter, and one number. Also only contain printable ASCII characters except for '/', '@', '\"', ' ', '\\' and '\\'.",
          "Type": "String",
          "NoEcho": "true"
        },
        "PortNumber": {
          "Description": "The port number on which the cluster accepts incoming connections.",
          "Type": "Number",
          "Default": "5439"
        }
      },
      "Conditions": {
        "IsMultiNodeCluster": {
          "Fn::Equals": [
            {
              "Ref": "ClusterType"
            },
            "multi-node"
          ]
        }
      },
  2. Utilice la siguiente plantilla para crear el rol de IAM para acceder a su clúster de Amazon Redshift:

    "Resources": {
        "RedshiftRole": {
          "Type": "AWS::IAM::Role",
          "Properties": {
            "RoleName": {
              "Fn::Sub": "${Environment}-${Name}-${Service}"
            },
            "AssumeRolePolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Effect": "Allow",
                  "Principal": {
                    "Service": [
                      "redshift.amazonaws.com"
                    ]
                  },
                  "Action": [
                    "sts:AssumeRole"
                  ],
                  "Condition": {
                    "StringEquals": {
                      "sts:ExternalId": {
                        "Fn::Sub": "arn:aws:redshift:${AWS::Region}:${AWS::AccountId}:dbuser:${Environment}-${Name}-${Service}/awsuser"
                      }
                    }
                  }
                }
              ]
            },
            "Path": "/",
  3. En Políticas, especifique las políticas de IAM que desea adjuntar al rol de IAM:

    "Policies": [
          {
          "PolicyName": "policy-s3",
          "PolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
            {
              "Effect": "Allow",
              "Action": [
              "s3:AbortMultipartUpload",
              "s3:GetBucketLocation",
              "s3:ListBucket",
              "s3:ListBucketMultipartUploads",
              "s3:GetObject",
              "s3:PutObject"
              ],
              "Resource": [
              {
                "Fn::Sub": "arn:aws:s3:::${Environment}-${Name}-tier1"
              },
              {
                "Fn::Sub": "arn:aws:s3:::${Environment}-${Name}-tier1/log-internal-${Service}/*"
              },
              {
                "Fn::Sub": "arn:aws:s3:::${Environment}-${Name}-tier2"
              },
              {
                "Fn::Sub": "arn:aws:s3:::${Environment}-${Name}-tier2/*"
              }
              ]
            },
            {
              "Effect": "Allow",
              "Action": [
              "s3:DeleteObject"
              ],
              "Resource": [
              {
                "Fn::Sub": "arn:aws:s3:::${Environment}-${Name}-tier1/log-internal-${Service}/*"
              },
              {
                "Fn::Sub": "arn:aws:s3:::${Environment}-${Name}-tier2/*"
              }
              ]
            }
            ]
          }
          },
          {
          "PolicyName": "policy-cloudwatch",
          "PolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
            {
              "Effect": "Allow",
              "Action": [
              "logs:CreateLogGroup",
              "logs:CreateLogStream",
              "logs:PutLogEvents"
              ],
              "Resource": "*"
            }
            ]
          }
          }
        ]
        }
      },
  4. Utilice la siguiente plantilla con la función Fn::GetAtt para crear el clúster de Amazon Redshift e incluir el RedshiftRole:

    "RedshiftCluster": {
          "Type": "AWS::Redshift::Cluster",
          "Properties": {
            "IamRoles": [
              {
                "Fn::GetAtt": [
                  "RedshiftRole",
                  "Arn"
                ]
              }
            ],
            "AllowVersionUpgrade": true,
            "AutomatedSnapshotRetentionPeriod": 7,
            "ClusterIdentifier": {
              "Fn::Sub": "${Environment}-${Name}-${Service}"
            },
            "ClusterVersion": 1,
            "ClusterType": {
              "Ref": "ClusterType"
            },
            "NumberOfNodes": {
              "Fn::If": [
                "IsMultiNodeCluster",
                {
                  "Ref": "NumberOfNodes"
                },
                {
                  "Ref": "AWS::NoValue"
                }
              ]
            },
            "NodeType": {
              "Ref": "NodeType"
            },
            "DBName": {
              "Ref": "DatabaseName"
            },
            "MasterUsername": {
              "Ref": "MasterUsername"
            },
            "MasterUserPassword": {
              "Ref": "MasterUserPassword"
            },
            "Port": {
              "Ref": "PortNumber"
            },
            "PreferredMaintenanceWindow": "Sun:18:30-Sun:19:30",
            "PubliclyAccessible": "true",
            "AvailabilityZone": {
              "Fn::Select": [
                0,
                {
                  "Fn::GetAZs": ""
                }
              ]
            }
          }
        }
      }
    }

Creación de una pila nueva en CloudFormation

Después de actualizar los parámetros de la plantilla, utilice su plantilla JSON o YAML para crear una nueva pila de CloudFormation.

Información relacionada

Referencia de tipos de recursos de Amazon Redshift

Fragmentos de plantillas de Amazon Redshift

Automatización de la creación de clústeres de Amazon Redshift con AWS CloudFormation

OFICIAL DE AWSActualizada hace 4 meses