LoginSignup
94
23

More than 5 years have passed since last update.

[初心者歓迎] Packer + Ansible + TerraformでWordPressを構築

Last updated at Posted at 2016-12-13

この記事はフロムスクラッチ Advent Calendar 2016の13日目の記事です。

1. はじめに。

「Keep it Simple, stupid! But fail fast! learn a lot!」

ショック.png
   ↓↓↓
考える人.png

いかに素早く失敗して
そこから学ぶかが重要だと思う今日この頃。
ご機嫌いかがでしょうか?jkです。

2. 想定読者

  1. 最近っぽいインフラをやってみたい人
  2. アプリの人でインフラをちょっとかじってみたい人
  3. hashicorpツールをちょっとかじったことある人

3. インフラは、インフラだけのものではない。

いろいろな場面で、以下のようなシーンがある気がする。

「これは、インフラの問題だろ!」
「いやいや、アプリの使い方が悪いんだろ!」

もうどうでもいい。みんな全部やれ!笑笑

ということで
なんか開発の人でも、ぱっとできそうな感じで
インフラ構築「やってみた」を、紹介したいと思います。

4. 今回使うツール

主に、最近流行りの
hashicorpのツールから
「Packer」と「Terraform」に関して、簡単に紹介します。
Terraformは結構紹介されているのですが
Packerに関してはあまり紹介されていない気がするので
まずは、簡単にPackerの紹介。

5. Packer導入のメリット・デメリット

◆ メリット

  • プロビジョニング処理
  • 類似の環境構築時の容易化
  • Packer + Ansibleで作成したイメージでの、バージョン管理

◆ デメリット

  • ミドルウェアのバージョンアップを忘れそう。(セキュリティ等)
  • 統合管理する無料ツールがない。(Atlasは有料・・・?) https://www.hashicorp.com/atlas.html
  • まだ開発途中(v0.12.0)なので、できないこともしばしば。

6. 早速、実際にやってみる

◆ やること

Packer + AnsibleでWordpressをインストールされたAWS AMIを作成し
そのAMIを元に、Terraformで、サーバー構築すること

◆ 前提

  1. Wordpressのansibleのソースコードは以下が、ベース。 https://github.com/ansible/ansible-examples/tree/master/wordpress-nginx
  2. 各種バージョン
    1. packer 0.12.0
    2. ansible 2.2.0.0
    3. Terraform v0.7.4

あとは、基本的には、ここみればok。
https://github.com/jkkitakita/hashicorp
以下、主要な部分抜粋。

Packer + Ansible

variables.json
{
  "scripts_dir": "scripts",
  "ssh_username": "ec2-user",
  "aws_region": "ap-northeast-1",
  "aws_instance_type": "t2.micro",
  "aws_environment": "production",
  "aws_source_ami_id": "ami-########"
}
packer-wordpress.json
{
  "builders": [{
    "type": "amazon-ebs",
    "region": "{{user `aws_region`}}",
    "source_ami": "{{user `aws_source_ami_id`}}",
    "instance_type": "{{user `aws_instance_type`}}",
    "ssh_username": "{{user `ssh_username`}}",
    "ssh_timeout": "5m",
    "ami_name": "Packer-ansible-{{timestamp}}",
    "tags": {
      "Name": "aws-{{user `aws_region`}}",
      "Environment": "{{user `aws_environment`}}",
      "Release": "Latest"
    }
  }],
  "provisioners": [
    {
      "type": "shell",
      "execute_command": "echo {{user `ssh_username`}} | {{ .Vars }} sudo -E -S sh '{{ .Path }}'",
      "inline": [
        "mkdir -p /ops/{{user `scripts_dir`}}",
        "chmod a+w /ops/{{user `scripts_dir`}}"
      ]
    },
    {
      "type": "file",
      "source": "{{user `scripts_dir`}}/.",
      "destination": "/ops/{{user `scripts_dir`}}"
    },
    {
      "type": "shell",
      "execute_command": "echo {{user `ssh_username`}} | {{ .Vars }} sudo -E -S sh '{{ .Path }}'",
      "inline": [
        "bash /ops/{{user `scripts_dir`}}/bootstrap.sh",
        "bash /ops/{{user `scripts_dir`}}/ansible.sh"
      ]
    },
    {
      "type": "ansible-local",
      "group_vars": "./ansible/group_vars",
      "playbook_file": "./ansible/site.yml",
      "role_paths": ["./ansible/roles/common", "./ansible/roles/mysql", "./ansible/roles/nginx", "./ansible/roles/php-fpm", "./ansible/roles/wordpress"],
      "staging_directory": "/tmp/packer-provisioner-ansible-local"
    }
  ]
}

実際に実行。

~/hashicorp/packer

 ~/h/packer ❯❯❯ packer build -var-file=variables.json packer-wordpress.json
amazon-ebs output will be in this color.

==> amazon-ebs: Prevalidating AMI Name...
    amazon-ebs: Found Image ID: ami-504f2037

~~ 中略 ~~

Build 'amazon-ebs' finished.

==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs: AMIs were created:

ap-northeast-1: ami-504f2037
 ~/h/packer ❯❯❯

→ 作成されたAMI: ami-504f2037

Terraform

main.tf
provider "aws" {
  region = "${var.region}"
}
variable.tf
provider "aws" {
  region = "${var.region}"
}
 ~/h/terraform ❯❯❯ more variables.tf
variable "region" {
  default = "ap-northeast-1"
}

variable "ec2_config" {
  default = {
    key_name            = "jkkitakita"
    instance_type       = "t2.micro"
  }
}
wordpress.tf
data "aws_ami" "wordpress" {
  filter {
    name = "state"
    values = ["available"]
  }
  filter {
    name = "tag:Release"
    values = ["Latest"] // PackerでAMI作成時につけたタグ
  }
  most_recent = true // 一番新しいものを取得
}

resource "aws_instance" "wordpress" {
  ami           = "${data.aws_ami.wordpress.id}"
  key_name      = "${lookup(var.ec2_config, "key_name")}"
  instance_type = "${lookup(var.ec2_config, "instance_type")}"
  tags {
      "Name" = "${format("wordpress%02d", count.index + 1)}"
  }
}

Dry-runからの、terraform実行

 ~/h/terraform ❯❯❯ terraform apply
data.aws_ami.wordpress: Refreshing state...
aws_instance.wordpress: Creating...
  ami:                      "" => "ami-504f2037" // Packerで作成したAMIを取得できてる。
  availability_zone:        "" => "<computed>"
  ebs_block_device.#:       "" => "<computed>"
  ephemeral_block_device.#: "" => "<computed>"
  instance_state:           "" => "<computed>"
  instance_type:            "" => "t2.micro"
  key_name:                 "" => "jkkitakita"
  network_interface_id:     "" => "<computed>"
  placement_group:          "" => "<computed>"
  private_dns:              "" => "<computed>"
  private_ip:               "" => "<computed>"
  public_dns:               "" => "<computed>"
  public_ip:                "" => "<computed>"
  root_block_device.#:      "" => "<computed>"
  security_groups.#:        "" => "<computed>"
  source_dest_check:        "" => "true"
  subnet_id:                "" => "<computed>"
  tags.%:                   "" => "1"
  tags.Name:                "" => "wordpress01"
  tenancy:                  "" => "<computed>"
  vpc_security_group_ids.#: "" => "<computed>"
aws_instance.wordpress: Still creating... (10s elapsed)
aws_instance.wordpress: Still creating... (20s elapsed)
aws_instance.wordpress: Creation complete

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.

State path: terraform.tfstate
 ~/h/terraform ❯❯❯

スクリーンショット 2016-12-13 17.49.14.png

7. つまづいた&苦労したところ

  1. pipのバージョンを合わせるのに少し手こずった。

  2. mysql-pythonのバージョンはansible-exampleをそのまま使えなかったので、role/mysqlの方にタスクを追加した。

  3. terraformのsyntaxに引っかかった。。。(Invalid dot index found)
    http://qiita.com/kenjiskywalker/items/766859ac550650df4530

  4. packerのprovisionorで、ansible(remote)でやろうとしたが、うまくいかなかったので、ansible(local)で書いた。(なんでうまくいかなかったのか忘れた。。)
    https://www.packer.io/docs/provisioners/ansible-local.html

8. 今後やりたいこと

まだまだ「おもちゃ感」がすごいので、なんかちゃんと書きたい。

  1. packer
    1. 複数種類のイメージ管理 【やりたい!】
    2. ansible以外の構成管理ツールとの連携 【やりたい!】
  2. ansible
    1. ワードプレスの構成はコピーしただけなので、見直し
    2. 全くバージョン指定していないので、ちゃんとしたバージョン管理
    3. とりあえずなんでもかんでも、become(旧sudo)を入れているので、見直し
    4. ダイナミックインベントリとかも使ってみたい。
  3. Terraform
    1. S3などでのバージョン管理 【やりたい!】
  4. packer→terraformの連携が「タグ」と「起動時刻」で判定しているから不安でしかない。 → Atlasが無料で使えれば・・・ 【やりたい!】
  5. Serverspec等による構成のテスト 【やりたい!】
  6. オートスケーリング 【やりたい!】
  7. Blue/Greenデプロイ 【やりたい!】
  8. Slackからのサーバー構築&自動デプロイ(チャットボット)【やりたいが...】
  9. AWSだけでなく、GCPでもやってみたい。

9. まとめ

hashicorpのツールはまだまだ発展途上のものが多いが
すごい期待できそうな感じだった。
各種ツールでも同じようなツールがあるはずなので
それも今後試していこうと思います。
皆さんも簡単なので、試してみてください(`・ω・´)キリッ

94
23
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
94
23