TerraformでAmazon Redshift クラスターを構築

2016.02.02

先日Terraformのv0.6.10がリリースされ、AWSプロバイダーにAmazon Redshift関連のリソースが追加されました。これによりTerraformでAmazon Redshiftのクラスターを構築することが可能となりました。Terraformの守備範囲を広げるうれしいアップデートです。

今回のエントリでは、このTerraformで新たに利用可能となったAmazon Redshift関連のリソースについてご紹介したいと思います。

なお、Terrafromの基本的な使い方については以下のブログエントリをご参照ください。

Amazon Redshift関連のリソース

新たに利用可能となったのは以下の4つのリソースです。

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が指定できるようになっています。

variables.tf

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 = ""
    }
}

main.tf

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のアップデートをウォッチしていきたいと思います。

脚注