初老のボケ防止日記

おっさんのひとりごとだから気にしないようにな。

スポンサーリンク

今更だけどVagrantでも使ってみるか(5)



前回までのあらすじ

Ansibleをためしてガッテンしたが、流石にこの歳だとハローワールドができたといってマスターしましたというと周囲から冷たい態度をとられてしまうのでちゃんと試す。

今更だけどVagrantでも使ってみるか(4) - 初老のボケ防止日記

環境

既にVirtualBoxとVagrantは使ってる状態。

OS Windows 8.1(x64)
VirtualBox 4.3.20
Vagrant 1.6.5
Ansible 1.5.4

前回同様、WindowsだとAnsibleが動作しないのでVagrant側ではなく、VM側にインストールしたものをローカル実行する。

Ansibleの基本

まずはここで学習。

Ansible チュートリアル | Ansible Tutorial in Japanese

「6.BestPlacticesに沿った構成を真似る」をやると時間がかかりそうなので、まずBadPlacticesな構成でやる。後で本気で使うときにBestを尽くせばよい。

Vagrant upでAnsibleをちゃんと使う

Vagrantで以下の2つのVMを生成する。

web geodjangoを動かす環境
db postgisを動かす環境

VMをフロントエンドとバックエンドで分けて、VM間はプライベートネットワークで通信可能な構成とする

Vagrant向けの構成

BadPlacticesだろうが、とりあえずシンプルでよいのだ。ということで、ここはちょい悪Ansibleというノリで行く。

choiwaru-ansible
├── provision_web.sh
├── provision_db.sh
├── ansible
│   ├── vars.yml
│   ├── geodjango.yml
│   ├── hosts
│   └── postgis.yml
└── Vagrantfile
  • Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "ubuntu1404dockerabsible"
  config.vm.synced_folder ".", "/vagrant", :mount_options => ['dmode=775', 'fmode=664']

  config.vm.define :web do | web |
    web.vm.hostname = "geodjango"
    web.vm.provision "shell", :path => "provision_web.sh"
    web.vm.network :private_network, ip: "192.168.33.10", virtualbox__intnet: "intnet"
    web.vm.network :forwarded_port, guest: 8000, host: 8000
  end

  config.vm.define :db do | db |
    db.vm.hostname = "postgis"
    db.vm.provision "shell", :path => "provision_db.sh"
    db.vm.network :private_network, ip: "192.168.33.20", virtualbox__intnet: "intnet"
  end
end

前回と違うのは、web側のVMにポートフォワーディングを追加している点のみ。何故追加したか?そこに浪漫があるからだ。意味がわからないだと? しょうがねえなヒヨッコめ、教えてやろう。VMはプライベートなIPしか割り当ててないからホスト側からIPアクセスできねえんだよ。ん? sshできてるって? 各VMのIPをよく見てみろ。プライベートIP以外は同じIPになってるだろう? sshもポートフォワーディングされてるんだよ。あとな、前回から定義済みだが共有フォルダのマウントオプションを指定しないとAnsibleが共有フォルダ上のファイルをちゃんと読まねえから注意するんだぜ。

  • provision_web.sh
ansible-playbook -i /vagrant/ansible/hosts /vagrant/ansible/geodjango.yml

ansible実行時に指定するplaybookを変えただけだ。

  • provision_db.sh
ansible-playbook -i /vagrant/ansible/hosts /vagrant/ansible/postgis.yml

ansible実行時に指定するplaybookを変えただけだ。

Ansibleの構成

ここからはAnsibleの構成だ。

  • ansible/hosts
127.0.0.1 ansible_connection=local

前回と同じ。

  • ansible/vars.yml
---
database:
  name: geodjangodb
  user: geodjango
  password: geodjango

両方のVM用のAnsibleで使うであろう設定項目を別ファイルに外出ししている。だが、結局今回は片方しか使わなかったぜ。

  • ansible/postgis.yml
---
- hosts: all
  sudo: yes
  tasks:
  - name: Install Dependency Packages for ansible
    apt: >
      pkg={{ item }}
      state=present
    with_items:
      - python-apt
      - python-pycurl

  - name: Add postgres repository
    apt_repository: repo='deb http://apt.postgresql.org/pub/repos/apt/ {{ansible_distribution_release}}-pgdg main' state=present

  - name: Add postgres repository key
    apt_key: url=http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc state=present 

  - name: Install postgis Packages
    apt: >
      pkg={{ item }}
      state=present
      update-cache=yes
    with_items:
      - postgresql-9.3-postgis-2.1
      - postgresql-contrib-9.3
      - python-psycopg2

- hosts: all
  sudo: yes
  sudo_user: postgres

  vars_files:
  - vars.yml 

  tasks:
  - name: Create extention adminpack
    command: psql -c 'CREATE EXTENSION IF NOT EXISTS adminpack'

  - name: Create template_postgis
    postgresql_db: name=template_postgis
    register: createdb_template_postgis

  - name: Create extention to template_postgis
    command: psql -d template_postgis -f {{ item }}
    with_items:
      - /usr/share/postgresql/9.3/contrib/postgis-2.1/postgis.sql 
      - /usr/share/postgresql/9.3/contrib/postgis-2.1/spatial_ref_sys.sql
    when: createdb_template_postgis.changed

  - name: Create geo database
    postgresql_db: >
      name={{ database.name }}
      template=template_postgis

  - name: Create geo database user
    postgresql_user: >
      db={{ database.name }}
      name={{ database.user }}
      password={{ database.password }}
      priv=ALL

  - name: Modify postgresql.conf ( listen )
    lineinfile: >
      dest=/etc/postgresql/9.3/main/postgresql.conf
      regexp='^#?listen_addresses\s*='
      line="listen_addresses = '*'"
      state=present
      backup=yes
    notify: restart postgresql

  - name: Modify pg_hba.conf ( local method )
    lineinfile: >
      dest=/etc/postgresql/9.3/main/pg_hba.conf
      regexp='local\s+all\s+all\s+peer'
      line='local all all md5'
      state=present
      backup=yes
    notify: restart postgresql

  - name: Modify pg_hba.conf ( allow access other host )
    lineinfile: >
      dest=/etc/postgresql/9.3/main/pg_hba.conf
      regexp='host\s+all\s+all\s+127.0.0.1/32\s+md5'
      line='host all all 0.0.0.0/0 md5'
      state=present
      backup=yes
    notify: restart postgresql

  handlers:
  - name: restart postgresql
    service: name=postgresql state=restarted

VM「db」用のPlaybookだ。ここは少し処理が長いので解説をしておくぜ。
まず、最初にaptでansibleのPlayBookを実行するのに必要なパッケージをインストールしている。使いたいモジュールが依存するパッケージは「ansible-doc 」でわかるぞ。
モジュールのパラメータの説明もでてくるので便利なコマンドだ。どんなモジュールが使えるかは「ansible-doc -l」で一覧がでるぞ。

$ ansible-doc apt_repository
> APT_REPOSITORY

  Add or remove an APT repositories in Ubuntu and Debian.

Options (= is mandatory):

= repo
        A source string for the repository.

- state
        A source string state. (Choices: absent, present)

- update_cache
        Run the equivalent of `apt-get update' if has changed.
        (Choices: yes, no)

Notes:  This module works on Debian and Ubuntu and requires `python-apt' and
        `python-pycurl' packages.This module supports Debian Squeeze
        (version 6) as well as its successors.This module treats
        Debian and Ubuntu distributions separately. So PPA could be
        installed only on Ubuntu machines.

Requirements:  python-apt, python-pycurl

repositoryを追加してpostgisをインストールした後、web側から利用するデータベースやユーザの作成をしている。commandモジュールでpsql実行でも問題はないんだが、二回目に実行した時に色々とと面倒なので、Ansibleの標準モジュールである「postgresql_db」「postgresql_user」を使ったほうが便利だぞ。

最後に、postgresの設定変更をしている。本来ならtemplate(jinja2)を使うべきなのだろうが、今回は「lineinfile」でゴリゴリやっているぞ。正規表現グッジョブ。本当は「0.0.0.0/0」ではなく、プライベートネットワークのみアクセス可能にしたいところだが、ホスト情報(GATHERING FACTS)からCIDRがとれないので今回はしてないぜ。で変更が終わったら、postgresの再起動で設定を反映させている。

  • ansible/geodjango.yml
---
- hosts: all
  sudo: yes
  tasks:
  - name: Install Dependency Packages for ansible
    apt: >
      pkg={{ item }}
      state=present
    with_items:
      - python-apt
      - python-pip
      - python-virtualenv

  - name: Install Dependency Packages for geodjango
    apt: >
      pkg={{ item }}
      state=present
    with_items:
      - gdal-bin 
      - proj-bin 
      - libproj-dev 
      - python-psycopg2
      - ipython

  - name: Install django and plugin
    pip: >
      name={{ item }}
      state=present
    with_items:
      - django
      - django-leaflet
      - django-geojson
      - django-cors-headers

VM「web」用のPlaybookだ。Ansibleにはdjango向けの「django_manage」というモジュールが存在するのだが、Django自体詳しくないので今回は使わなかったぜ。本当はsettings.pyへのDB情報やインストールしたdjangoプラグインを登録したいところだが、「lineinfile」では汚すぎるのでやめた。そこまでできたらモテるだろうに。

Vagrant upでAnsibleぶちかます

$ vagrant up
Bringing machine 'web' up with 'virtualbox' provider...
Bringing machine 'db' up with 'virtualbox' provider...
==> web: Importing base box 'ubuntu1404dockeransible'...
==> web: Matching MAC address for NAT networking...
==> web: Setting the name of the VM: test3_web_1418714082352_52150
==> web: Clearing any previously set network interfaces...
==> web: Preparing network interfaces based on configuration...
    web: Adapter 1: nat
    web: Adapter 2: intnet
==> web: Forwarding ports...
    web: 8000 => 8000 (adapter 1)
    web: 22 => 2222 (adapter 1)
==> web: Booting VM...
==> web: Waiting for machine to boot. This may take a few minutes...
    web: SSH address: 127.0.0.1:2222
    web: SSH username: vagrant
    web: SSH auth method: private key
    web: Warning: Connection timeout. Retrying...
==> web: Machine booted and ready!
==> web: Checking for guest additions in VM...
==> web: Setting hostname...
==> web: Configuring and enabling network interfaces...
==> web: Mounting shared folders...
    web: /vagrant => C:/AppData/Packer/test3
==> web: Running provisioner: shell...
    web: Running: C:/Users/osa_000/AppData/Local/Temp/vagrant-shell20141216-7304-1glmufh.sh
==> web: stdin: is not a tty
==> web:
==> web: PLAY [all] ********************************************************************
==> web:
==> web: GATHERING FACTS ***************************************************************
==> web: ok: [127.0.0.1]
==> web:
==> web: TASK: [Install Dependency Packages for ansible] *******************************
==> web: changed: [127.0.0.1] => (item=python-apt,python-pip,python-virtualenv)
==> web:
==> web: TASK: [Install Dependency Packages for geodjango] *****************************
==> web: changed: [127.0.0.1] => (item=gdal-bin,proj-bin,libproj-dev,python-psycopg2,ipython)
==> web:
==> web: TASK: [Install django and plugin] *********************************************
==> web: changed: [127.0.0.1] => (item=django)
==> web: changed: [127.0.0.1] => (item=django-leaflet)
==> web: changed: [127.0.0.1] => (item=django-geojson)
==> web: changed: [127.0.0.1] => (item=django-cors-headers)
==> web:
==> web: PLAY RECAP ********************************************************************
==> web: 127.0.0.1                  : ok=4    changed=3    unreachable=0    failed=0
==> db: Importing base box 'ubuntu1404dockeransible'...
==> db: Matching MAC address for NAT networking...
==> db: Setting the name of the VM: test3_db_1418714192182_79711
==> db: Fixed port collision for 22 => 2222. Now on port 2200.
==> db: Clearing any previously set network interfaces...
==> db: Preparing network interfaces based on configuration...
    db: Adapter 1: nat
    db: Adapter 2: intnet
==> db: Forwarding ports...
    db: 22 => 2200 (adapter 1)
==> db: Booting VM...
==> db: Waiting for machine to boot. This may take a few minutes...
    db: SSH address: 127.0.0.1:2200
    db: SSH username: vagrant
    db: SSH auth method: private key
    db: Warning: Connection timeout. Retrying...
==> db: Machine booted and ready!
==> db: Checking for guest additions in VM...
==> db: Setting hostname...
==> db: Configuring and enabling network interfaces...
==> db: Mounting shared folders...
    db: /vagrant => C:/AppData/Packer/test3
==> db: Running provisioner: shell...
    db: Running: C:/Users/osa_000/AppData/Local/Temp/vagrant-shell20141216-7304-nmc136.sh
==> db: stdin: is not a tty
==> db:
==> db: PLAY [all] ********************************************************************
==> db:
==> db: GATHERING FACTS ***************************************************************
==> db: ok: [127.0.0.1]
==> db:
==> db: TASK: [Install Dependency Packages for ansible] *******************************
==> db: changed: [127.0.0.1] => (item=python-apt,python-pycurl)
==> db:
==> db: TASK: [Add postgres repository] ***********************************************
==> db: changed: [127.0.0.1]
==> db:
==> db: TASK: [Add postgres repository key] *******************************************
==> db: changed: [127.0.0.1]
==> db:
==> db: TASK: [Install postgis Packages] **********************************************
==> db: changed: [127.0.0.1] => (item=postgresql-9.3-postgis-2.1,postgresql-contrib-9.3,python-psycopg2)
==> db:
==> db: PLAY [all] ********************************************************************
==> db:
==> db: GATHERING FACTS ***************************************************************
==> db: ok: [127.0.0.1]
==> db:
==> db: TASK: [Create extention adminpack] ********************************************
==> db: changed: [127.0.0.1]
==> db:
==> db: TASK: [Create template_postgis] ***********************************************
==> db: changed: [127.0.0.1]
==> db:
==> db: TASK: [Create extention to template_postgis] **********************************
==> db: changed: [127.0.0.1] => (item=/usr/share/postgresql/9.3/contrib/postgis-2.1/postgis.sql)
==> db: changed: [127.0.0.1] => (item=/usr/share/postgresql/9.3/contrib/postgis-2.1/spatial_ref_sys.sql)
==> db:
==> db: TASK: [Create geo database] ***************************************************
==> db: changed: [127.0.0.1]
==> db:
==> db: TASK: [Create geo database user] **********************************************
==> db: changed: [127.0.0.1]
==> db:
==> db: TASK: [Modify postgresql.conf ( listen )] *************************************
==> db: changed: [127.0.0.1]
==> db:
==> db: TASK: [Modify pg_hba.conf ( local method )] ***********************************
==> db: changed: [127.0.0.1]
==> db:
==> db: TASK: [Modify pg_hba.conf ( allow access other host )] ************************
==> db: changed: [127.0.0.1]
==> db:
==> db: NOTIFIED: [restart postgresql] ************************************************
==> db: changed: [127.0.0.1]
==> db:
==> db: PLAY RECAP ********************************************************************
==> db: 127.0.0.1                  : ok=15   changed=13   unreachable=0    failed=0

で、この後、とある会社のブログの記事を参考にgeodjangoのプロジェクトを作成してVMホスト側で地図表示できるところまで確認済みさ!

感想

一番面倒なのは設定ファイルを弄るところ。テンプレートを導入環境に合わせて適用するのがスジなんだろうなとは思うが、まだそこまでしてない。あとはBadPlacticesをどこまで意識するかというのは導入プロダクトの規模にもよるのでそこは色々と考えどころである(そもそもAnsible使う必要があるのか含めて)。それと、今回用いたAnsibleはaptでインストールしたので「1.5」なんだけど、現在の最新は「1.8」なので色々と参考にした情報が使えなかったりしてそういう細かな所で躓くところが多かった。box生成時にインストールするのであればpipで最新版入れたほうがいいのかもしれない。

入門Ansible

入門Ansible

次回予告

AnsibleのTemplate(jinja2)を使ったり構成をちょっと見なおしたりしたい。

スポンサーリンク