nisshiee.org

さくっとAWSにWordPressを立てる

2018-12-02

タイトルの通り。
この記事に書くのは、ガチガチに設計・チューニングされたWordPress環境の話ではないので注意。

前提

  • 独自ドメインのDNSをRoute53で管理していて、WordPressはその下に紐付ける
  • CertificateManagerでSSL証明書を管理していて、その証明書を使ったHTTPSのみを提供
  • VPCは新しく作る

構成

  • EC2インスタンス1台
    • 「BitNami(*1)」AMIから作る
  • ALBでSSLを溶かして↑のEC2に投げる
  • Route53でDNSのAレコードをALBに向ける

構築手順

Terraformでインフラ構築

コードは付録を参照。
WordPressとは関係なくよくある構成なのであんまり見どころはないけど、強いて言えば今回使うBitNamiAMIのIDを取得している部分かな。

WordPressの設定を修正

デフォルトじゃ動かないので少し設定をいじる。

何が問題かというと、ブラウザはHTTPSサイトにアクセスしているのに対し、WordPressはSSLを溶かしてくれるALBの背後にいるので自分はHTTPだと思っている。結果、一部のアセットへのリンクがhttp://~~~となってしまったりする。(これぐらいでWordPressやプラグインに対してストレスを溜めるようならWordPressを使うのはやめようw)

$ vi /opt/bitnami/apps/wordpress/htdocs/wp-config.php

以下の1行を適当に入れる。
これにより、アプリケーションは自分がHTTPSを受けているという想定で動く。

$_SERVER['HTTPS'] ='on';

また、デフォルトでは画面にBitNamiアイコンが表示されているので、これを消す。

$ sudo /opt/bitnami/apps/wordpress/bnconfig --disable_banner 1

これで動くはず。

appendix

main.tf

terraform {
  backend "s3" {}
}

provider "aws" {
  region = "ap-northeast-1"
}

# ============================================================
# Variables
# ============================================================
variable "ope_ip" {}
variable "key_name" {}
variable "certificate_arn" {}
variable "zone_id" {}
variable "dns_name" {}

# ============================================================
# Network
# ============================================================

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

resource "aws_internet_gateway" "main" {
  vpc_id = "${aws_vpc.main.id}"
}

resource "aws_route_table" "main" {
  vpc_id = "${aws_vpc.main.id}"

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = "${aws_internet_gateway.main.id}"
  }
}

resource "aws_main_route_table_association" "main" {
  vpc_id         = "${aws_vpc.main.id}"
  route_table_id = "${aws_route_table.main.id}"
}

resource "aws_subnet" "main" {
  vpc_id                  = "${aws_vpc.main.id}"
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "ap-northeast-1a"
  map_public_ip_on_launch = true
}

resource "aws_subnet" "main2" {
  vpc_id                  = "${aws_vpc.main.id}"
  cidr_block              = "10.0.2.0/24"
  availability_zone       = "ap-northeast-1c"
  map_public_ip_on_launch = true
}

# ============================================================
# EC2
# ============================================================

resource "aws_security_group" "main" {
  name        = "site_main"
  description = "site_main"
  vpc_id      = "${aws_vpc.main.id}"

  ingress {
    from_port = 22
    to_port   = 22
    protocol  = "tcp"
    cidr_blocks = ["${var.ope_ip}"]
  }

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["10.0.0.0/16"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

data "aws_ami" "wordpress" {
  most_recent = true

  filter {
    name   = "name"
    values = ["bitnami-wordpress-*-linux-debian-*-x86_64-hvm-ebs"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  filter {
    name   = "root-device-type"
    values = ["ebs"]
  }

  filter {
    name   = "owner-id"
    values = ["979382823631"]
  }
}

resource "aws_instance" "main" {
  ami                    = "${data.aws_ami.wordpress.id}"
  instance_type          = "t3.micro"
  key_name               = "${var.key_name}"
  subnet_id              = "${aws_subnet.main.id}"
  vpc_security_group_ids = ["${aws_security_group.main.id}"]

  credit_specification {
    cpu_credits = "unlimited"
  }

  lifecycle {
    ignore_changes = ["ami"]
  }
}

# ============================================================
# ALB
# ============================================================

resource "aws_security_group" "alb_main" {
  name        = "site_alb_main"
  description = "site_alb_main"
  vpc_id      = "${aws_vpc.main.id}"

  ingress {
    from_port   = 443
    to_port     = 443
    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"]
  }
}

resource "aws_lb" "main" {
  name               = "site-main"
  internal           = false
  load_balancer_type = "application"
  security_groups    = ["${aws_security_group.alb_main.id}"]

  subnets = [
    "${aws_subnet.main.id}",
    "${aws_subnet.main2.id}",
  ]
}

resource "aws_lb_target_group" "main" {
  name     = "site-main"
  port     = 80
  protocol = "HTTP"
  vpc_id   = "${aws_vpc.main.id}"
}

resource "aws_lb_target_group_attachment" "main" {
  target_group_arn = "${aws_lb_target_group.main.arn}"
  target_id        = "${aws_instance.main.id}"
  port             = 80
}

resource "aws_lb_listener" "main" {
  load_balancer_arn = "${aws_lb.main.arn}"
  port              = "443"
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-2016-08"
  certificate_arn   = "${var.certificate_arn}"

  default_action {
    type             = "forward"
    target_group_arn = "${aws_lb_target_group.main.arn}"
  }
}

# ============================================================
# DNS
# ============================================================

resource "aws_route53_record" "main" {
  zone_id = "${var.zone_id}"
  name    = "${var.dns_name}"
  type    = "A"

  alias {
    name                   = "${aws_lb.main.dns_name}"
    zone_id                = "${aws_lb.main.zone_id}"
    evaluate_target_health = false
  }
}

*1
AWSの公式ドキュメントでも紹介されている