🌟
【Terraform】EC2とRDSでWPをインストールしてみる
はじめに
下記の構成をTerraformで作成していきます。
- EC2
- AMI
- Amazon Linux 2 AMI (HVM) - Kernel 5.10, SSD Volume Type
- インスタンスタイプ
- t2.micro
- AMI
- RDS
- DB
- Mysql 8.0.40
- インスタンスタイプ
- t3.micro
- マルチAZ
- DB
ファイル構成
.
├── architecture.drawio
├── ec2.tf
├── keypair.tf
├── main.tf
├── network.tf
├── providers.tf
├── rds.tf
├── securitygroup.tf
├── terraform.tfstate
├── terraform.tfstate.backup
├── terraform.tfvars
├── userdata.sh
└── variable.tf
バージョン設定
provider.tf
#------------------
# Terraform configuration
#------------------
terraform {
required_version = ">=1.10"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
profile = "udemy_terraform"
region = "ap-northeast-1"
}
tfstateをS3で管理できるようにする
- マネジメントコンソールからS3バケットを作成
- ブロックパブリックアクセスをオフにしておく
- バケットポリシーの作成(ポリシージェネレータを使用)
- ブロックパブリックアクセスをオンにしておく
- terraformブロックにbackend属性を追加
-
terraform init
で初期化
provider.tf
#------------------
# Terraform configuration
#------------------
terraform {
backend "s3" {
bucket = "terraform-wp-dev-tfstate"
region = "ap-northeast-1"
key = "terraform.tfstate"
profile = "udemy_terraform"
}
}
VPC作成
network.tf
#------------------
# VPC
#------------------
resource "aws_vpc" "vpc" {
cidr_block = "10.0.0.0/24"
instance_tenancy = "default"
enable_dns_hostnames = true
enable_dns_support = true
assign_generated_ipv6_cidr_block = false
tags = {
Name = "${var.project}-${var.environment}-vpc"
Project = var.project
Env = var.environment
}
}
サブネットの作成
network.tf
#------------------
# Subnet
#------------------
resource "aws_subnet" "public-subnet-1a" {
vpc_id = aws_vpc.vpc.id
availability_zone = "ap-northeast-1a"
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
tags = {
Name = "${var.project}-${var.environment}-public-subnet-1a"
Project = var.project
Env = var.environment
Type = "public"
}
}
resource "aws_subnet" "private-subnet-1a" {
vpc_id = aws_vpc.vpc.id
availability_zone = "ap-northeast-1a"
cidr_block = "10.0.2.0/24"
map_public_ip_on_launch = false
tags = {
Name = "${var.project}-${var.environment}-private-subnet-1a"
Project = var.project
Env = var.environment
Type = "private"
}
}
resource "aws_subnet" "private-subnet-1c" {
vpc_id = aws_vpc.vpc.id
availability_zone = "ap-northeast-1c"
cidr_block = "10.0.3.0/24"
map_public_ip_on_launch = false
tags = {
Name = "${var.project}-${var.environment}-private-subnet-1c"
Project = var.project
Env = var.environment
Type = "private"
}
}
インターネットゲートウェイとルートテーブルの作成
network.tf
#------------------
# internet gateway
#------------------
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = "${var.project}-${var.environment}-igw"
Project = var.project
Env = var.environment
}
}
#------------------
# Route table
#------------------
resource "aws_route_table" "rt" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = "${var.project}-${var.environment}-rt"
Project = var.project
Env = var.environment
}
}
resource "aws_route" "route" {
route_table_id = aws_route_table.rt.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
resource "aws_route_table_association" "rt-public-1a" {
route_table_id = aws_route_table.rt.id
subnet_id = aws_subnet.public-subnet-1a.id
}
セキュリティグループの作成
securitygroup.tf
#------------------
# Security Group
#------------------
resource "aws_security_group" "app-sg" {
name = "app-sg"
description = "Webserver security group"
vpc_id = aws_vpc.vpc.id
tags = {
Name = "${var.project}-${var.environment}-app-sg"
Project = var.project
Env = var.environment
}
}
resource "aws_security_group" "db-sg" {
name = "db-sg"
description = "DBserver security group"
vpc_id = aws_vpc.vpc.id
tags = {
Name = "${var.project}-${var.environment}-db-sg"
Project = var.project
Env = var.environment
}
}
resource "aws_security_group_rule" "app-ssh" {
security_group_id = aws_security_group.app-sg.id
type = "ingress"
from_port = "22"
to_port = "22"
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "app-http" {
security_group_id = aws_security_group.app-sg.id
type = "ingress"
from_port = "80"
to_port = "80"
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "app-all" {
security_group_id = aws_security_group.app-sg.id
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "app-mysql" {
security_group_id = aws_security_group.app-sg.id
type = "egress"
from_port = "3306"
to_port = "3306"
protocol = "tcp"
source_security_group_id = aws_security_group.db-sg.id
}
resource "aws_security_group_rule" "db-tcp" {
security_group_id = aws_security_group.db-sg.id
type = "ingress"
from_port = "3306"
to_port = "3306"
protocol = "tcp"
source_security_group_id = aws_security_group.app-sg.id
}
RDSの作成
今回はデフォルトのパラメーターグループで作成しました。
rds.tf
#------------------
# RDS
#------------------
resource "aws_db_subnet_group" "mysql-subnetgroup" {
name = "${var.project}-${var.environment}-mysql-subnetgroup"
description = "DB Subnet Group"
subnet_ids = [aws_subnet.private-subnet-1a.id, aws_subnet.private-subnet-1c.id]
tags = {
Name = "${var.project}-${var.environment}-mysql-subnetgroup"
Project = var.project
Env = var.environment
}
}
resource "aws_db_instance" "mysql_db" {
#基本設定
engine = "mysql"
engine_version = "8.0.40"
identifier = "${var.project}-${var.environment}-mysql"
username = var.db_username
password = var.db_password
instance_class = "db.t3.micro"
#ストレージ
allocated_storage = 20
max_allocated_storage = 50
storage_type = "gp2"
storage_encrypted = false
#ネットワーク
multi_az = true
db_subnet_group_name = aws_db_subnet_group.mysql-subnetgroup.name
vpc_security_group_ids = [aws_security_group.db-sg.id]
publicly_accessible = false
port = 3306
#DB設定
db_name = "wp_terraform_db"
#バックアップ
backup_window = "04:00-05:00"
backup_retention_period = 7
maintenance_window = "Mon:05:00-Mon:08:00"
auto_minor_version_upgrade = false
#削除防止
deletion_protection = false
skip_final_snapshot = true
apply_immediately = true
tags = {
Name = "${var.project}-${var.environment}-mysqldb"
Project = var.project
Env = var.environment
}
}
EC2の作成
ec2.tf
#------------------
# EC2
#------------------
data "aws_ami" "app" {
most_recent = true
owners = ["self", "amazon"]
filter {
name = "name"
values = ["amzn2-ami-kernel-5.10-hvm-2.0.*.0-x86_64-gp2"]
}
filter {
name = "root-device-type"
values = ["ebs"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
#------------------
#EC2 Instance
#------------------
resource "aws_instance" "app_server" {
#基本設定
ami = data.aws_ami.app.id
instance_type = "t2.micro"
#ネットワーク
subnet_id = aws_subnet.public-subnet-1a.id
associate_public_ip_address = true
vpc_security_group_ids = [aws_security_group.app-sg.id]
#その他
key_name = aws_key_pair.keypair.key_name
user_data = file("./userdata.sh")
tags = {
Name = "${var.project}-${var.environment}-app-ec2"
Project = var.project
Env = var.environment
Type = "app"
}
}
userdata.sh
#!/bin/bash
yum update -y
##php
amazon-linux-extras install php7.2 -y
yum -y install mysql httpd php-mbstring php-xml
##wp
wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
tar zxvf /tmp/latest-ja.tar.gz -C /tmp
cp -r /tmp/wordpress/* /var/www/html/
## Apache Setup
chown -R apache:apache /var/www/html
systemctl start httpd
systemctl enable httpd
EC2にssh接続
- キーペアを作成し、適切なフォルダに格納
$ ssh-keygen -t rsa -b 2048 -f 作成したい鍵の名前
- キーペアを登録
keypair.tf
resource "aws_key_pair" "keypair" {
key_name = "${var.project}-${var.environment}-keypair"
public_key = file("pubキーを置いたパス")
tags = {
Name = "${var.project}-${var.environment}-keypair"
}
}
- ssh接続
$ ssh -i 秘密鍵のパス ec2-user@パブリックIP
- userdata.shの内容が反映されているか確認
WPの設定
下記でRDSの内容を設定。
- データベース名 : RDSで設定した
db_name
- ユーザー名 : RDSで設定した
username
- パスワード : RDSで設定した
password
- ホスト名 : RDSのエンドポイント(〜.ap-northeast-1.rds.amazonaws.com)
成功!
感想
- 一から自分で作成してみることで理解が深まった!
- パブリックサブネットのセキュリティグループのアウトバウンドが解放されていなかった為、ec2.tfのuserdata.shが実行されていなかった。
- moduleやoutputなどを使用し、効率的にコーディングしていきたい。
Discussion