AWSでDBのmaster、slaveをTerraformで構築したい

AWSでDBのmaster、slaveをTerraformで構築してみました。


```
├── main.tf
├── output.tf
├── rds
│   ├── output.tf
│   ├── rds.tf
│   └── variables.tf
├── sg
│   ├── output.tf
│   ├── sg.tf
│   └── variables.tf
├── terraform.tfstate
├── terraform.tfstate.backup
├── variables.tf
└── vpc
    ├── output.tf
    ├── variables.tf
    └── vpc.tf
```

```main.tf
terraform {

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }

  required_version = ">= 1.2.0"
}

provider "aws" {
  region = "ap-northeast-1"
}

# VPC
module "vpc" {
  source = "./vpc"

  name_prefix = var.name_prefix
  region      = var.region
  az_a        = var.az_a
  az_c        = var.az_c
  tag_name    = var.tag_name
  tag_group   = var.tag_group
}

# SG
module "sg" {
  source = "./sg"

  name_prefix = var.name_prefix
  region      = var.region
  az_a        = var.az_a
  az_c        = var.az_c
  tag_name    = var.tag_name
  tag_group   = var.tag_group

  vpc_id = module.vpc.vpc_id
}

# RDS
module "rds" {
  source = "./rds"

  name_prefix = var.name_prefix
  region      = var.region
  az_a        = var.az_a
  az_c        = var.az_c
  tag_name    = var.tag_name
  tag_group   = var.tag_group

  vpc_id      = module.vpc.vpc_id
  public_a_id = module.vpc.public_a_id
  public_c_id = module.vpc.public_c_id
  sg_id       = module.sg.sg_id
}
```

```output.tf

output "rds_endpoint" {
  value = module.rds.endpoint
}
```

```variables.tf
variable "region" {
  default = "ap-northeast-1"
}

variable "az_a" {
  default = "ap-northeast-1a"
}

variable "az_c" {
  default = "ap-northeast-1c"
}

variable "name_prefix" {
  default = "ltar" 
}

variable "tag_name" {
  default = "learn-terraform-aws-rds"
}

variable "tag_group" {
  default = "learn-terraform-aws"
}
```

```vpc/vpc.tf
# VPC
resource "aws_vpc" "default" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true # DNSホスト名を有効化
  tags = {
    Name = "${var.tag_name}"
  }
}

# Subnet
resource "aws_subnet" "public_1a" {
  vpc_id            = aws_vpc.default.id
  cidr_block        = "10.0.0.0/20"
  availability_zone = var.az_a
  tags = {
    Name = "${var.tag_name}"
  }
}

resource "aws_subnet" "public_1c" {
  vpc_id            = aws_vpc.default.id
  cidr_block        = "10.0.16.0/20"
  availability_zone = var.az_c
  tags = {
    Name = "${var.tag_name}"
  }
}

# Internet Gateway
resource "aws_internet_gateway" "default" {
  vpc_id = aws_vpc.default.id
  tags = {
    Name = "${var.tag_name}"
  }
}

# Route table
resource "aws_route_table" "default" {
  vpc_id = aws_vpc.default.id
  tags = {
    Name = "${var.tag_name}"
  }
}

resource "aws_route" "default" {
  route_table_id         = aws_route_table.default.id
  gateway_id             = aws_internet_gateway.default.id
  destination_cidr_block = "0.0.0.0/0"
}

# SubnetとRoute tableの関連付け
resource "aws_route_table_association" "public_1a" {
  subnet_id      = aws_subnet.public_1a.id
  route_table_id = aws_route_table.default.id
}

resource "aws_route_table_association" "public_1c" {
  subnet_id      = aws_subnet.public_1c.id
  route_table_id = aws_route_table.default.id
}
```

```vpc/variables.tf
variable "region"      {default = "ap-northeast-1"}
variable "az_a"        {default = "ap-northeast-1a"}
variable "az_c"        {default = "ap-northeast-1c"}
variable "name_prefix" {default = "ltar"}
variable "tag_name"    {default = "learn-terraform-aws-rds"}
variable "tag_group"   {default = "learn-terraform-aws"}
```

```vpc/output.tf
output "vpc_id" {
    value = "${aws_vpc.default.id}"
}

output "public_a_id" {
    value = "${aws_subnet.public_1a.id}"
}

output "public_c_id" {
    value = "${aws_subnet.public_1c.id}"
}

```

```sg/sg.tf

resource "aws_security_group" "default" {
  vpc_id = "${var.vpc_id}"
  tags = {
    Name = "${var.tag_name}"
  }
}

resource "aws_security_group_rule" "mysql" {
  type              = "ingress"
  from_port         = "3306"
  to_port           = "3306"
  protocol          = "tcp"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.default.id
}

resource "aws_security_group_rule" "out_all_allow" {
  type              = "egress"
  from_port         = 0
  to_port           = 0
  protocol          = "all"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.default.id
}

```

```sg/variables.tf

variable "region"      {default = "ap-northeast-1"}
variable "az_a"        {default = "ap-northeast-1a"}
variable "az_c"        {default = "ap-northeast-1c"}
variable "name_prefix" {default = "ltar" }
variable "tag_name"    {default = "learn-terraform-aws-rds"}
variable "tag_group"   {default = "learn-terraform-aws"}

variable "vpc_id"      {default = "aws_vpc.default.id"}
```

```sg/output.tf

output "sg_id" {
    value = "${aws_security_group.default.id}"
}

```

```rds/rds.tf
locals {
  aurora_database_name   = "learn"
  aurora_master_username = "learn_user"
  aurora_master_password = "Passw0rd"
}

resource "aws_rds_cluster" "learn" {
  cluster_identifier              = "${var.name_prefix}-rds-cluster"
  engine                          = "aurora-mysql"
  engine_version                  = "8.0.mysql_aurora.3.05.2"
  database_name                   = local.aurora_database_name
  master_username                 = local.aurora_master_username
  master_password                 = local.aurora_master_password
  port                            = 3306
  vpc_security_group_ids          = ["${var.sg_id}"]
  db_subnet_group_name            = aws_db_subnet_group.learn.name
  db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.learn.name

  skip_final_snapshot = true
  apply_immediately   = true
}

resource "aws_rds_cluster_parameter_group" "learn" {
  name   = "${var.name_prefix}-database-cluster-parameter-group"
  family = "aurora-mysql8.0"

  parameter {
    name         = "character_set_client"
    value        = "utf8mb4"
    apply_method = "immediate"
  }

  parameter {
    name         = "character_set_connection"
    value        = "utf8mb4"
    apply_method = "immediate"
  }

  parameter {
    name         = "character_set_database"
    value        = "utf8mb4"
    apply_method = "immediate"
  }

  parameter {
    name         = "character_set_filesystem"
    value        = "utf8mb4"
    apply_method = "immediate"
  }

  parameter {
    name         = "character_set_results"
    value        = "utf8mb4"
    apply_method = "immediate"
  }

  parameter {
    name         = "character_set_server"
    value        = "utf8mb4"
    apply_method = "immediate"
  }

  parameter {
    name         = "collation_connection"
    value        = "utf8mb4_general_ci"
    apply_method = "immediate"
  }

  parameter {
    name         = "collation_server"
    value        = "utf8mb4_general_ci"
    apply_method = "immediate"
  }

  parameter {
    name         = "time_zone"
    value        = "Asia/Tokyo"
    apply_method = "immediate"
  }
}

resource "aws_db_subnet_group" "learn" {
  name = "${var.name_prefix}-db-subnet"
  subnet_ids = ["${var.public_a_id}", "${var.public_c_id}"]
}

resource "aws_rds_cluster_instance" "learn" {
  count = 1

  cluster_identifier = aws_rds_cluster.learn.id
  identifier              = "${var.name_prefix}-rds-instance-${count.index}"

  engine                  = aws_rds_cluster.learn.engine
  engine_version          = aws_rds_cluster.learn.engine_version
  instance_class          = "db.t3.medium"
  db_subnet_group_name    = aws_db_subnet_group.learn.name
  db_parameter_group_name = aws_db_parameter_group.learn.name

  publicly_accessible = true
}

resource "aws_rds_cluster_instance" "learn-replica" {
  count = 2

  cluster_identifier = aws_rds_cluster.learn.id
  identifier              = "${var.name_prefix}-rds-instance-${count.index}-replica"

  engine                  = aws_rds_cluster.learn.engine
  engine_version          = aws_rds_cluster.learn.engine_version
  instance_class          = "db.t3.medium"
  db_subnet_group_name    = aws_db_subnet_group.learn.name
  db_parameter_group_name = aws_db_parameter_group.learn.name
  depends_on              = [aws_rds_cluster_instance.learn]

  publicly_accessible = true
}

resource "aws_db_parameter_group" "learn" {
  name   = "${var.name_prefix}-db-parameter-group"
  family = "aurora-mysql8.0"
}
```

```rds/variables.tf
variable "region"      {default = "ap-northeast-1"}
variable "az_a"        {default = "ap-northeast-1a"}
variable "az_c"        {default = "ap-northeast-1c"}
variable "name_prefix" {default = "ltar"}
variable "tag_name"    {default = "learn-terraform-aws-rds"}
variable "tag_group"   {default = "learn-terraform-aws"}

variable "vpc_id"      {default = "aws_vpc.default.id"}
variable "public_a_id" {default = "aws_subnet.public_1a.id"}
variable "public_c_id" {default = "aws_subnet.public_1c.id"}
variable "sg_id"       {default = "aws_security_group.default.id"}

```

```rds/output.tf
output "endpoint" {
  value = aws_rds_cluster.learn.endpoint
}

```

engine_versionは使われてないこともあるため確認。