Re:boot!

35歳からのエンジニアWay

ロードバランス用にpacker+ansibleでAPサーバ用AMIを作成する

前回までのエントリで、一般的なAPサーバ+DBサーバ(RDS)という構成は作る事ができたので、次はAPサーバを2台にしてELBでロードバランシングしてみたいと思います。

ELBはAWSのL7ロードバランサ機能ですね。ここでは一旦ELBは置いておいて今回はAPサーバを増やす下準備をしたいと思います。

前回もansibleを使ったので比較的手間なくnginx,wordpressのインストールを行えましたが、毎回マネージメントコンソールでEC2インスタンスを作る所からやるのは手間です。

趣味や勉強でやる程度の数ならまだしも、実運用で何十台と同じ役割をするインスタンスを作るとなると流石にやってられません。

そこで登場するのがpacker(とterraform)です。packerを使えば役割毎のAMI(雛形となるOSイメージ)を簡単に作る事が出来るようです。

ということで今回はWordpressを動かすAPサーバをpackerでAMI化してみたいと思います。

packerとはどんなもの?

packerがどんなものなのかは下記の記事が参考になりました。

thinkit.co.jp

packerは(仮想)マシン上に展開するOSのイメージを作るツールです。

AWSはもちろん、他のクラウドサービスやDockerのイメージも作成できるらしいです。

公式サイトは以下。

www.packer.io

今回はpakcerを使ってAMIを作るのですが、packerを使えばコンフィグを各だけで以下の様な事をやってくれます。

はい、こんな感じです。まあ使ってみないと良くわかんないので、さっさと触っていきたいと思います。

packerでAMIイメージを作る

まずはpackerをインストールします。Macならhomebrewでサクッとインストールできます。

$ brew tap homebrew/binary
$ brew install terraform
$ pakcer -v
#=> 0.10.1

v0.10.1がインストールされました。作成するAMI用の設定ファイルを作ります。今回は下記の設定ファイルを前回とってきたansibleのディレクトリに「wordpress.json」という名前で保存しました。

{
  "builders": [{
    "type": "amazon-ebs",
    "region": "ap-northeast-1",
    "source_ami": "ami-9f0c67f8",
    "ami_name": "aws-wordpress",
    "instance_type": "t2.micro",
    "vpc_id": "vpc-xxxxxxxx",
    "subnet_id": "subnet-xxxxxxxx",
    "associate_public_ip_address": true,
    "ssh_username": "ec2-user",
    "ssh_timeout": "5m",
    "ssh_pty": "true",
    "security_group_id": "sg-xxxxxxxx"
  }],
  "provisioners":[{
    "type": "shell",
    "inline": [
      "sudo yum -y update",
      "sudo yum -y --enablerepo=epel install ansible",
      "mkdir -p /tmp/ansible-local"
    ]
  }, {
    "type": "file",
    "source": "./",
    "destination": "/tmp/ansible-local"
  }, {
    "type": "ansible-local",
    "playbook_file": "site.yml",
    "role_paths": [
      "roles"
    ],
    "staging_directory": "/tmp/ansible-local"
  }]
}

サラっと書きましたが、このファイルを作るにはちょっとばかり試行錯誤しました。

見ればなんとなくわかるところも多いと思うので、ポイントとなりそうな部分だけ説明してみようと思います。

buildersの項目

作成するAMIの基本的な設定を記述するセクションですね。

type 作成するイメージの種類(AWS用、DegitalOcean用、VMWare用...など)、今回はAWSのEC2インスタンスのAMIなので「amazon-ebs」にしてあります。

source_ami 作成するAMIの元となるイメージのIDです。AMIは色々な物が用意されていますが、今回は新規インスタンスを立ち上げる時に選択できる、Amazon LinuxのAMI IDを指定してあります。

f:id:yusan09:20170112000947j:plain

ami_name 作成するAMIの名前です。

ssh_timeout ec2インスタンスの作成作業をした後、実際にsshでログイン出来る様になるまでには(初期化作業が走るため)少しタイムラグがあります。

初期化に少し時間がかかっても大丈夫なように、ssh_timeoutを少し長めに設定してあります。

associate_public_ip_address 例えばローカルでDockerイメージを作る場合などは必要ないですが、今回の様にEC2インスタンスを使ってAMIを作る場合はインスタンスsshでログインする必要が出てきます。

associate_public_ip_addressをtrueにすることでグローバルIPインスタンスに付与し、SSHでのログインを可能にしています。

provisioners

名前の通りプロビジョニングに関する設定を各ことです。やることは前回のansibleファイルを実行するだけなのですが、EC2インスタンスのローカル上でansibleを実行するために、少し手間がかかっています。

どういうことをしているのか簡単にまとめると

  • ansibleを実行するために、yumでansibleをインストールする
  • 実行するansibleのファイル一式をローカルからEC2インスタンスに送る
  • ansibleを実行する

といった感じです。

ansibleをEC2ローカルで実行する(ansible-local)ための設定は下記が非常に参考になりました。

qiita.com

設定が終われば後はbuildを実行してイメージを作成するだけです。

$ packer build wordpress.json

成功すると下記の様にAMIの項目の中に自分で作成したイメージが表示されます。後はこのAMIを使ってEC2インスタンスを立ち上げるだけです。しかし、EC2インスタンスの立ち上げに関してもマネージメントコンソールは使いたくないので、次回terraformを使った方法を試してみたいと思います。

f:id:yusan09:20170112234647j:plain