#本記事のゴール
https://qiita.com/chanP_yamazaki/items/3691d624a3510236458a
「AWSでwordpressを動かす」1~5までの内容をほぼほぼ網羅した構成をterraformで構築する
参考資料
#terraformのインストール
インストール
公式サイトからバイナリをDLして解凍
https://learn.hashicorp.com/tutorials/terraform/install-cli
$ mkdir -p ~/Applications/terraform
$ mv DLしたterraformファイル ~/Applications/terraform/
$ export PATH=$PATH:~/Applications/terraform/
#プロジェクトのディレクトリ構成
project
┣━ main.tf
┣━ network.tf
┣━ security_group.tf
┣━ key.tf
┣━ ec2.tf
┣━ loadbalancer.tf
┣━ rds.tf
┣━ cloudfront.tf
┣━ scripts
┃ ┣━ apache.sh
┃ ┣━ ftp.sh
┃ ┣━ mysql.sh
┃ ┣━ nfs_master.sh
┃ ┣━ nfs_slave_org.sh
┃ ┣━ php-fpm.sh
┃ ┣━ postfix.sh
┃ ┣━ timezone.sh
┃ ┣━ wordpress_master.sh
┃ ┗━ wordpress_slave.sh
┃
┗━ sshKey
┣━ pubKey
┗━ id_rsa
鍵ファイルの配置
新規に鍵を作成 or 既存の鍵を再利用どちらでも良いので、キーペアをプロジェクトのsshkeyディレクトリ下に配置
公開鍵名称: pubKey
秘密鍵名称: id_rsa
各ファイル
main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.27"
}
}
required_version = ">= 0.14.9"
}
provider "aws" {
access_key = "hogehoge"
secret_key = "hogehoge"
profile = "default"
region = "ap-northeast-1"
}
network.tf
resource "aws_vpc" "wordpress_vpc" {
cidr_block = "10.100.0.0/16"
instance_tenancy = "default"
enable_dns_support = "true"
enable_dns_hostnames = "true"
tags = {
Name = "wordpress_vpc"
}
}
resource "aws_internet_gateway" "wordpress_gw" {
vpc_id = "${aws_vpc.wordpress_vpc.id}"
}
resource "aws_subnet" "public-a" {
vpc_id = "${aws_vpc.wordpress_vpc.id}"
cidr_block = "10.100.1.0/24"
availability_zone = "ap-northeast-1a"
}
resource "aws_subnet" "public-c" {
vpc_id = "${aws_vpc.wordpress_vpc.id}"
cidr_block = "10.100.2.0/24"
availability_zone = "ap-northeast-1c"
}
resource "aws_subnet" "private-a" {
vpc_id = "${aws_vpc.wordpress_vpc.id}"
cidr_block = "10.100.3.0/24"
availability_zone = "ap-northeast-1a"
}
resource "aws_subnet" "private-c" {
vpc_id = "${aws_vpc.wordpress_vpc.id}"
cidr_block = "10.100.4.0/24"
availability_zone = "ap-northeast-1c"
}
resource "aws_route_table" "public-route" {
vpc_id = "${aws_vpc.wordpress_vpc.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.wordpress_gw.id}"
}
}
resource "aws_route_table_association" "puclic-a" {
subnet_id = "${aws_subnet.public-a.id}"
route_table_id = "${aws_route_table.public-route.id}"
}
resource "aws_route_table_association" "puclic-c" {
subnet_id = "${aws_subnet.public-c.id}"
route_table_id = "${aws_route_table.public-route.id}"
}
security_group.tf
resource "aws_security_group" "all_ssh" {
name = "ssh-sg"
vpc_id = "${aws_vpc.wordpress_vpc.id}"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group_rule" "all_ssh_inbound1" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [
"0.0.0.0/0"
]
security_group_id = "${aws_security_group.all_ssh.id}"
}
resource "aws_security_group" "all_vpc" {
name = "all_vpc"
vpc_id = "${aws_vpc.wordpress_vpc.id}"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["10.100.0.0/16"]
}
}
resource "aws_security_group" "all_web" {
name = "all-web"
vpc_id = "${aws_vpc.wordpress_vpc.id}"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group_rule" "all_web_inbound1" {
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = [
"0.0.0.0/0"
]
security_group_id = "${aws_security_group.all_web.id}"
}
resource "aws_security_group" "all_ftp" {
name = "ftp-web"
vpc_id = "${aws_vpc.wordpress_vpc.id}"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group_rule" "all_ftp_inbound1" {
type = "ingress"
from_port = 21
to_port = 21
protocol = "tcp"
cidr_blocks = [
"0.0.0.0/0"
]
security_group_id = "${aws_security_group.all_ftp.id}"
}
resource "aws_security_group_rule" "all_ftp_inbound2" {
type = "ingress"
from_port = 60001
to_port = 60010
protocol = "tcp"
cidr_blocks = [
"0.0.0.0/0"
]
security_group_id = "${aws_security_group.all_ftp.id}"
}
key.tf
resource "aws_key_pair" "ssh_key" {
key_name = "ssh_key"
public_key = file("./sshKey/pubKey")
}
ec2.tf
resource "aws_instance" "master_server" {
ami = "ami-0b276ad63ba2d6009"
instance_type = "t2.micro"
associate_public_ip_address = true
vpc_security_group_ids = [
"${aws_security_group.all_web.id}",
"${aws_security_group.all_ssh.id}",
"${aws_security_group.all_ftp.id}",
"${aws_security_group.all_vpc.id}"
]
subnet_id = "${aws_subnet.public-a.id}"
key_name = "${aws_key_pair.ssh_key.id}"
tags = {
Name = "wordpress_master"
}
provisioner "remote-exec" {
connection {
type = "ssh"
user = "ec2-user"
host = "${self.public_ip}"
private_key = file("./sshKey/id_rsa")
}
scripts = [
"./scripts/timezone.sh",
"./scripts/apache.sh",
"./scripts/mysql.sh",
"./scripts/php-fpm.sh",
"./scripts/wordpress_master.sh",
"./scripts/ftp.sh",
"./scripts/postfix.sh",
"./scripts/nfs_master.sh"
]
}
provisioner "local-exec" {
command = "cp scripts/nfs_slave_org.sh scripts/nfs_slave.sh; sed -ie 's|<MASTER_PRIVATE_IP>|${self.private_ip}|' scripts/nfs_slave.sh"
}
}
resource "aws_instance" "slave_server" {
ami = "ami-0b276ad63ba2d6009"
instance_type = "t2.micro"
associate_public_ip_address = true
vpc_security_group_ids = [
"${aws_security_group.all_ssh.id}",
"${aws_security_group.all_vpc.id}"
]
subnet_id = "${aws_subnet.public-a.id}"
key_name = "${aws_key_pair.ssh_key.id}"
tags = {
Name = "wordpress_slave"
}
provisioner "remote-exec" {
connection {
type = "ssh"
user = "ec2-user"
host = "${self.public_ip}"
private_key = file("./sshKey/id_rsa")
}
scripts = [
"./scripts/timezone.sh",
"./scripts/apache.sh",
"./scripts/mysql.sh",
"./scripts/php-fpm.sh",
"./scripts/wordpress_slave.sh",
"./scripts/nfs_slave.sh"
]
}
depends_on = [
aws_instance.master_server
]
}
loadbalancer.tf
resource "aws_lb_target_group" "wordpress_tg" {
name = "wordpress"
port = 80
protocol = "HTTP"
vpc_id = "${aws_vpc.wordpress_vpc.id}"
}
resource "aws_lb_target_group_attachment" "wordpress_tg1" {
target_group_arn = "${aws_lb_target_group.wordpress_tg.arn}"
target_id = "${aws_instance.master_server.id}"
port = 80
}
resource "aws_lb_target_group_attachment" "wordpress_tg2" {
target_group_arn = "${aws_lb_target_group.wordpress_tg.arn}"
target_id = "${aws_instance.slave_server.id}"
port = 80
}
resource "aws_lb_target_group" "wordpress_master_tg" {
name = "wordpress-master"
port = 80
protocol = "HTTP"
vpc_id = "${aws_vpc.wordpress_vpc.id}"
}
resource "aws_lb_target_group_attachment" "wordpress_master_tg1" {
target_group_arn = "${aws_lb_target_group.wordpress_master_tg.arn}"
target_id = "${aws_instance.master_server.id}"
port = 80
}
resource "aws_lb" "wordpress_lb" {
name = "wordpress"
internal = false
load_balancer_type = "application"
security_groups = ["${aws_security_group.all_web.id}"]
subnets = ["${aws_subnet.public-a.id}", "${aws_subnet.public-c.id}"]
}
resource "aws_lb_listener" "wordpress_lb_listener" {
load_balancer_arn = "${aws_lb.wordpress_lb.arn}"
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = "${aws_lb_target_group.wordpress_tg.arn}"
}
}
resource "aws_alb_listener_rule" "rule_login" {
listener_arn = "${aws_lb_listener.wordpress_lb_listener.arn}"
priority = 1
action {
type = "forward"
target_group_arn = "${aws_lb_target_group.wordpress_master_tg.arn}"
}
condition {
path_pattern {
values = ["/wp-login.php"]
}
}
}
resource "aws_alb_listener_rule" "rule_admin" {
listener_arn = "${aws_lb_listener.wordpress_lb_listener.arn}"
priority = 2
action {
type = "forward"
target_group_arn = "${aws_lb_target_group.wordpress_master_tg.arn}"
}
condition {
path_pattern {
values = ["/wp-admin/*"]
}
}
}
rds.tf
resource "aws_db_subnet_group" "wordpress_db_subnet" {
name = "wordpress"
subnet_ids = ["${aws_subnet.private-a.id}", "${aws_subnet.private-c.id}"]
}
resource "aws_rds_cluster" "wordpress_clustor" {
cluster_identifier = "wordpress"
engine = "aurora-mysql"
engine_version = "5.7.mysql_aurora.2.10.0"
db_subnet_group_name = "${aws_db_subnet_group.wordpress_db_subnet.id}"
availability_zones = ["ap-northeast-1a"]
database_name = "wordpress"
master_username = "root"
master_password = "wordpress"
skip_final_snapshot = "true"
vpc_security_group_ids = ["${aws_security_group.all_vpc.id}"]
}
resource "aws_rds_cluster_instance" "wordpress_clustor_instance" {
count = 1
identifier = "wordpress-db"
cluster_identifier = "${aws_rds_cluster.wordpress_clustor.id}"
instance_class = "db.t3.small"
engine = "${aws_rds_cluster.wordpress_clustor.engine}"
engine_version = "${aws_rds_cluster.wordpress_clustor.engine_version}"
availability_zone = "ap-northeast-1a"
}
cloudfront.tf
resource "aws_cloudfront_distribution" "wordpress_cf" {
enabled = true
is_ipv6_enabled = false
origin {
domain_name = "${aws_lb.wordpress_lb.dns_name}"
origin_id = "${aws_lb.wordpress_lb.id}"
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "http-only"
origin_ssl_protocols = ["TLSv1", "TLSv1.1", "TLSv1.2"]
}
}
default_cache_behavior {
allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "${aws_lb.wordpress_lb.id}"
forwarded_values {
query_string = true
headers = ["Host", "CloudFront-Forwarded-Prot"]
cookies {
forward = "all"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 0
max_ttl = 0
}
ordered_cache_behavior {
path_pattern = "wp-content/uploads/*"
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "${aws_lb.wordpress_lb.id}"
forwarded_values {
query_string = false
headers = ["Host", "CloudFront-Forwarded-Prot"]
cookies {
forward = "none"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 86400
default_ttl = 86400
max_ttl = 86400
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
}
apache.sh
#!/bin/sh
sudo yum -y update
sudo yum install -y httpd
sudo cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org
sudo systemctl start httpd
sudo systemctl enable httpd
ftp.sh
#!/bin/sh
sudo yum install -y vsftpd
sudo cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.org
sudo sed -i 's|anonymous_enable=YES|anonymous_enable=NO|' /etc/vsftpd/vsftpd.conf
sudo sed -i 's|#chroot_local_user=YES|chroot_local_user=YES|' /etc/vsftpd/vsftpd.conf
sudo sed -i 's|#chroot_list_enable=YES|chroot_list_enable=YES|' /etc/vsftpd/vsftpd.conf
sudo sed -i 's|listen=NO|listen=YES|' /etc/vsftpd/vsftpd.conf
sudo sed -i 's|listen_ipv6=YES|listen_ipv6=NO|' /etc/vsftpd/vsftpd.conf
sudo sed -i 's|tcp_wrappers=YES|tcp_wrappers=NO|' /etc/vsftpd/vsftpd.conf
echo -e "pasv_enable=YES\npasv_addr_resolve=YES\npasv_min_port=60001\npasv_max_port=60010\nuse_localtime=YES\nforce_dot_files=YES\nallow_writeable_chroot=YES" | sudo tee -a /etc/vsftpd/vsftpd.conf
sudo touch /etc/vsftpd/chroot_list
sudo systemctl start vsftpd
sudo systemctl enable vsftpd
mysql.sh
#!/bin/sh
sudo yum remove -y mariadb*
sudo yum install -y http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
sudo yum-config-manager --disable mysql55-community
sudo yum-config-manager --enable mysql56-community
sudo yum -y install mysql mysql-devel mysql-server mysql-utilities
sudo cp /etc/my.cnf /etc/my.cnf.org
echo -e "character_set_server=utf8\nskip-character-set-client-handshake" | sudo tee -a /etc/my.cnf
nfs_master.sh
#!/bin/sh
echo "/home/wordpress/wordpress *(rw,no_root_squash)" | sudo tee -a /etc/exports
sudo exportfs -ra
sudo systemctl restart nfs
sudo systemctl enable nfs
nfs_slave_org.sh
#!/bin/sh
echo "<MASTER_PRIVATE_IP>:/home/wordpress/wordpress /home/wordpress/wordpress nfs4 defaults 0 0" | sudo tee -a /etc/fstab
sudo mount /home/wordpress/wordpress
php-fpm.sh
#!/bin/sh
sudo amazon-linux-extras install -y epel
sudo yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
sudo yum install -y --enablerepo=remi-php70 php70-php php70-php-common php70-php-pdo php70-php-cli php70-php-mbstring php70-php-xml php70-php-mysqlnd php70-php-json php70-php-process
cat /opt/remi/php70/enable | sudo tee -a /etc/bashrc
sudo source /etc/bashrc
sudo cp /etc/opt/remi/php70/php.ini /etc/opt/remi/php70/php.ini.org
sed -i 's|;date\.timezone\s*=\s*.*|date\.timezone = "Asia/Tokyo"|' /etc/opt/remi/php70/php.ini
sudo systemctl restart httpd
sudo echo '<?php phpinfo();' | sudo tee /var/www/html/index.php
postfix.sh
#!/bin/sh
sudo yum install -y postfix
sudo systemctl enable postfix
sudo systemctl restart postfix
sudo postmap /etc/postfix/virtual
sudo update-alternatives --set mta /usr/sbin/sendmail.postfix
timezone.sh
#!/bin/sh
sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
echo -e "ZONE="Asia/Tokyo"\nUTC=False" | sudo tee /etc/sysconfig/clock
wordpress_master.sh
#!/bin/bash
sudo useradd -m wordpress
echo wordpress | sudo passwd --stdin wordpress
sudo chmod 775 /home/wordpress
sudo cd /tmp
sudo wget http://ja.wordpress.org/wordpress-4.9.4-ja.tar.gz
sudo tar zxvf wordpress-4.9.4-ja.tar.gz
sudo mv wordpress /home/wordpress/
sudo chown wordpress:wordpress -R /home/wordpress/wordpress
sudo ln -s /home/wordpress/wordpress /var/www/wordpress
sudo chown -R wordpress:wordpress /var/www/wordpress
sudo sed -i 's|DocumentRoot \"/var/www/html\"|DocumentRoot \"/var/www/wordpress\"|' /etc/httpd/conf/httpd.conf
sudo systemctl restart httpd
wordpress_slave.sh
#!/bin/sh
sudo useradd -m wordpress
echo wordpress | sudo passwd --stdin wordpress
sudo mkdir /home/wordpress/wordpress
sudo chmod 775 -R /home/wordpress
sudo chown wordpress:wordpress -R /home/wordpress/wordpress
sudo ln -s /home/wordpress/wordpress /var/www/wordpress
sudo chown -R wordpress:wordpress /var/www/wordpress
sudo sed -i 's|DocumentRoot \"/var/www/html\"|DocumentRoot \"/var/www/wordpress\"|' /etc/httpd/conf/httpd.conf
sudo systemctl restart httpd
terraform実行ユーザーの作成
「AmazonRDSFullAccess / AmazonEC2FullAccess / CloudFrontFullAccess」付きのユーザーを作成し、アクセスキーも作成、その後main.tfにアクセスキー情報を記載する
terraform実行
$ terraform init
$ terraform apply
5分程度で立ち上がります
注意点
セキュリティグループは必要最低限のIPに調整してください