0
0

Terraformによるスケーラブルウェブサイト構築

Last updated at Posted at 2023-07-23

はじめに

  • (Terraformに慣れるために)AWS CLIで構築したスケーラブルなウェブサイト環境を手順と資料を合わせてアウトプット資料としてまとめます。
  • 個人的に気づいたことも付け加えていこうと思います。

構成図

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333530313630352f39386333393837622d663933322d396530652d6235626.png

手順

main.tf
# ---------------------------
# プロバイダ設定
# ---------------------------
# AWS
provider "aws" {
  region     = "ap-northeast-1"
}

# 自分のパブリックIPを取得する
provider "http" {}

VPCの作成

vpc.tf
#---
#VPCの作成
#---
resource "aws_vpc" "test" {
  cidr_block       = "10.0.0.0/16"
  enable_dns_hostnames = "true"

  tags = {
    Name = "test"
  }
}

#---
#サブネットの作成
#---
resource "aws_subnet" "test-public-1a" {
  vpc_id     = aws_vpc.test.id
  cidr_block = "10.0.0.0/24"
  availability_zone = "${var.az_a}"

  tags = {
    Name = "test-public-1"
  }
}

resource "aws_subnet" "test-public-1c" {
  vpc_id     = aws_vpc.test.id
  cidr_block = "10.0.1.0/24"
  availability_zone = "${var.az_c}"

  tags = {
    Name = "test-public-2"
  }
}

resource "aws_subnet" "test-private-1a" {
  vpc_id     = aws_vpc.test.id
  cidr_block = "10.0.2.0/24"
  availability_zone = "${var.az_a}"

  tags = {
    Name = "test-private-1"
  }
}

resource "aws_subnet" "test-private-1c" {
  vpc_id     = aws_vpc.test.id
  cidr_block = "10.0.3.0/24"
  availability_zone = "${var.az_c}"

  tags = {
    Name = "test-private-2"
  }
}

#---
#IGWの作成
#---
resource "aws_internet_gateway" "test-igw" {
  vpc_id = aws_vpc.test.id

  tags = {
    Name = "test-igw"
  }
}

#---
#ルートテーブルの作成
#---
resource "aws_route_table" "test-public" {
  vpc_id = aws_vpc.test.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.test-igw.id
  }
  tags = {
    Name = "test-public"
  }
}

#---
#ルートテーブルの関連付け
#---
resource "aws_route_table_association" "test-public-1a" {
  subnet_id      = aws_subnet.test-public-1a.id
  route_table_id = aws_route_table.test-public.id
}

resource "aws_route_table_association" "test-public-1c" {
  subnet_id      = aws_subnet.test-public-1c.id
  route_table_id = aws_route_table.test-public.id
}

#---
#セキュリティグループの作成
#---
#EC2
resource "aws_security_group" "test-web" {
  name        = "test-web"
  description = "test-web sg"
  vpc_id      = aws_vpc.test.id

  ingress {
    description      = "ssh"
    from_port        = 22
    to_port          = 22
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }

  ingress {
    description      = "http"
    from_port        = 80
    to_port          = 80
    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 = "test-web"
  }
}

#RDS
resource "aws_security_group" "test-rds" {
  name        = "test-rds"
  description = "test-rds-sg"
  vpc_id      = aws_vpc.test.id
  ingress {
    from_port   = 3306
    to_port     = 3306
    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 = "test-rds"
  }
}

#ELB
resource "aws_security_group" "test-elb" {
  name        = "test-elb"
  description = "test-elb-sg"
  vpc_id      = aws_vpc.test.id
  ingress {
    from_port   = 80
    to_port     = 80
    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 = "test-elb"
  }
}

EC2の作成

ec2.tf
# Amazon Linux 2 の最新AMIを取得する
data "aws_ssm_parameter" "amzn2_latest_ami" {
  name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
}

#キーペアの作成
variable "key_name" {
  default = "test-keypair"
}

# 秘密鍵のアルゴリズム設定
resource "tls_private_key" "private_key" {
  algorithm = "RSA"
  rsa_bits  = 2048
}

# PCにキーペアを作成
locals {
  public_key_file  = "C:\\terraform_handson\\${var.key_name}.id_rsa.pub"
  private_key_file = "C:\\terraform_handson\\${var.key_name}.id_rsa"
}

resource "local_file" "private_key_pem" {
  filename = "${local.private_key_file}"
  content  = "${tls_private_key.private_key.private_key_pem}"
}

# 上記で作成した公開鍵をAWSのKey pairにインポート
resource "aws_key_pair" "keypair" {
  key_name   = "${var.key_name}"
  public_key = "${tls_private_key.private_key.public_key_openssh}"
}

#EC2の作成
resource "aws_instance" "test-ec2" {
  ami                         = data.aws_ssm_parameter.amzn2_latest_ami.value
  instance_type               = "t2.micro"
  availability_zone           = "${var.az_a}"
  vpc_security_group_ids      = [aws_security_group.test-web.id]
  subnet_id                   = aws_subnet.test-public-1a.id
  associate_public_ip_address = "true"
  key_name                    = "${var.key_name}"
  user_data = file("userdata.sh")
  tags = {
    Name = "test-web-instance-1a"
  }

}

RDSの作成

rds.tf
#---
#RDSサブネットグループの作成
#---
resource "aws_db_subnet_group" "test-db-subnet" {
  name       = "test-db-subnet"
  subnet_ids = [aws_subnet.test-private-1a.id, aws_subnet.test-private-1c.id]

  tags = {
    Name = "test-db-subnet"
  }
}

#---
#インスタンスの作成
#---
resource "aws_db_instance" "test-db" {
  allocated_storage    = 20
  db_name              = "test-db"
  engine               = "mysql"
  engine_version       = "8.0.28"
  instance_class       = "db.t3.micro"
  username             = "test"
  password             = "password"
  backup_retention_period = 0
  db_subnet_group_name = "test-db-subnet"

  skip_final_snapshot  = true
  multi_az = true

  tags = {
          Name = "test-rds"
  }
}

ELBの作成

elb.tf
#---
#ALBの作成
#---
resource "aws_lb" "test" {
  name               = "test-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.lb_sg.id]
  subnets            = [aws_subnet.test-public-1a.id,aws_subnet.test-public-1c.id]
  ip_address_type    = "ipv4"

  enable_deletion_protection = true

  tags = {
  	name = "test-alb"
  }
}

#---
#ターゲットグループの作成
#---
resource "aws_lb_target_group" "test-target" {
  name     		= "test-target"
  target_type	= "instance"
  port     		= 80
  protocol 		= "HTTP"
  vpc_id   		= aws_vpc.test.id
  
  tags			= {
  	name		= "test-elb"
	}

  health_check {
  	protocol	= "HTTP"
  	path		= "/"
  	}
}

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

#ターゲットグループにインスタンスを登録
"##1台目
resource "aws_lb_target_group_attachment" "test-target-1" {
  target_group_arn = aws_lb_target_group.test-target.arn
  target_id        = aws_instance.test.id
  port             = 80
}

##2台目
resource "aws_lb_target_group_attachment" "test-target-2" {
  target_group_arn = aws_lb_target_group.test-target.arn
  target_id        = aws_instance.test.id
  port             = 80
}

#---
#リスナー設定
#---
resource "aws_lb_listener" "test-listnet" {
  load_balancer_arn = aws_lb.test.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.test-target.arn
  }
}

AMIの作成

ami.tf
#---
#AMIの作成
#---
resource "aws_ami_from_instance" "test-ami" {
  name               = "test-ec2-ami"
  source_instance_id = "i-xxxxxxxx"
}

作成したAMIをもとに、EC2を作成します。

Terraformレジストリ

VPC

RDS

ELB

AMI

補足

複数台のEC2を構築したいとき、異なるAZ間に配置したいときの

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0