Comment résoudre l'erreur de rôle IAM que je reçois dans Amazon Redshift lorsque j'utilise CloudFormation ?

Lecture de 7 minute(s)
0

Je souhaite créer un cluster Amazon Redshift ou une action planifiée dans AWS CloudFormation. Cependant, je reçois l’erreur de rôle AWS Identity and Access Management (IAM) « The IAM role must delegate access to an Amazon Redshift account » (Le rôle IAM doit déléguer l'accès à un compte Amazon Redshift).

Brève description

Lorsque vous essayez de créer un cluster Amazon Redshift ou une action planifiée dans CloudFormation, le message d'erreur suivant s'affiche :

« The IAM role is not valid. The IAM role must delegate access to an Amazon Redshift account. » (Le rôle IAM n'est pas valide. Le rôle IAM doit déléguer l'accès à un compte Amazon Redshift)

Pour résoudre ce problème, vous devez définir le rôle IAM dans les paramètres de votre modèle CloudFormation afin que le cluster puisse accéder à d'autres services AWS.

Résolution

Mettre à jour les paramètres de votre modèle CloudFormation en YAML

Pour mettre à jour les paramètres du modèle CloudFormation en YAML, procédez comme suit :

  1. Définissez vos paramètres pour créer une pile :

    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

    Remarque : Il est recommandé d'utiliser des références dynamiques dans votre modèle de pile. Pour plus d'informations sur les bonnes pratiques, consultez la section Bonnes pratiques en matière de sécurité pour CloudFormation.

  2. Utilisez le modèle suivant pour créer un rôle IAM qu'Amazon RedShift endossera lorsqu'il accède à d'autres services 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. Sous Politiques, spécifiez les politiques IAM à associer au rôle 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. Utilisez le modèle suivant avec la fonction Fn::GetAtt pour créer le cluster Amazon Redshift et incluez le 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 ""]

    Remarque : Une référence de rôle IAM incorrecte, telle que Ref, provoque une erreur.

Mettre à jour les paramètres de votre modèle CloudFormation au format JSON

Pour mettre à jour les paramètres du modèle CloudFormation au format JSON, procédez comme suit :

  1. Définissez vos paramètres pour créer une pile :

    {
      "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. Utilisez le modèle suivant pour créer le rôle IAM afin d'accéder à votre cluster 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. Sous Politiques, spécifiez les politiques IAM à associer au rôle 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. Utilisez le modèle suivant avec la fonction Fn::GetAtt pour créer le cluster Amazon Redshift et incluez le 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": ""
                }
              ]
            }
          }
        }
      }
    }

Créer une nouvelle pile dans CloudFormation

Après avoir mis à jour les paramètres du modèle, utilisez votre modèle JSON ou YAML pour créer une nouvelle pile CloudFormation.

Informations connexes

Référence de type de ressource Amazon Redshift

Extraits de modèles Amazon Redshift

Automatiser la création de clusters Amazon Redshift à l'aide d'AWS CloudFormation

AWS OFFICIEL
AWS OFFICIELA mis à jour il y a 2 mois