0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

wordpressサイトをterraformで構築する

Posted at

#本記事のゴール
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に調整してください

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?