Go x Next.js(SPA) な環境をTerraformでAWSに構築してみます!
バックエンドのGoには、ECS Fargateで。
フロントエンドのSPAには、CloudFront・S3を使用して静的ホスティングをしてます。
また、System エージェントをインストールすることでFargateコンテナ内に接続できるようにしています。
はじめに
連載記事でこの環境を構築していきます。
本記事では、API用のドメインhttps化・アプリケーションロードバランサー構築・RDSの構築を行います!
フォルダ構成とか書き方、モージュル化などは、【ネットワーク環境構築】terraform AWS環境構築 第1回この記事とほぼ同じなので気になる方は御覧ください!
全体のソースコード:github
環境は以下です。
OS | Cataline 10.15.6 |
Terraform | 0.14.4 |
Go | 1.16.3 |
React | 17.0.2 |
基本構文などこちらにまとめてますので、よかったらみてください!
AWS Terraform 基本コード まとめ
連載一覧
- Go x Next.js(SPA) をTerraformでさっさと構築 1/3
- Go x Next.js(SPA) をTerraformでさっさと構築 2/3 ←ここ
- Go x Next.js(SPA) をTerraformでさっさと構築 3/3
やること
以下の定義と作成をします。
API用のドメインACM証明書発行
【ドメインhttps化・ACM(SSL)証明書発行】terraform AWS環境構築 第2回
こことほぼ同じですが、発行するドメインに「api.」を付け加えます。
./main.tf
module "network" { source = "./network" app_name = var.app_name } module "acm" { source = "./acm" domain = var.domain } module "spa" { source = "./spa" app_name = var.app_name domain = var.domain acm_id = module.acm.acm_id } #追記 module "subdomain_acm" { source = "./subdomain_acm" domain = var.domain }
./subdomain_acm/main.tf
resource "aws_acm_certificate" "this" { domain_name = "api.${var.domain}" validation_method = "DNS" lifecycle { create_before_destroy = true } } resource "aws_route53_record" "this" { depends_on = [aws_acm_certificate.this] for_each = { for dvo in aws_acm_certificate.this.domain_validation_options : dvo.domain_name => { name = dvo.resource_record_name record = dvo.resource_record_value type = dvo.resource_record_type } } zone_id = data.aws_route53_zone.this.zone_id name = each.value.name records = [each.value.record] ttl = 60 type = each.value.type } resource "aws_acm_certificate_validation" "this" { certificate_arn = aws_acm_certificate.this.arn validation_record_fqdns = [for record in aws_route53_record.this : record.fqdn] }
./subdomain_acm/variables.tf
variable "domain" {}
./subdomain_acm/data.tf
data "aws_route53_zone" "this" { name = var.domain private_zone = false }
./subdomain_acm/outputs.tf
output "sub_acm_id" { value = aws_acm_certificate.this.id }
[terraform] $ terraform plan
作成されるリソースの確認。
[terraform] $ terraform apply
リソースの作成。
api.<your domain> のACM証明書が発行されているのが確認できましたね。
アプリケーションロードバランサー
【ロードバランサー構築】terraform AWS環境構築 第3回
こことほぼ同じです。
./main.tf
module "network" { source = "./network" app_name = var.app_name } module "acm" { source = "./acm" domain = var.domain } module "spa" { source = "./spa" app_name = var.app_name domain = var.domain acm_id = module.acm.acm_id } module "subdomain_acm" { source = "./subdomain_acm" domain = var.domain } #追記 module "elb" { source = "./elb" app_name = var.app_name vpc_id = module.network.vpc_id public_subnet_ids = module.network.public_subnet_ids sub_acm_id = module.subdomain_acm.sub_acm_id domain = var.domain }
./elb/main.tf
resource "aws_security_group" "this" { vpc_id = var.vpc_id dynamic "ingress" { for_each = var.ingress_ports iterator = port content { from_port = port.value to_port = port.value protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "${var.app_name}-sg" } } resource "aws_lb" "this" { name = "${var.app_name}-alb" load_balancer_type = "application" security_groups = [aws_security_group.this.id] subnets = var.public_subnet_ids } resource "aws_lb_listener" "http" { port = "80" protocol = "HTTP" load_balancer_arn = aws_lb.this.arn default_action { type = "redirect" redirect { port = "443" protocol = "HTTPS" status_code = "HTTP_301" } } } resource "aws_lb_listener" "https" { port = "443" protocol = "HTTPS" load_balancer_arn = aws_lb.this.arn certificate_arn = var.sub_acm_id default_action { type = "fixed-response" fixed_response { content_type = "text/plain" status_code = "200" message_body = "ok" } } } resource "aws_route53_record" "this" { type = "A" name = "api.${var.domain}" zone_id = data.aws_route53_zone.this.id alias { name = aws_lb.this.dns_name zone_id = aws_lb.this.zone_id evaluate_target_health = true } }
./elb/variables.tf
variable "app_name" {} variable "vpc_id" {} variable "ingress_ports" { description = "list of ingress ports" default = [80, 443] } variable "public_subnet_ids" {} variable "sub_acm_id" {} variable "domain" {}
./elb/data.tf
data "aws_route53_zone" "this" { name = var.domain private_zone = false }
./elb/outputs.tf
output "http_listener_arn" { value = aws_lb_listener.http.arn } output "https_listener_arn" { value = aws_lb_listener.https.arn } output "alb_security_group_id" { value = aws_security_group.this.id }
RDSの構築
【RDS構築】terraform AWS環境構築 第5回
ここと同じです。
./main.tf
module "network" { source = "./network" app_name = var.app_name } module "acm" { source = "./acm" domain = var.domain } module "spa" { source = "./spa" app_name = var.app_name domain = var.domain acm_id = module.acm.acm_id } module "subdomain_acm" { source = "./subdomain_acm" domain = var.domain } module "elb" { source = "./elb" app_name = var.app_name vpc_id = module.network.vpc_id public_subnet_ids = module.network.public_subnet_ids sub_acm_id = module.subdomain_acm.sub_acm_id domain = var.domain } # 追記 module "rds" { source = "./rds" app_name = var.app_name db_name = var.db_name db_user = var.db_user db_password = var.db_password vpc_id = module.network.vpc_id alb_security_group_id = module.elb.alb_security_group_id private_subnet_ids = module.network.private_subnet_ids }
./terraform.tfvars
domain = "<your domain>" db_name = "go-next_db" db_user = "root" db_password = "password"
./rds/main.tf
resource "aws_security_group" "this" { 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}-rds-sg" } } resource "aws_security_group_rule" "this" { security_group_id = aws_security_group.this.id type = "ingress" from_port = 3306 to_port = 3306 protocol = "tcp" source_security_group_id = var.alb_security_group_id } resource "aws_db_subnet_group" "this" { name = var.db_name description = "db subent group of ${var.db_name}" subnet_ids = var.private_subnet_ids } resource "aws_db_instance" "this" { allocated_storage = 10 storage_type = "gp2" engine = var.engine engine_version = var.engine_version instance_class = var.db_instance identifier = "${var.app_name}-rds" username = var.db_user password = var.db_password skip_final_snapshot = true enabled_cloudwatch_logs_exports = [ "error", "general", "slowquery" ] vpc_security_group_ids = [aws_security_group.this.id] db_subnet_group_name = aws_db_subnet_group.this.name }
./rds/variables.tf
variable "app_name" {} variable "db_name" {} variable "db_user" {} variable "db_password" {} variable "vpc_id" {} variable "alb_security_group_id" {} 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" {}
./rds/outputs.tf
output "db_address" { value = aws_db_instance.this.address }
おわり
これで、ロードバランサーの構築・DB構築が完了しました。
次回は、ECSクラスター・ECSサービス・SSMアクティベーションの作成を行います。
最後までご覧いただきありがとうございます!
何か疑問に思うことがあれば、何でもいいのでコメントくれれば精一杯答えさせていただきます。
Twitterとかフォローしてくれると嬉しいです。では、次回お会いしましょう!
コメント