Amazon Redshift Serverless インフラ構築を自動化するCloudFromationテンプレートの公開とその解説

2022.08.11

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

データアナリティクス事業本部コンサルティングチームの石川です。Redshift Serverlessのインフラ構築について、コードを用いた自動化や変更管理をしたいというニーズは少なくありません。本日は、インフラ構築を自動化するCloudFromationテンプレートの公開とその解説をします。

なお、マネジメントコンソールからRedshift Serverlessのインフラ構築する方法については、以下のブログをご覧ください。

CloudFromationで構築するリソースについて

Redshift Serverlessは、Workgroup(ワークグループ)とNamespace(名前空間)から構成され、CloudFromationのリソースもAWS::RedshiftServerless::WorkgroupAWS::RedshiftServerless::Namespace2つのリソースを作成することで、構築できます。

なお、CloudFromationのリソースであるWorkgroupは、Namespaceに対して依存関係があります。

  • Namespace(名前空間)
    • 関連付けられたデータベースリソース、スナップショット、暗号化キー、およびユーザー等を作成します。
  • ワークグループ
    • ワークロードの処理に使用できるネットワークやコンピューティング リソースを定義します。

CloudFromationの2つのリソースの詳細については、以下をご覧ください。

CloudFromationテンプレートサンプル

CloudFromationテンプレートの解説

今回のサンプルは、本番環境に向けた「設定をカスタマイズ」による環境構築手順とほぼ同様の環境を構築できるように作成しています。EnhancedVpcRouting(拡張VPCルーティング)やPubliclyAccessible(パブリックIPアドレスの付与)などは、スタックのパラメータとして任意の値に変更可能です。

変更点は、以下のとおりです。

  • BaseCapacityは、RPUのベースラインパフォーマンスを指定します。最初は小さなスケールから開始することを想定して、デフォルトの128から32に変更しました。
  • KmsKeyIdは、ストレージ暗号化のキーの指定です。何も指定しない場合は、AWS_OWNED_KMS_KEYですが、KMS KeyのIDを指定するように変更しています。私は、将来的なRedshift間データ共有を想定して、CMK(Customer Managed Key)の利用を推奨します。
  • WorkGroupのConfigParametersにて、search_path$userのみを指定しています。
  • 監査ログの出力などは、コメントにサンプルを記載しています。
  • Redshiftに付与するS3のIAMポリシーについては、要件に応じて調整してください。

CloudFromationテンプレート(redshift-serverless.yaml)

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  WorkgroupName: 
    Type: String
    Default: default-wg
  BaseCapacity: 
    Type: Number
    Default: 32
  EnhancedVpcRouting: 
    Type: String
    Default: false
  NamespaceName: 
    Type: String
    Default: default-ns
  PubliclyAccessible: 
    Type: String
    Default: false
  SecurityGroupIds: 
    Type: CommaDelimitedList
    Default: sg-abcd1234
  SubnetIds: 
    Type: CommaDelimitedList
    Default: subnet-aaaa1234,subnet-bbbb1234,subnet-cccc1234
  NamespaceName: 
    Type: String
    Default: default-ns
  AdminUsername:
    Type: String
    Default: awsuser
  AdminUserPassword:
    Type: String
    MinLength: 8
    MaxLength: 41
    AllowedPattern: "[a-zA-Z0-9]*"
    ConstraintDescription: must contain only alphanumeric characters.
  DbName: 
    Type: String
    Default: dev
  KmsKeyId: 
    Type: String
    Default: 11111111-2222-3333-4444-555555555555
#  LogExports: 
#    Type: CommaDelimitedList
#    Default: userlog,connectionlog,useractivitylog

Resources:
  RedshiftServerlessWorkGroup:
    Type: AWS::RedshiftServerless::Workgroup
    Properties: 
      WorkgroupName: !Ref WorkgroupName
      BaseCapacity: !Ref BaseCapacity
      EnhancedVpcRouting: !Ref EnhancedVpcRouting
      NamespaceName: !Ref RedshiftServerlessNamespace
      PubliclyAccessible: !Ref PubliclyAccessible
      SecurityGroupIds: !Ref SecurityGroupIds
      SubnetIds: !Ref SubnetIds
      ConfigParameters: 
        - ParameterKey: "search_path"
          ParameterValue: "$user"
#        - ParameterKey: "enable_user_activity_logging"
#          ParameterValue: "true"
#        - ParameterKey: "datestyle"
#          ParameterValue: "ISO,MDY"
#        - ParameterKey: "query_group"
#          ParameterValue: "adhoc"
#        - ParameterKey: "max_query_execution_time"
#          ParameterValue: "3600"
  RedshiftServerlessNamespace:
    Type: AWS::RedshiftServerless::Namespace
    Properties: 
      NamespaceName: !Ref NamespaceName
      AdminUsername: !Ref AdminUsername
      AdminUserPassword: !Ref AdminUserPassword
      KmsKeyId: !Ref KmsKeyId
      DbName: !Ref DbName
      IamRoles: 
      - Fn::GetAtt:
        - RedshiftServerlessRole
        - Arn
#      LogExports: !Ref LogExports

  RedshiftServerlessRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "AmazonRedshiftServerlessRole-${NamespaceName}"
      Path: "/"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: 
                - redshift-serverless.amazonaws.com
                - redshift.amazonaws.com
                - sagemaker.amazonaws.com
            Action: "sts:AssumeRole"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonRedshiftAllCommandsFullAccess
        - !Ref AmazonRedshiftCommandsAccessPolicy
  AmazonRedshiftCommandsAccessPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: !Sub "AmazonRedshiftCommandsAccessPolicy-${NamespaceName}"
      Description: Policy allowing access to S3
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action:
          - s3:GetObject
          - s3:GetBucketAcl
          - s3:GetBucketCors
          - s3:GetEncryptionConfiguration
          - s3:GetBucketLocation
          - s3:ListBucket
          - s3:ListAllMyBuckets
          - s3:ListMultipartUploadParts
          - s3:ListBucketMultipartUploads
          - s3:PutObject
          - s3:PutBucketAcl
          - s3:PutBucketCors
          - s3:DeleteObject
          - s3:AbortMultipartUpload
          - s3:CreateBucket
          Resource: arn:aws:s3:::*

スタックの作成

マネジメントコンソールのCloudFromationのCreate Srtack(スタックの作成)ボタンを押して、[テンプレートファイルのアップロード]で、ファイルを選択してアップロードします。

CloudFromationテンプレートをCreate Srtack(スタックの作成)すると以下のように、パラメタを入力して実行します。

作成したリソース

最後に

私が知る限り、サンプルコードがなかったのでこの機会に作成しました。誰かのお役に立てたら幸いです。CDKのL2 Construct Libraryのあるようなので、別の機会に紹介したいと思います。

現在は、CDKのL1 Construct Libraryのみのようです。RedshiftのL2 Construct Libraryがリリースされるのを正座待機で待ってます!