【RDS構築】terraform AWS環境構築 第5回

AWS

AWSRails + Nginxな環境をTerraformで構築してみようと思います。

はじめに

本連載で一つずつインフラを構築していきます。

ドメインのhttps化したり、ECS Fargateを使用したコンテナオーケストレーションを用いてアプリケーションをデプロイします。

この記事ではRDSの構築をします。

環境は以下です。

OS Cataline 10.15.6
Terraform 0.14.4

 

 

 

基本構文などこちらにまとめてますので、よかったらみてください!
AWS Terraform 基本コード まとめ

連載一覧

やること

以下の定義と作成をします。

RDSの構築

DBの環境構築を定義しておきます。

./terrafrom.tfvars に以下を追記します。

db_name = "rails-hello"
db_username = "root"
db_password = "password"

./variable.tf に以下を追記します。

variable "db_name" {}

variable "db_username" {}

variable "db_password" {}

rdsモジュールの作成

RDSを作成するモジュールを作成します。

terraformフォルダ内にrdsフォルダを作成しましょう。main.tfも作成しておきます。

rdsモジュールを使用できるよう./main.tfに以下を追記します。

./main.tf

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

  app_name    = var.app_name
  # DB環境変数
  db_name     = var.db_name
  db_username = var.db_username
  db_password = var.db_password
}

rdsモジュール内でapp_nameを受け取れるように、variable.tfを用意します。

./rds/variable.tf

variable "app_name" {}

variable "db_name" {}

variable "db_username" {}

variable "db_password" {}

ディレクトリ構成は以下のようにしています。

[terraform] $ tree 
. 
├── rds
│   ├── main.tf
│   └── variable.tf
├── ecs_cluster
│   ├── main.tf
│   └── output.tf
├── ecs_nginx
│   ├── container_definitions.json
│   ├── data.tf
│   ├── main.tf
│   └── variable.tf
├── iam_role
│   ├── data.tf
│   ├── main.tf
│   ├── output.tf
│   └── variable.tf
├── elb
│   ├── data.tf
│   ├── main.tf
│   ├── output.tf
│   └── variable.tf
├── acm
│   ├── data.tf
│   ├── main.tf
│   ├── output.tf
│   └── variable.tf
├── network 
│   ├── main.tf 
│   ├── output.tf 
│   └── variable.tf
├── env
│   └── backend.config
├── main.tf
├── output.tf
├── backend.tf
├── provider.tf
├── terraform.tfvars
└── variable.tf

用意できたら、terraformの初期化を行いましょう。

[terraform] $ terraform init -backend-config=env/backend.config -upgrade

セキュリティーグループの作成

MySQL用のセキュリティーグループを作成します。

./rds/main.tf に以下を追記します。

resource "aws_security_group" "db_sg" {
  name        = "${var.app_name}-mysql"
  description = "security group on db of ${var.app_name}"

  vpc_id = var.vpc_id

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.app_name}-sg of mysql"
  }
}

resource "aws_security_group_rule" "mysql-rule" {
  security_group_id = aws_security_group.db_sg.id

  type = "ingress"

  from_port                = 3306
  to_port                  = 3306
  protocol                 = "tcp"
  source_security_group_id = var.alb_security_group
}
  • source_security_group_id:アクセスを許可するセキュリティーグループ

vpc_id, alb_security_group が必要になるので、rdsモジュールに追記します。

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

  app_name           = var.app_name
  db_name            = var.db_name
  db_username        = var.db_username
  db_password        = var.db_password
  # 追記
  vpc_id             = module.network.vpc_id
  alb_security_group = module.elb.alb_security_group
}

受け取れるように、variable.tfにも追記しておきます。

./rds/variable.tf

variable "vpc_id" {}

variable "alb_security_group" {}

terraform plan, apply して作成されるか見てみましょう。

セキュリティーグループが追加で作成さたのが確認できましたね。

DBサブネットグループの作成

RDSインスタンスが配置されうるサブネットのグループを作成します。

./rds/main.tf に以下を追記します。

resource "aws_db_subnet_group" "db_subnet_group" {
  name        = var.db_name
  description = "db subent group of ${var.db_name}"
  subnet_ids  = var.private_subnet_ids
}
  • nameDBサブネットグループ名
  • description:説明
  • subnet_ids:グループ化するサブネット

private_subnet_ids が必要なので、rdsモジュールに追記します。

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

  app_name           = var.app_name
  db_name            = var.db_name
  db_username        = var.db_username
  db_password        = var.db_password
  vpc_id             = module.network.vpc_id
  alb_security_group = module.elb.alb_security_group
  # 追記
  private_subnet_ids = module.network.private_subnet_ids
}

受け取れるように、variable.tfにも追記しておきます。

./rds/variable.tf

variable "private_subnet_ids" {}

terraform plan, apply して作成されるか見てみましょう。

サブネットグループが作成されたのが確認できましたね。

RDSの定義

データベースであるRDSの作成します。

./rds/main.tf に以下を追記します。

resource "aws_db_instance" "db" {
 allocated_storage = 10
 storage_type    = "gp2"
  engine           = var.engine
  engine_version   = var.engine_version
  instance_class   = var.db_instance

  identifier          = var.db_name
  username            = var.db_username
  password            = var.db_password
  skip_final_snapshot = true

  vpc_security_group_ids = [aws_security_group.db_sg.id]
  db_subnet_group_name   = aws_db_subnet_group.db_subnet_group.name
}
  • allocated_storage:割当ストレージ
  • storage_type:ストレージタイプ
  • engineDBデータベースエンジン
  • egine_versionDBエンジンバージョン
  • instance_classDBインスタンスサイズ
  • identifierRDSonly lowercase alphanumeric characters and hyphens allowed inインスタンス名
  • username:マスターユーザー名
  • password:マスターパスワード
  • skip_final_snapshotDB削除時にスナップショット作成するかどうか
  • vpc_security_group_ids:セキュリティーグループ
  • db_subnet_group_nameDBサブネットグループ

./rds/variable.tf

variable "engine" {
  type    = string
  default = "mysql"
}

variable "engine_version" {
  type    = string
  default = "8.0.20"
}

variable "db_instance" {
  type    = string
  default = "db.t2.micro"
}

terraform plan, apply して作成されるか見てみましょう。

データベースが作成されたのが確認できましたね。

まとめ

DBインスタンスのエンドポイントは、Railsサーバーで使用するのでアウトプット変数を定義しておきましょう。

./rds/output.tf

output "db_address" {
  value = aws_db_instance.db.address
}

aws_db_instance.db.endpoint だと :3306が最後についてしまうんで、これだとrailsから繋がらないので注意が必要です。

今回、作成したコードとディレクトリ構成は以下になります。

[terraform] $ tree 
. 
├── rds
│   ├── main.tf
│   ├── output.tf
│   └── variable.tf
├── ecs_cluster
│   ├── main.tf
│   └── output.tf
├── ecs_nginx
│   ├── container_definitions.json
│   ├── data.tf
│   ├── main.tf
│   └── variable.tf
├── iam_role
│   ├── data.tf
│   ├── main.tf
│   ├── output.tf
│   └── variable.tf
├── elb
│   ├── data.tf
│   ├── main.tf
│   ├── output.tf
│   └── variable.tf
├── acm
│   ├── data.tf
│   ├── main.tf
│   ├── output.tf
│   └── variable.tf
├── network 
│   ├── main.tf 
│   ├── output.tf 
│   └── variable.tf
├── env
│   └── backend.config
├── main.tf
├── output.tf
├── backend.tf
├── provider.tf
├── terraform.tfvars
└── variable.tf

./rds/main.tf

resource "aws_security_group" "db_sg" {
  name        = "${var.app_name}-mysql"
  description = "security group on db of ${var.app_name}"

  vpc_id = var.vpc_id

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.app_name}-sg of mysql"
  }
}

resource "aws_security_group_rule" "mysql-rule" {
  security_group_id = aws_security_group.db_sg.id

  type = "ingress"

  from_port                = 3306
  to_port                  = 3306
  protocol                 = "tcp"
  source_security_group_id = var.alb_security_group
}

resource "aws_db_subnet_group" "db_subnet_group" {
  name        = var.db_name
  description = "db subent group of ${var.db_name}"
  subnet_ids  = var.private_subnet_ids
}

resource "aws_db_instance" "db" {
  allocated_storage = 10
  storage_type      = "gp2"
  engine            = var.engine
  engine_version    = var.engine_version
  instance_class    = var.db_instance

  identifier          = var.db_name
  username            = var.db_username
  password            = var.db_password
  skip_final_snapshot = true

  enabled_cloudwatch_logs_exports = [
    "error",
    "general",
    "slowquery"
  ]
  vpc_security_group_ids = [aws_security_group.db_sg.id]
  db_subnet_group_name   = aws_db_subnet_group.db_subnet_group.name
}

./rds/variable.tf

variable "app_name" {}

variable "vpc_id" {}

variable "alb_security_group" {}

variable "engine" {
  type    = string
  default = "mysql"
}

variable "engine_version" {
  type    = string
  default = "8.0.20"
}

variable "db_instance" {
  type    = string
  default = "db.t2.micro"
}

variable "private_subnet_ids" {}

variable "db_name" {}

variable "db_username" {}

variable "db_password" {}

おわり

これで、RDSの構築が完了しました。お疲れさまでした!

何か疑問に思うことがあれば、何でもコメントしてください!

次回は、Rails+NginxのDockerイメージを作成してECRへpushをします。

コメント

タイトルとURLをコピーしました