積極的後進

後ろ向きに全力ダッシュ

AnsibleとPackerを使ってAWS上にWordPressを展開するDocker Imageを作成する

概要

Ansible入門として,Amazon Linuxイメージを展開したDockerコンテナ上にWordPress環境を構築するplaybookを作成する. また,ローカルでのDockerコンテナ生成からplaybook適用後のDocker Imageの生成までを,Packerを用いて一括して行うようにする.

今回はAWS上に展開することを想定して各種ファイルを作成したが,実際にWordpressAWS上に展開する場合はAWS Marketplaceを利用した方が圧倒的に楽なのでそちらを使うべきだろう.

Docker

amazonlinuxイメージをpullしておく. テスト環境として,

% docker run -i -t -d --name aws -p 3000:80 amazonlinux

としてコンテナを生成し,ここに向けてansibleを実行する.

Ansible

下準備

playbook.ymlをローカルで作成し,上記で作成したdockerコンテナ上に流し込む. 実行前にansibleで使用するhostsファイルを作成する. Ansible 2.0以降はDocker Connectionが使用できるので,下記のようなファイルをローカルに作成する.

[docker]
aws

上記をdockerHostsというファイル名で保存しておく.ansible-playbook時に使用する.

playbook

実際のplaybookを作成する. 今回は下記のようなplaybookになる. wordpress周りの各種設定はAWSガイドラインそのままなので,適宜変更・追加が必要になる.

- hosts: all
  connection: docker
  # 初期設定
  # mysql周りのパラメーター
  vars:
    mysql_user: "wordpress-user"
    mysql_password: "hogehogehoge"
    mysql_database: "wordpress_db"
  tasks:
  # 各種パッケージのインストール(vimは趣味)
  - name: install yum packages
    yum: name={{item}} state=latest
    with_items:
    - vim
    - httpd
    - mysql
    - mysql-devel
    - mysql-server
    - php
    - php-devel
    - php-mysql
    - php-mbstring
    - php-gd
    - MySQL-python27
    - MySQL-python
  # wordpressのダウンロードと展開
  - name: wordpress download
    get_url: url="https://wordpress.org/latest.tar.gz" dest=/wordpress-latest.tar.gz
  - name: unarchive wordpress
    command: tar -xzf /wordpress-latest.tar.gz chdir=/var/www/html
  # mysqld起動のためのネットワーク設定,mysqld起動
  - name: network settings for mysql
    shell: echo "NETWORKING=yes" >/etc/sysconfig/network
  - name: enable mysqld
    service: name=mysqld state=started enabled=yes
  # dbとuserの作成,権限設定
  - name: create mysql database
    mysql_db:
        name: "{{mysql_database}}"
        state: present
  - name: create mysql user
    shell: |
      mysql << " _EOF_"
      CREATE USER "{{mysql_user}}"@'localhost' IDENTIFIED BY "{{mysql_password}}";
      GRANT ALL PRIVILEGES ON `{{mysql_database}}`.* TO "{{mysql_user}}"@"localhost";
      FLUSH PRIVILEGES;
      _EOF_
  # wordpress設定ファイルの作成
  - name: config wordpress
    lineinfile:
      dest: /var/www/html/wordpress/wp-config.php
      create: yes
      insertafter: yes
      line: |
        <?php
          define('DB_NAME', '{{mysql_database}}');
          define('DB_USER', '{{mysql_user}}');
          define('DB_PASSWORD', '{{mysql_password}}');
          define('DB_HOST', 'localhost');
          define('DB_CHARSET', 'utf8');
          define('DB_COLLATE', '');
          define('AUTH_KEY',         'put your unique phrase here');
          define('SECURE_AUTH_KEY',  'put your unique phrase here');
          define('LOGGED_IN_KEY',    'put your unique phrase here');
          define('NONCE_KEY',        'put your unique phrase here');
          define('AUTH_SALT',        'put your unique phrase here');
          define('SECURE_AUTH_SALT', 'put your unique phrase here');
          define('LOGGED_IN_SALT',   'put your unique phrase here');
          define('NONCE_SALT',       'put your unique phrase here');
          $table_prefix  = 'wp_';
          define('WP_DEBUG', false);
          if ( !defined('ABSPATH') )
                  define('ABSPATH', dirname(__FILE__) . '/');
          require_once(ABSPATH . 'wp-settings.php');
  # apacheの設定
  - name: "modify httpd.conf"
    shell: >-
      c='/etc/httpd/conf/httpd.conf' &&
      k='<Directory "\/var\/www\/html">' &&
      s='AllowOverride None' &&
      r='AllowOverride All' &&
      mv $c $c.backup &&
      awk "/$k/{f=1} f==1&&/$s/{sub(/.+/,\"$r\"); f=0} 1" $c.backup > $c
  # apache userのグループ設定
  - name: creat a group
    group:
      name:  www
      state: present
  - name: add user to group
    shell: usermod -aG www apache
  - name: change user auth
    file: path=/var/www/html/ owner=apache group=www mode=2755 state=directory recurse=yes
  # httpd起動
  - name: enable apache
    service: name=httpd state=started enabled=yes

playbook実行と確認

先程作成したDockerコンテナに向けて,上記playbookを実行する.

% ansible-playbook -i dockerHosts playbook.yml

無事に展開が終わったら,localhost:3000/wordpress にむけてアクセスすると,wordpressの初期設定画面にアクセスできる.

Packer

上記で,playbookを用いてDockerコンテナ上にWordPress環境が構築できるところまで確認できた. 最後に,Packerを用いてコンテナ生成から,環境構築後のDocker Image生成まで行う.

下記のようなjsonファイルを作成する(ファイル名はpacker.jsonとする).

{
    "builders":[{
        "type": "docker",
        "image": "amazonlinux",
        "export_path": "controller.tar",
        "run_command": ["-d", "-i", "-t", "--name", "aws", "-p", "3000:80", "{{.Image}}"],
        "pull": false
    }],

    "provisioners":[{
        "type": "ansible",
        "playbook_file": "./playbook.yml",
        "extra_arguments": ["-i", "dockerHosts"]
    }],

    "post-processors": [{
        "type": "docker-import",
        "repository": "wordpress-aws",
        "tag": "aws"
    }]
}

上記のjsonファイルを用いて,次のように実行する.

% packer build packer.json

これで,Wordpress環境が構築されたDocker Imageが生成される.

さいごに

Wordpress環境を構築した状態のDocker Imageを一通り生成するところまでが確認できた. AnsibleとPackerは初体験だったが,まずは使ってみることができたので満足した. 上記で生成されたDocker Imageを,例えばECRに登録して適宜デプロイされるようにしておく,などが次のゴールになる.

間違いや,より効率的な書き方があると思われるので適宜ご指摘いただけますと幸いです.

2017 5/29 追記

ダウンロードしたwordpressを解凍する際にバージョンが固定になっていたので,最新バージョンをダウンロード・解凍するように変更しました.

tumblrAPI(tumblr.js)のoffset,before,after

tumblr.jsを使ってtumblrAPIを叩いて投稿データを取ってくるのは,認証周りでさえコケなければ難しくない. ただ,実際にAPIを叩く際には少し配慮が必要となる.

tumblrAPIのoffset,beforeとafter

tumblrAPIの仕様として,offsetは上限が1000件と決められているらしい. offset=1000以降は遡ることが出来ない.

そこで,beforeとafterというパラメータをAPIに渡してやる解決する. beforeとafterは共にtimestamp型のデータを渡して使う. beforeは○○以前,afterは○○以降のデータを返してくれる. よって,例えばアーカイブページを自前で作ろうとした場合には, beforeに現在のtimestampを渡してやって,その後追加でデータを読み込む際には,最初に受け取ったデータの中から一番古いタイムスタンプを渡してやれば良い.

注意点として,

  • before, afterを使う際にはoffsetは使用できない
  • before, afterは同時に併用できない
  • 取得件数はデフォルトで20件となる(limitを変えて色々試してみたが,最大でも50件だった)

このように,tumblrAPIを介して投稿データを取ってくる際にはパラメータに気を配る必要がある. 調べてもあまりこの辺の話は出てこなかったので,誰かの役に立てば幸い.

ブラウザから多重リクエストが来る問題

href, src, background-image

ブラウザから特定のページに遷移した場合,そのページに対して複数回リクエストが送られてしまう事例がある. どうやらブラウザのバグらしく,hrefやsrcが空だと多重リクエストが発生する.

<!-- example -->
<a href="">hogehoge</a>
<img src="" />

ここまではググるとよくヒットするが,上記の他にもbackground-imageで指定したurlが空だったりすると,こちらも多重リクエストが発生するようだ.

<!-- example -->
<div style="background-image:url()"></div>

まだ一回しか出くわしていないが,何かのヒントになるかもしれない. しかしこのバグ,5年以上前から既に報告されているのに各ブラウザが全く対応してくれない… 開発者が気をつけるしかないらしい.

隗より始めよ

前のエントリから1年近くが経ってしまった. もう少し雑記的な使い方をしようと試みることにする.

就職した

前回のエントリ執筆時は学生だったが,ついに社会に出ることになってしまった. いろいろと困ったりすることも多いが,技術的な学びという点ではやはり現場に勝るものは無い. マイナスな話を書くとキリがないが,なんとかやっていきたいと思う.

アウトプットをしたい

このブログ然りなんでもそうだが,自分は「一定ラインのクオリティを担保してからアウトプット・公開したい」という欲が強いということに最近気がついた. ここで問題になるのは「一定のライン」が必要以上に高いことだ. モチベーションもそれに応じて高い状態を常に維持出来るのならば問題無いが,日常の生活の中でそれを行うのは当然難しい. その結果,肝心のアウトプットがそもそも行われない循環に陥ってしまう.

アウトプットは公開されてこそ意味があるので,とにかく数をこなすことを意識したい. 数が質を高めてくれると,まずはこの方針で行動したい.

とにかく

雑に何でもやっていきたい

海外に行ってきた

国際学会参加のために,生まれて初めて海外に行った. 初めてづくしだったので何もかもが不安だったけれども,色々と収穫があったのでよかった.

せっかくなので色々と所感を書き留めておこうと思う.

事前準備

海外ニュービーなので,事前準備として何が必要なのかを調べるところから始まった. パスポートと航空券が最低限必要ということはなんとなくわかっていたけれど,具体的に何をどういう感じで進めていけば良いのかわからなくて手探り感満載だった. 特にパスポート申請のときに,名前表記で窓口のおばちゃんに散々脅されたことは忘れられない.

ネットで調べたりボスが声をかけたりもしてくれたけど,詳しそうな人間に聞いてみるのが一番手っ取り早かったような気がする.

旅券の手配

旅行会社を通して準備を進めたので,航空券は会社経由で入手した. 今回の行き先は韓国のチェジュ島で,少し前までは関空からの直行便が出ていたけれど,最近になって無くなってしまったらしい. そこで,釜山経由で行くことになったけれど,その場合の手続きがどういう塩梅なのかというのもよくわからなかったし,多少高くついてもその辺を代行してもらえるのはありがたかった.

ホテルの予約

国際会議の会場がホテルだったので,そのホテルを利用することにした. 事前に予約の内容や利用するクレジットカードの情報などをFAXとかいうナウい手段で送りつけるのは中々にファンキーだった. 予約のために,事前に頭金を支払う必要があるというのは覚えておいて良いことだと思う.日本では経験したことのないルールだ.

その他の準備

曲りなりにもエンジニアなので,電源と回線が無いと生きていけない. というわけで,他の準備としては,wifiの手配をしておくと捗ると思う. simフリー端末を持ちあわせているなら,現地でsimを調達しても良い. その他,旅行保険や現地通貨の準備も必要なので適当に.

また,旅行保険は通常手続きに結構時間がかかるらしいけど,今回はネットで申し込めるタイプの保険を使用したので出発前夜に申し込んでも問題なかった.必要ないという話も聞いたけれど,念の為に仕込んでおいて良いだろう.

現地通貨は現地の空港で両替すると良いという話を聞いていたけれど,時間があったので関空で両替しておいた.こっちの方が日本語でやり取りできるから楽かもしれない. 現地通貨をどれくらい用意するかという観点からも,現地の物価情報を調べておくことは最低限やっておいてよかったと思う.

あと,だいたいの国において電源の規格が違うので変換プラグを,数種類用意しておくと良い. 今回,2種類のプラグを持って行っていなければ電源難民になるところだった(規格はあっているが,壁の穴の形状的にプラグがきちんと刺さらないというトラブルに見舞われた).

移動

飛行機

僕は飛行機に乗るときに毎回身体検査にひっかかる(今回も引っかかった)ので心配だったけど,それよりも入国審査の方が心配だった. 入国審査では,目的が観光ならあまり突っ込まれることはないけど,目的が会議だと逆にかなり突っ込んだところまで聞かれると小耳に挟んでいたからだ. ただでさえ不慣れな英語でその辺をうまく伝えられるかどうか非常に心配だった. 実際は,審査の係員と一言も交わすことなく終わった(顔写真と指紋は取られた).

また,今回はエコノミークラスを利用したけれど,長時間の搭乗の場合はかなり疲れる.正直に言って,乗り心地の良いものじゃなかった. 飛行機から降りる段階でボロボロになっていても仕方がないから,お金はかかるけど少し良いランクの座席を購入したほうが良いと思う.

大韓航空を利用したけど,機内でナッツが出てくるかどうかと思ったのは内緒だ.出てこなかった.

現地

基本的に移動はタクシーを使った. チェジュ島においては,タクシーの料金は安くて1500ウォン前後,高くても5000ウォンしないくらいだった.日本円にして150~500円なので,距離次第ということを考えても破格の安さだ.

空港からホテルまではバスを使った.1時間ほどの乗車だったけれど,日本円にして500円ほどだった.やはり安い.

滞在

目的が国際会議ということと,周辺に驚くほど何もなかったので特にホテルから出歩かずにいた.海外にきてそれはどうなのという気もしなくはない. その中で,いくつか思うことがあるので書いておく.

ホテル

今回は会場になってるホテルを利用したと上にも書いたけれど,カンファレンス会場としても使われるだけあって一泊の値段は少し高かった. 金欠学生なので,行く前こそ値段の高さに不満を覚えたものだが,実際に行くと考えが変わった. つまり,ある程度値が張るホテルを利用すると,サービスの質も高くて大変捗るということだ. ここでのサービスとは,部屋や食事などの諸々だけでなく,スタッフの質も含む.例えば,フロントにいるボーイをつかまえて「近くでオススメの観光地は?」「外で食事したいんだけど美味しい店知ってる?」なんていう質問をしても丁寧に,かつ親身になって応えてくれる. これは僕のような海外旅行ニュービーや初めてその土地を訪れる人間にとっては非常にありがたくて,滞在中はずいぶんとお世話になった. 額面だけで見れば確かに値段は高いけれども,投資と思えば十分なリターンがあったと思う. 高い金額を払うメリットを改めて感じた.

あいさつ

現地の言葉で簡単な挨拶は出来たほうがよかったと思う. 「こんにちは」と「ありがとう」を最低限言えるとほんの少しだけやりとりがスムーズになる気がする. 今回の訪問先は多くの場所で英語や日本語が通じるので問題なかったが,現地の言葉で挨拶するのは一つのマナーかもしれない.

まとめ

今回の一件で強く感じたのは「英語くらい使えて当たり前」であるということだ. 数カ国語を当たり前のように操る人たちがゴロゴロいて,あっちこっちでいろんな言葉が飛び交っている. そんな環境においては,せめて英語くらい使えなければ一切何も出来ないということを痛感した. 日本国内にいればそんなことはあまり感じないし,頭では理解できていることではあったけれども,実際に肌で感じるとインパクトが大きい. 母国語以外の言語でなければコミュニケーションが一切取れないという状況に陥ることは日本にいればまずないが,それ故に決定的な能力不足を思い知ったし,今後どのようにトレーニングをしていくのかが悩みどころだ. 学会での質疑応答にどうにかついていくのが精一杯の英語力では,まだまだ通用しないらしい.

また,海外旅行の準備などの知見が全く無かったのでその辺を得ることができたことも大きい. 旅行保険と電源の準備はうっかり忘れてしまうところだったし,次回からはこのエントリを読んで思い出せるようにしておきたい. あとは,免税で酒と煙草を買い忘れないようにすること. 国外の免税で買った煙草はやっぱり味が違う.

本場のUKロックとスコッチを楽しむという野望に一歩近づいた.

鉄のラインバレル完結

ついに鉄のラインバレルが完結した.
また一つ,楽しみにしていたロボット作品が終わりを告げるのかと思うと少し寂しい気持ちになる.

ラインバレルと言えば,アニメと原作漫画ではシナリオが随分違ったことで印象深い. とはいえ,アニメの方のシナリオも僕としてはそれとして楽しむことが出来た. 原作漫画のシナリオは結構ヘヴィな部類だと思うけれど,アニメの方も若干マイルドになったとは言えそこそこヘヴィだと思う.

そして原作漫画はそのヘヴィさを最後まで持ったまま,ついに主人公の早瀬浩一が”正義の味方”であることを貫き通した. 最初は力を持って増長するだけだった少年が最終的にどこに行き着くのか,是非とも読んで確かめて欲しい.

また,原作漫画版は数年前にスーパーロボット大戦UXでシナリオが途中(21巻くらい)まで再現されたことも注目しておきたい. 何故注目するかと言うと,原作により感情移入できるからに他ならない. 原作のアツい名シーンがアニメ版のキャストによって再現される様は,1ファンとしてもプレイヤーとしても胸に来る. まさにスパロボの醍醐味と言えるだろう. ぶっちゃけた話,ラインバレル作中でも一番の盛り上がりを見せる部分がボイス付きで再現され,UXストーリーのターニングポイントの一つにまでなっているのでこれを体験しないのは損だ.

併せて書くと,スパロボUXはストーリーの優秀さで非常に評価の高い作品である. ラインバレル序盤では”想像する”がキーワードになっているが,UXはユーザーの想像の斜め上を行き,度肝を抜くような展開が待っている. ラインバレルファンはプレイの価値があるだろう.

ラインバレルはメカニックの描写も割と好きなのだが,この辺のノウハウは同じ作者のULTRAMANにも活かされている. ウルトラマンも好きな僕としては,こちらの作品も今後が気になるところである.レオは出てくるだろうか.

最初から最後までアツさを失わなかった名作,鉄のラインバレルは是非書庫に加えておきたい.

久々に技術ネタをオンラインに投げた

先週1週間くらい悩みに悩んでようやく解決した件について,qiitaに残しておいた.
このブログに書いておいてもよかったのだけれど,僕自身がqiitaをよく利用するので,僕から何か返せるものがあればいいなと思って敢えて向こうに投稿した.

のだけれど,やっぱり技術ネタをpostするのは緊張する.間違ったことを書いてしまったり,そういったことに起因して何か攻撃的な発言をされることを恐れているようだ.学会などに行ってもそういうことがままあるので,避け得ないことなのだと思う.

でもまぁ,せっかく発見したし日本語で触れられてない話題なので,何かの糧になればいいなあ.