AWS CloudFormation の使用時に Amazon Redshift で「IAM ロールは Amazon Redshift アカウントのアクセスを委任する必要があります」というエラーが表示されます。どうすれば解決できますか?

所要時間6分
0

AWS CloudFormation を使用して Amazon Redshift クラスターまたはスケジュールされたアクションを作成しようとしています。ただし、AWS Identity and Access Management (IAM) ロールエラーが発生します。どうすればこのエラーを解決できますか?

簡単な説明

AWS CloudFormation を使用すると、必要なすべての AWS リソースを説明するテンプレートを JSON または YAML で作成できます。その後、AWS CloudFormation で AWS リソースをプロビジョニングして設定します。AWS CloudFormation テンプレートを使用して、Amazon Redshift クラスターまたはスケジュールされたアクションを作成することもできます。

ただし、Amazon Redshift クラスターが他の AWS のサービスへのアクセスを許可する IAM ロールを正しく参照する必要があります。そうしないと、次のようなエラーが表示されます:

"The IAM role <role> is not valid. The IAM role must delegate access to an Amazon Redshift account."

この問題を解決するには、CloudFormation を使用して AWS IAM ロールを適切に作成し、アタッチします。CloudFormation テンプレートファイルが作成されると、Amazon Redshift クラスターおよび指定された AWS リソース(スタックなど)も自動的に作成されます。スタックに追加の (手動) 更新は必要ありません。

解決方法

AWS CloudFormation テンプレートパラメータを (YAML で) 更新する

YAML で AWS 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

注:機密情報を AWS CloudFormation テンプレートに埋め込むのではなく、スタックテンプレートで動的参照を使用するのがベストプラクティスです。ベストプラクティスの詳細については、「AWS CloudFormation のセキュリティのベストプラクティス」を参照してください。

2.    [リソース] で、他の AWS サービスにアクセスするために RedShift サービスが引き受ける IAM ロールを作成します。Resources: RedshiftRole: Type: AWS::IAM::Role Properties:

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.    Function Fn::GetAtt 関数を使用して Amazon Redshift クラスターを作成し、IAM ロール (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 ""]

Fn::GetAtt 関数は、指定された属性の値を返します。

**注記:**間違った形式の参照を使用して IAM ロール (Ref 関数など) にアタッチすると、IAM ロールエラーが発生します。

AWS CloudFormation テンプレートパラメータを (JSON で) 更新する

JSON で AWS 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"
      ]
    }
  },

:機密情報を AWS CloudFormation テンプレートに埋め込むのではなく、スタックテンプレートで動的参照を使用するのがベストプラクティスです。ベストプラクティスの詳細については、「AWS CloudFormation のセキュリティのベストプラクティス」を参照してください。

2.    [Resources (リソース)] で Amazon Redshift クラスターへのアクセスに使用する IAM ロールを作成します。

"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.    Function Fn::GetAtt 関数を使用して Amazon Redshift クラスターを作成し、IAM ロール (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": ""
            }
          ]
        }
      }
    }
  }
}

Fn::GetAtt 関数は、指定された属性の値を返します。

**注記:**間違った形式の参照を使用して IAM ロール (Ref 関数など) にアタッチすると、IAM ロールエラーが発生します。

AWS CloudFormation で新しいスタックを作成する

JSON または YAML テンプレートを使用してスタックを作成するには、次の手順で操作します。

1.    AWS CloudFormation コンソールを開きます。

2.    [Create stack (スタックを作成)] を選択して新しいスタックを作成します。

3.    ステップ 1 の [Prerequisite - Prepare template (前提条件 - テンプレートを準備する)] で [Prerequisite - Prepare template (テンプレートの準備ができました)] を選択します。

4.    ステップ 1 の [Specify template (テンプレートを指定)] の下でテンプレートソースを選択します。

5.    (オプション) テンプレートファイルをアップロードする必要がある場合は、テンプレートファイルをアップロードします。

6.    [次へ] を選択します。

7.    ステップ 2 の [Specify stack details (スタックの詳細を指定)] でスタック名パラメータを指定します。

8.    [次へ] を選択します。

9.    ステップ 3 の [Configure stack options (スタックオプションを設定する)] でスタックの詳細をすべて見直します。

10.    (オプション) スタックオプションを変更するには、更新するページが表示されるまで [Previous (前へ)] を選択します。必要に応じてスタックオプションを更新し、[Configure stack options (スタックオプションの設定)] ページに戻るまで [Next (次へ)] を選択します。

11.    [Create stack (スタックを作成)] を選択します。


関連情報

Amazon Redshift リソースタイプリファレンス

Amazon Redshift テンプレートスニペット

AWS CloudFormation を使用して Amazon Redshift クラスターの作成を自動化する

AWS公式
AWS公式更新しました 3年前
コメントはありません

関連するコンテンツ