
TerraformでAmazon Redshift クラスターを構築
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
先日Terraformのv0.6.10がリリースされ、AWSプロバイダーにAmazon Redshift関連のリソースが追加されました。これによりTerraformでAmazon Redshiftのクラスターを構築することが可能となりました。Terraformの守備範囲を広げるうれしいアップデートです。
今回のエントリでは、このTerraformで新たに利用可能となったAmazon Redshift関連のリソースについてご紹介したいと思います。
なお、Terrafromの基本的な使い方については以下のブログエントリをご参照ください。
Amazon Redshift関連のリソース
新たに利用可能となったのは以下の4つのリソースです。
- aws_redshift_parameter_group
 - aws_redshift_subnet_group
 - aws_redshift_security_group
 - aws_redshift_cluster
 
aws_redshift_parameter_group
Amazon Redshiftのパラメータグループを定義するためのリソースです。
サポートされる引数
| 引数名 | 説明 | 必須/オプション | 
|---|---|---|
| name | パラメータグループ名 | 必須 | 
| family | パラメータグループファミリー | 必須 | 
| description | パラメータグループの説明 | 必須 | 
| parameter | パラメータのリスト | オプション | 
familyは、本ブログ記事執筆時点(2016年1月時点)で指定可能なものは「redshift-1.0」のみです(Terraformの仕様ではなく、Amazon Redshift側の仕様です。Amazon Redshiftはバージョン1.0系しかリリースされていないため、パラメータグループファミリーの選択肢も1.0のみとなります)。
parameterには、引数としてパラメータ名(name)とパラメータ値(value)を与えます。設定したいパラメータが複数ある場合は、その分のparameterブロックを定義します。(一つのパラメータに対して一つのparameterブロックを定義します)。paramterを省略した場合は、デフォルトのパラメータ値でパラメータグループが作成されます。
resource "aws_redshift_parameter_group" "tf-test-parameter-group" {
    name = "tf-test"
    family = "redshift-1.0"
    description = "Test parameter group for terraform"
    parameter {
      name = "require_ssl"
      value = "true"
    }
    parameter{
      name = "enable_user_activity_logging"
      value = "true"
    }
}
エクスポートされる属性
エクスポートされる属性(他リソースから参照できる属性)はidのみです(属性名はidですが、値としてはパラメータグループ名がエクスポートされます)。
| 属性名 | 説明 | 
|---|---|
| id | パラメータグループ名 | 
aws_redshift_subnet_group
Amazon Redshiftのクラスターノードを起動するサブネットのグループを定義するためのリソースです。
サポートされる引数
| 引数名 | 説明 | 必須/オプション | 
|---|---|---|
| name | サブネットグループ名 | 必須 | 
| description | サブネットグループの説明 | 必須 | 
| subnet_ids | サブネットIDの配列 | オプション | 
subnet_idsには、既存のサブネットのIDを配列形式で指定します。予めサブネットを作成しておく必要があります。
resource "aws_redshift_subnet_group" "tf-test-subnet-group" {
    name = "tf-test"
    description = "Test subnet group for terraform"
    subnet_ids = ["${aws_subnet.public-a.id}"]
}
エクスポートされる属性
エクスポートされる属性はidのみです。
| 属性名 | 説明 | 
|---|---|
| id | パラメータグループID | 
aws_redshift_security_group
Amazon Redshiftのクラスターに割り当てるセキュリティグループを定義するためのリソースですが、このリソースで定義可能なセキュリティグループは、EC2-Classic Platformが利用可能なAWSアカウントでVPC外にAmazon Redshiftのクラスターを起動する場合に利用するセキュリティグループです。VPC内にクラスターを起動する場合は、VPCのセキュリティグループを使用します。
新規でAmazon Redshiftのクラスターを起動する場合、あえてVPC外にクラスターを起動するパターンは稀かと思いますので、このaws\_redshift\_security\_groupの説明は割愛します。
aws_redshift_cluster
Amazon Redshiftのクラスターを定義するためのリソースです。Amazon Redshiftのクラスターを作成したことが無いという方は、以下のブログエントリも合わせてご確認ください。
Amazon Redshift クラスターの作成手順 | Developers.IO
サポートされる引数
| 引数名 | 説明 | 必須/オプション | デフォルト値 | 
|---|---|---|---|
| cluster_identifier | クラスター名 | 必須 | |
| database_name | DB名 | オプション | |
| cluster_type | クラスタータイプ(multi-node or single-node) | 必須 | |
| node_type | ノードタイプ(インスタンスタイプ) | 必須 | |
| master_password | マスターユーザーのパスワード | 必須 | |
| master_username | マスターユーザー名 | 必須 | |
| cluster_security_groups | クラスターに割り当てるセキュリティグループ名(EC2-Classic Platformの場合のみ) | オプション | |
| vpc_security_group_ids | クラスターに割り当てるVPCセキュリティグループ名 | オプション | |
| cluster_subnet_group_name | クラスターを起動するセキュリティグループ名 | オプション | |
| availability_zone | クラスターを起動するアベイラビリティゾーン | オプション | |
| preferred_maintenance_window | メンテナンスウィンドウ(ddd:hh24:mi-ddd:hh24:mi) | オプション | |
| cluster_parameter_group_name | クラスターに割り当てるパラメータグループ | オプション | |
| automated_snapshot_retention_period | 自動スナップショットの保存日数(1-35、0は自動スナップショットを無効化) | オプション | 1 | 
| port | クラスターの接続ポート番号 | オプション | 5439 | 
| cluster_version | クラスターバージョン(1.0のみ指定可能(2016年1月時点)) | オプション | 1.0 | 
| allow_version_upgrade | 自動メジャーアップグレードを許可する/しない | オプション | true | 
| number_of_nodes | クラスターノード数 | オプション | 1 | 
| publicly_accessible | パブリックアクセスを許可する/しない | オプション | 1 | 
| encrypted | データベースを暗号化する/しない | オプション | false | 
| elastic_ip | クラスターに割り当てるEIP | オプション | |
| skip_final_snapshot | クラスター削除時に最終スナップショットを取得する/しない | オプション | false | 
| final_snapshot_identifier | 最終スナップショット名 | オプション | 
エクスポートされる属性
| 引数名 | 説明 | 
|---|---|
| id | クラスターID | 
| cluster_identifier | クラスター名 | 
| cluster_type | クラスタータイプ(multi-node or single-node) | 
| node_type | ノードタイプ(インスタンスタイプ) | 
| database_name | DB名 | 
| availability_zone | クラスターを起動するアベイラビリティゾーン | 
| automated_snapshot_retention_period | 自動スナップショットの保存日数(1-35、0は自動スナップショットを無効化) | 
| preferred_maintenance_window | メンテナンスウィンドウ(ddd:hh24:mi-ddd:hh24:mi) | 
| endpoint | クラスターのエンドポイント | 
| encrypted | データベースを暗号化有無 | 
| cluster_security_groups | クラスターに割り当てるセキュリティグループ名(EC2-Classic Platformの場合のみ) | 
| vpc_security_group_ids | クラスターに割り当てるVPCセキュリティグループ名 | 
| port | クラスターの接続ポート番号 | 
| cluster_version | クラスターバージョン(1.0のみ指定可能(2016年1月時点)) | 
| cluster_parameter_group_name | クラスターに割り当てるパラメータグループ | 
| cluster_subnet_group_name | クラスターを起動するセキュリティグループ名 | 
| cluster_public_key | クラスターのパブリックキー | 
| cluster_revision_number | クラスターのリビジョン番号 | 
Terraformのテンプレートファイルの例
以下のテンプレートファイルを作成して、実際にAmazon Redshiftのクラスターを構築してみました。
なぜかpublicly_accessible = falseが効かなかったのでpublicly_accessible = trueでクラスターを起動しました(publicly_accessible = true の前提条件となるInternet GatewayもVPCにアタッチしています)。v0.6.12でこの問題が *1が修正され、publicly_accessible = falseが指定できるようになっています。
variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region" {
    default = "ap-northeast-1"
}
variable "redshift_master_password" {}
variable "cidr_block" {
    type = "map"
    default = {
      classmethod = ""
    }
}
provider "aws" {
    access_key = "${var.aws_access_key}"
    secret_key = "${var.aws_secret_key}"
    region = "ap-northeast-1"
}
resource "aws_vpc" "myVPC" {
    cidr_block = "10.50.0.0/16"
    enable_dns_hostnames = true
}
resource "aws_internet_gateway" "myGW" {
    vpc_id = "${aws_vpc.myVPC.id}"
}
resource "aws_subnet" "public-a" {
    vpc_id = "${aws_vpc.myVPC.id}"
    cidr_block = "10.50.10.0/24"
    availability_zone = "ap-northeast-1a"
}
resource "aws_route_table" "public-route" {
    vpc_id = "${aws_vpc.myVPC.id}"
    route {
        cidr_block = "0.0.0.0/0"
        gateway_id = "${aws_internet_gateway.myGW.id}"
    }
}
resource "aws_route_table_association" "puclic-a" {
    subnet_id = "${aws_subnet.public-a.id}"
    route_table_id = "${aws_route_table.public-route.id}"
}
resource "aws_security_group" "sg_for_redshift" {
  name = "sg_for_redshift"
  description = "Security Group for Redshift"
  vpc_id = "${aws_vpc.myVPC.id}"
  ingress {
      from_port = 5439
      to_port = 5439
      protocol = "tcp"
      cidr_blocks = ["${var.cidr_block.classmethod}"]
  }
  egress {
      from_port = 0
      to_port = 0
      protocol = "-1"
      cidr_blocks = ["0.0.0.0/0"]
  }
}
resource "aws_redshift_parameter_group" "tf-test-parameter-group" {
    name = "tf-test"
    family = "redshift-1.0"
    description = "Test parameter group for terraform"
    parameter {
      name = "require_ssl"
      value = "true"
    }
    parameter{
      name = "enable_user_activity_logging"
      value = "true"
    }
}
resource "aws_redshift_subnet_group" "tf-test-subnet-group" {
    name = "tf-test"
    description = "Test subnet group for terraform"
    subnet_ids = ["${aws_subnet.public-a.id}"]
}
resource "aws_redshift_cluster" "tf-test-redshift-cluster" {
  cluster_identifier = "tf-test-redshift-cluster"
  database_name = "mydwh"
  master_username = "root"
  master_password = "${var.redshift_master_password}"
  node_type = "dc1.large"
  cluster_type = "multi-node"
  vpc_security_group_ids = ["${aws_security_group.sg_for_redshift.id}"]
  cluster_subnet_group_name = "${aws_redshift_subnet_group.tf-test-subnet-group.id}"
  availability_zone = "ap-northeast-1a"
  preferred_maintenance_window = "sat:20:00-sat:20:30"
  cluster_parameter_group_name = "${aws_redshift_parameter_group.tf-test-parameter-group.id}"
  automated_snapshot_retention_period = 7
  number_of_nodes = 2
  publicly_accessible = true
  skip_final_snapshot = true
}
まとめ
TerraformはAmazon RDS、Amazon ElastiCache、Amazon DynamoDBには対応済みだったため、Amazon Redshift関連のリソースの追加によりAWSのデータベースサービスに対応するリソースが出揃った形となりました。
個人的には仕事でよく使うAmazon CloudFrontへの対応を待ち望んでいます。引き続きTerraformのアップデートをウォッチしていきたいと思います。






