Skip to content

如何解決使用 CloudFormation 時,在 Amazon Redshift 中收到的 IAM 角色錯誤?

5 分的閱讀內容
0

我想在 AWS CloudFormation 中建立 Amazon Redshift 叢集或排程動作。但是,我收到「IAM 角色必須委派對 Amazon Redshift 帳戶的存取權」AWS Identity and Access Management (IAM) 角色錯誤。

簡短描述

當您嘗試在 CloudFormation 中建立 Amazon Redshift 叢集或排程動作時,您收到以下錯誤訊息:

「IAM 角色無效。IAM 角色必須將存取權委派給 Amazon Redshift 帳戶。」

若要解決此問題,您必須在 CloudFormation 範本參數中定義 IAM 角色,以便叢集可以存取其他 AWS 服務。

解決方案

以 YAML 格式更新 CloudFormation 範本參數

若要以 YAML 格式更新 CloudFormation 範本參數,請完成下列步驟:

  1. 定義參數以建立堆疊:

    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

    **注意:**最佳做法是在堆疊範本中使用動態參考。如需最佳做法的詳細資訊,請參閱 CloudFormation 的安全最佳做法

  2. 使用下列範本為 Amazon RedShift 建立 IAM 角色,以便在其存取其他 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. Policies (政策) 下,指定要附加到 IAM 角色的 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. 使用以下範本和 Fn::GetAtt 函數來建立 Amazon Redshift 叢集,並包含 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 ""]

    **注意:**不正確的 IAM 角色參考 (例如 Ref) 會導致錯誤。

以 JSON 格式更新 CloudFormation 範本參數

若要以 JSON 格式更新 CloudFormation 範本參數,請完成下列步驟:

  1. 定義參數以建立堆疊:

    {
      "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. 使用以下範本建立 IAM 角色,以存取您的 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. Policies (政策) 下,指定要附加到 IAM 角色的 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. 使用以下範本和 Fn::GetAtt 函數來建立 Amazon Redshift 叢集,並包含 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": ""
                }
              ]
            }
          }
        }
      }
    }

在 CloudFormation 中建立新堆疊

更新範本參數後,使用 JSON 或 YAML 範本建立新的 CloudFormation 堆疊

相關資訊

Amazon Redshift 資源類型參考

Amazon Redshift 範本片段

使用 AWS CloudFormation 自動建立 Amazon Redshift 叢集

AWS 官方已更新 4 個月前