My Note

自己理解のためのブログ

Terraform ( v0.12.0 ) でAWSの環境構築 ( Redis )

やったこと

yhidetoshi.hatenablog.com

で書いたコードをTerraformのバージョンを0.11.14から0.12.0アップデートして書き直してみた。Redisクラスターを作成する説明については上記リンクのブログに記載しています。

■ 構築する構成図 (workspace=prod)

f:id:yhidetoshi:20190621231505p:plain

変更点

■ redisのnode_typeをEnvで切り替わるように修正

tf node_type = "${terraform.workspace == "prod" ? "cache.m3.medium" : "cache.t2.small"}" → ENV=prodなら cache.m3.medium それ以外のENV(dev/stg)なら cache.t2.small をセット

subnet_idの取得を resouce側 で処理


── modules
│   ├── elasticache
│   │   └── redis
│   │       └── main.tf
├── redis.tf
├── s3-backend.tf
/////////////////////////
// module側 (redis.tf) //
////////////////////////

// vpc_idを取得する
data "aws_ssm_parameter" "redis_vpc_id" {
  name = "vpc_id"
}

// cacheサブネットのidを取得する
data "aws_subnet_ids" "cache_c" {
  vpc_id = "${data.aws_ssm_parameter.redis_vpc_id.value}"
  tags = {
    Name = "cache-c"
  }
}
// cacheサブネットのidを取得する
data "aws_subnet_ids" "cache_d" {
  vpc_id = "${data.aws_ssm_parameter.redis_vpc_id.value}"
  tags = {
    Name = "cache-d"
  }
}

locals {
  ・・・
  cache_subnet_ids       = ["${data.aws_subnet_ids.cache_c.*.ids}", "${data.aws_subnet_ids.cache_d.*.ids}"] 
  ・・・
}
module "redis-cluster" {
  ・・・
  node_type              = "${terraform.workspace == "prod" ? "cache.m3.medium" : "cache.t2.small"}"
  subnet_ids             = ["${local.cache_subnet_ids}"]
  ・・・
}

■ 変更後

vpc_idを取得してsubnet_id情報を取得する処理りをresouce側だけの処理で完結させた。


///////////////////////////////////////////
// resouce側 (elasticache/redis/main.tf) //
///////////////////////////////////////////

variable "security_group_ids" {
  default = []
}
variable "subnet_ids" {
  default = []
}

// vpc_idを取得する
data "aws_ssm_parameter" "redis_vpc_id" {
  name = "vpc_id"
}

// subnet-idを取得する
data "aws_subnet_ids" "redis" {
  vpc_id = data.aws_ssm_parameter.redis_vpc_id.value

  tags = {
    Name = "redis-*"
  }
}

resource "aws_elasticache_replication_group" "redis" {
  ・・・
  node_type  = var.node_type
  ・・・
}


resource "aws_elasticache_subnet_group" "redis" {
  name       = var.name
  subnet_ids = data.aws_subnet_ids.redis.ids
}

→ subnet-idをlistで取得して、 resource "aws_db_subnet_group" "default" で取得した subnet_idsは data.aws_subnet_ids.db.idsを参照でき、 subnet_ids にlistで渡すようにした。処理もかなりシンプルにすることができた。

Terraformのコード全体

ディレクトリ構造(一部抜粋)

── modules
│   ├── elasticache
│   │   └── redis
│   │       └── main.tf
├── redis.tf
├── s3-backend.tf

■ Module側 ( rds.tf )

module "redis-cluster" {
  source                        = "./modules/elasticache/redis"
  parameter_group_name          = "default.redis3.2"
  engine_version                = "3.2.4"
  port                          = 6379
  subnet_group_name             = "redis"
  replication_group_description = "test description"
  name                          = "redis"
  snapshot_retention_limit      = 0
  node_type                     = "${terraform.workspace == "prod" ? "cache.m3.medium" : "cache.t2.small"}"
  replication_group_id          = "redis-${terraform.workspace}"
  number_cache_clusters         = "${terraform.workspace == "prod" ? 2 : 1}"
  automatic_failover_enabled    = "${terraform.workspace == "prod" ? true : false}"
}

■ Resource側 ( elasticache/redis/main.tf )

variable "security_group_ids" {
  default = []
}
variable "subnet_ids" {
  default = []
}

variable "parameter_group_name" {}
variable "engine_version" {}
variable "port" {}
variable "node_type" {}
variable "replication_group_description" {}
variable "replication_group_id" {}
variable "snapshot_retention_limit" {}
variable "subnet_group_name" {}
variable "automatic_failover_enabled" {}
variable "name" {}
variable "number_cache_clusters" {}


// vpc_idを取得する
data "aws_ssm_parameter" "redis_vpc_id" {
  name = "vpc_id"
}

// subnet-idを取得する
data "aws_subnet_ids" "redis" {
  vpc_id = data.aws_ssm_parameter.redis_vpc_id.value

  tags = {
    Name = "redis-*"
  }
}


// dbのSecurityGroupのidを取得する
data "aws_security_group" "redis" {
  vpc_id = data.aws_ssm_parameter.redis_vpc_id.value

  tags = {
    Name = "redis"
  }
}


resource "aws_elasticache_replication_group" "redis" {
  replication_group_id          = var.replication_group_id
  replication_group_description = var.replication_group_description
  node_type                     = var.node_type
  port                          = var.port
  engine_version                = var.engine_version
  security_group_ids            = [data.aws_security_group.redis.id]
  parameter_group_name          = var.parameter_group_name
  subnet_group_name             = var.subnet_group_name
  automatic_failover_enabled    = var.automatic_failover_enabled
  number_cache_clusters         = var.number_cache_clusters
  snapshot_retention_limit      = var.snapshot_retention_limit
  depends_on                    = ["aws_elasticache_subnet_group.redis"]
}


resource "aws_elasticache_subnet_group" "redis" {
  name       = var.name
  subnet_ids = data.aws_subnet_ids.redis.ids
}

まとめ

Terraformのバージョンを 0.11.14 から 0.12.0 にバージョンを上げた。 今回は、以前に作成したRedisSのコードを 0.12.0版に修正した。 付与するサブネットを動的に割り当てる処理をresource側で定義・修正してシンプル化した。 また、変数に "${}" が不要になったので、コードとしてもすっきりするし、書くのが楽になった。