Terraform ( v0.12.0 ) でSSMパラメータと連携してAurora ( MySQL ) を構築する
やったこと
で書いたコードをTerraformのバージョンを0.11.14
から0.12.0
アップデートして書き直してみた。
RDSクラスターを作成する説明については上記リンクのブログに記載しています。
■ 構築する構成図 (workspace=prod)
変更点
- サブネットIDを取得するためにNameTagの検索で
*
を活用 ( redis-cとredis-dを取得する )
// subnet-idを取得する data "aws_subnet_ids" "redis" { vpc_id = data.aws_ssm_parameter.redis_vpc_id.value tags = { Name = "redis-*" } }
- vpcを作成するコードで0.12.0で書き直したところは 変数を以下のように書き換えができる。
- First-Class Expressions
- (変更前):
"${var.hoge}"
- (変更後):
var.hoge
- (変更前):
- First-Class Expressions
■ 参考: HashiCorp Terraform 0.12 Preview: First-Class Expressions
サブネットIDをセットする方法を変更した
■ ディレクトリ構造
── modules │ ├── rds │ │ └── aurora-mysql │ │ └── main.tf ├── rds.tf ├── s3-backend.tf
■ 変更前 (subnet_idに関わるところを抜粋)
/////////////////////// // module側 (rds.tf) // /////////////////////// // dbサブネットのidを取得する data "aws_subnet_ids" "db-c" { vpc_id = "${data.aws_ssm_parameter.vpc_id.value}" tags { Name = "db-c" } } // dbサブネットのidを取得する data "aws_subnet_ids" "db-d" { vpc_id = "${data.aws_ssm_parameter.vpc_id.value}" tags { Name = "db-d" } } locals { ・・・ db_subnet_ids_anyenv = ["${data.aws_subnet_ids.db-c.ids}", "${data.aws_subnet_ids.db-d.ids}"] db_subnet_ids = "${split(",",join(",",local.db_subnet_ids_anyenv))}" ・・・ } module "create-aurora-mysql" { ・・・ db_subnet_ids = "${split(",",join(",",local.db_subnet_ids))}" ・・・ } ///////////////////////// // resouce側 (main.tf) // ///////////////////////// variable "db_subnet_ids" { default = [] } resource "aws_db_subnet_group" "default" { name = "${var.db_subnet_group_name}" subnet_ids = ["${var.db_subnet_ids}"] description = "${var.description}" }
■ 変更後
- vpc_idを取得してsubnet_id情報を取得する処理りをresouce側だけの処理で完結させた。
///////////////////////// // resource側 (main.tf) // ///////////////////////// // subnet-idを取得する data "aws_subnet_ids" "db" { vpc_id = data.aws_ssm_parameter.redis_vpc_id.value tags = { Name = "db-*" } } resource "aws_db_subnet_group" "default" { name = var.db_subnet_group_name subnet_ids = data.aws_subnet_ids.db.ids description = var.description }
→ subnet-idをlistで取得して、 resource "aws_db_subnet_group" "default"
で取得した subnet_idsは data.aws_subnet_ids.db.ids
を参照でき、 subnet_ids
にlistで渡すようにした。処理もかなりシンプルにすることができた。
Terraformのコード全体
■ ディレクトリ構造(一部抜粋)
├── modules │ ├── rds │ │ └── aurora-mysql │ │ └── main.tf ( resource側 ) ├── rds.tf ( module側 ) ├── s3-backend.tf
■ Module側 ( rds.tf )
variable "availability_zone_prod" { default = ["ap-northeast-1c", "ap-northeast-1d"] } variable "availability_zone_stg" { default = ["ap-northeast-1c"] } variable "availability_zone_dev" { default = ["ap-northeast-1c"] } locals { instance_class_prod = "db.r4.large" instance_class_stg = "db.t2.medium" instance_class_dev = "db.t2.medium" availability_zone = "${split(",", (terraform.workspace == "prod" && terraform.workspace != "stg" && terraform.workspace != "dev") ? join(",", var.availability_zone_prod) : join(",", var.availability_zone_dev))}" } module "create-aurora-mysql" { source = "./modules/rds/aurora-mysql" description = "for app" cluster_identifier = "app-db-${terraform.workspace}-cluster" identifier = "app-db-${terraform.workspace}" database_name = "app" master_username = "root" engine = "aurora-mysql" engine_version = "5.7.12" db_subnet_group_name = "app_db" db_parameter_group_name = "app-aurora57" db_parameter_group_family = "aurora-mysql5.7" cluster_parameter_group_family = "aurora-mysql5.7" cluster_parameter_group_name = "app-cluster-aurora57" preferred_backup_window_cluster = "20:06-20:36" preferred_maintenance_window_instance = "sun:19:00-sun:19:30" preferred_maintenance_window_cluster = "sun:19:00-sun:19:30" final_snapshot_identifier = true backup_retention_period = 7 auto_minor_version_upgrade = true publicly_accessible = false storage_encrypted = "${terraform.workspace == "prod" ? true : false}" instance_class = "${terraform.workspace == "prod" ? local.instance_class_prod : terraform.workspace == "stg" ? local.instance_class_stg : local.instance_class_dev}" availability_zone = "${split(",", (terraform.workspace != "prod" && terraform.workspace == "stg" && terraform.workspace != "dev") ? join(",", var.availability_zone_stg) : join(",", local.availability_zone))}" }
■ Resource側 ( rds/aurora-mysql/main.tf )
variable "instance_class" {} variable "description" {} variable "identifier" {} variable "cluster_identifier" {} variable "database_name" {} variable "master_username" {} variable "engine" {} variable "engine_version" {} variable "db_subnet_group_name" {} variable "db_parameter_group_name" {} variable "db_parameter_group_family" {} variable "cluster_parameter_group_name" {} variable "cluster_parameter_group_family" {} variable "preferred_backup_window_cluster" {} variable "preferred_maintenance_window_cluster" {} variable "preferred_maintenance_window_instance" {} variable "final_snapshot_identifier" {} variable "backup_retention_period" {} variable "auto_minor_version_upgrade" {} variable "publicly_accessible" {} variable "storage_encrypted" {} variable "availability_zone" { default = [] } // vpc_idを取得する data "aws_ssm_parameter" "redis_vpc_id" { name = "vpc_id" } // subnet-idを取得する data "aws_subnet_ids" "db" { vpc_id = data.aws_ssm_parameter.redis_vpc_id.value tags = { Name = "db-*" } } // dbのSecurityGroupのidを取得する data "aws_security_group" "db" { vpc_id = data.aws_ssm_parameter.redis_vpc_id.value tags = { Name = "db" } } // dbのpasswordをssmパラメータから取得する data "aws_ssm_parameter" "db_password" { name = "db_password" } resource "aws_rds_cluster" "aurora_cluster" { cluster_identifier = var.cluster_identifier availability_zones = var.availability_zone database_name = var.database_name engine = var.engine master_username = var.master_username master_password = data.aws_ssm_parameter.db_password.value db_cluster_parameter_group_name = var.cluster_parameter_group_name db_subnet_group_name = aws_db_subnet_group.default.name vpc_security_group_ids = [data.aws_security_group.db.id] preferred_backup_window = var.preferred_backup_window_cluster preferred_maintenance_window = var.preferred_maintenance_window_cluster final_snapshot_identifier = var.final_snapshot_identifier backup_retention_period = var.backup_retention_period storage_encrypted = var.storage_encrypted } resource "aws_rds_cluster_instance" "cluster_instances" { count = "${length(var.availability_zone)}" identifier = "${var.identifier}-${count.index+1}" cluster_identifier = aws_rds_cluster.aurora_cluster.id instance_class = var.instance_class engine = var.engine db_subnet_group_name = aws_db_subnet_group.default.name db_parameter_group_name = var.db_parameter_group_name auto_minor_version_upgrade = var.auto_minor_version_upgrade publicly_accessible = var.publicly_accessible preferred_maintenance_window = var.preferred_maintenance_window_instance } resource "aws_db_subnet_group" "default" { name = var.db_subnet_group_name subnet_ids = data.aws_subnet_ids.db.ids description = var.description } resource "aws_db_parameter_group" "default" { name = var.db_parameter_group_name family = var.db_parameter_group_family description = var.description } resource "aws_rds_cluster_parameter_group" "default" { name = var.cluster_parameter_group_name family = var.cluster_parameter_group_family description = var.description }
まとめ
Terraformのバージョンを 0.11.14
から 0.12.0
にバージョンを上げた。
今回は、以前に作成したRDS(MySQL Aurora)のコードを 0.12.0版に修正した。
付与するサブネットを動的に割り当てる処理をresource側に定義・修正してシンプル化した。
また、変数に "${}"
が不要になったので、コードとしてもすっきりするし、書くのが楽になった。