開発室ブログ

Ansible Laravel Vagrant

Vagrant * Ansible Local で Laravel環境を作る

 またインフラ方面のお話。でも今回はローカル環境。

 Vagrant仮想マシンを作ってもらい、その後 Ansible に Laravel 用の環境構築をやってもらいました。内容的にはAnsibleメインです。

環境

  • Windows10 Home
  • Vagrant 2.0.2
    • Box は centos/7
      • PHP 7.2.*
      • Laravel 5.5.*
    • Ansible Local (Ansible 2.4)
    • vagrant-vbguest プラグイン

こんな感じです。

Laravel なら Homestead でいいんじゃないの?

 だと思います。公式でも 強くおすすめします と記載されています。
 なんでイチから作ってるんだっていうと CodeIgniter 3 開発環境をAnsible Localにて作成後、 Laravel 5.5 で開発する方向に変更したからです。なんかもったいないので destroy して Laravel 用にするかぁ…っていうだけなので、普通は Homestead がいいでしょう 。

Vagrant 設定

その前に。バグ?

 自分の WIndows10 環境ではVagrant自体がちゃんと動いてくれませんでした。なんか設定か環境が悪かったのか。はてさて。

io.rb:32:in `encode’: “\xE7” from IBM857 to UTF-8 (Encoding::UndefinedConversionError) · Issue #9368 · hashicorp/vagrant · GitHub

Ansible Local

 Windows ではそもそも Ansible が使えません。なので、ゲスト側に Ansible をインストールしてしまおうというのがコイツです。

www.vagrantup.com

プラグイン追加

 Ansible Localは、ゲスト側にAnsibleを入れる格好になるので、プレイブック(設定タスクを書いたYAML) はホストから共有フォルダ経由で読んでもらいます。その際に Guest Additions を利用するので、関連プラグインをインストールしておきます。

vagrant plugin install vagrant-vbguest

Vagrantfile

 こんな感じでしょうか。config.vm.provision を入れて、仮想マシン作成後に Ansible でプロビジョンしてくれるように設定します。

Vagrant.configure("2") do |config|
  config.vm.define :testhost do |testhost|
    testhost.vm.hostname = "testhost"
    testhost.vm.box = "centos/7"
    testhost.vm.network "private_network", ip: "192.168.xxx.yyy"
    
    # 共有フォルダ
    testhost.vm.synced_folder "C:\\works\\testdir\\src", "/var/www", type: "virtualbox"
    
    # Ansible_local
    testhost.vm.provision "ansible_local" do |ansible|
      ansible.playbook = "/var/www/playbook.yml"
      ansible.install_mode = "pip"
      ansible.version = "2.4.3.0"
    end
    
    # httpd再起動
    testhost.vm.provision :shell, run: "always", :inline => <<-EOT
    sudo systemctl restart httpd
EOT
  end
end

 この例では C:\works\testdir\src/var/www となります。
 ansible.playbook では /var/www/playbook.yml となっているので、Windows上のプレイブックの場所は C:\works\testdir\src\playbook.yml となります。
 また、Ansible のインストール方法やバージョンも指定OKです。

仮想マシンを再起動すると httpd がコケる

 共有フォルダのマウントが済んでいないのに httpd が立ち上がろうとして失敗、という場合があるようなので、以下あたりを参照。

qiita.com

 /etc/fstab にいれたら解決したりしないのかな(未検証)

Ansible 設定

 仮想マシン作成後、Ansible が ホストのPlaybook を読み込んで自動構成処理を行ってくれます。

Playbookを書く

 Ansible はプレイブックから設定・タスクを別ファイルに分割したり、変数や条件を使って各環境の構成管理をスマートにできたりするのですが…今回は開発環境ということもあり up & destroy で検証 + いつものコマンドどう書くの? をメインに作業してました。そのため、1ファイルにゴリッと書いてあるだけとなっています。

 カッコイイ構成、いわゆるベストプラクティスは本家にもありますし、検索してもいろいろ出てきます。今後参考にしていきたい。

Best Practices — Ansible Documentation

書いた

こんな感じでしょうか。
/var/www/testblog/ に Laravelのプロジェクトを配置します。

 Laravel 5.5のインストール条件はこちらを参照 インストール 5.5 Laravel

- hosts: all

  # rootで実行
  become: yes
  become_user: root
  
  tasks:
    - name: SELinuxをコントロールするためのパッケージ導入
    yum:
      name: libselinux-python
      state: installed

    - name: SELinuxオフ
      selinux:
      state: disabled

    - name: タイムゾーン設定
      timezone:
      name: Asia/Tokyo

    # yumインストール
    - name: EPELレポジトリ
      yum:
        name: epel-release
        state: latest

    - name: remiレポジトリ
      command: rpm -ih http://rpms.famillecollet.com/enterprise/remi-release-7.rpm creates=/etc/yum.repos.d/remi.repo

    - name: git インストール
      yum:
        name: git
        state: latest

    - name: httpd インストール
      yum:
        name: httpd
        state: latest

    - name: redis インストール
      yum:
        name: redis
        state: latest

    - name: PHP 7.2 インストール
    yum: name={{ item }} enablerepo=remi,remi-php72 state=latest
    with_items:
      - php
      - php-devel
      - php-common
      - php-fpm
      - php-opcache
      - php-pecl-redis
      - php-mbstring
      - php-mcrypt
      - php-mysqlnd
      - php-pdo
      - php-gd
      - php-xml
      - php-zip

    # サービス設定
    - name: httpd サービス設定
      service:
        name: httpd
        state: started
        enabled: true

    - name: Redis サービス設定
      service:
        name: redis
        state: started
        enabled: true

    # Composer
    - name: Composer インストール
      shell: curl -sS https://getcomposer.org/installer | php -- --install-dir=/bin && mv /bin/composer.phar /bin/composer
      args:
        creates: /bin/composer

    # Laravel
   - name: Laravel 5.5 インストーラ
      shell: composer global require "laravel/installer"
      args:
        creates: /root/.composer/vendor/bin/laravel
    - name: Laravel プロジェクト配置
      shell: composer create-project "laravel/laravel=5.5.*" testblog
      args:
        chdir: /var/www
        creates: /var/www/testblog

    # php.ini 編集
    - name: php.ini変更 - timezone
      replace:
        path: /etc/php.ini
        regexp: '^;date.timezone ='
        replace: date.timezone = Asia/Tokyo
    # 略

    # httpd.conf 編集
    - name: httpd.conf変更 - DocRoot
      replace:
        path: /etc/httpd/conf/httpd.conf
        regexp: '^DocumentRoot "/var/www/html"'
        replace: DocumentRoot "/var/www/testblog/public"
    - name: httpd.conf変更 - DocRoot
      replace:
        path: /etc/httpd/conf/httpd.conf
        regexp: '^\<Directory "/var/www/html"\>'
        replace: <Directory "/var/www/testblog/public">
  # 略

長。やっぱり分割したいですね。

root実行

 Ansible 2.4では become を使って指定します。

yum インストール

 yum モジュールを利用します。PHPのインストールでも記載している通り、remiレポジトリの利用も指定可。state によって状態を指定します。PHPの場合は latest なので、with_itemで指定したパッケージが最新でなければ、インストール or アップデートの処理が走ります(changed)。逆に最新が入っていれば、何もしません(ok)。

systemctl サービス設定

 service モジュールを利用します。state と enabled でサービスの起動や、サービス有効/無効を設定できます。
 state: restarted と書くと、タスクの途中で再起動なんてこともできます。

ComposerとLaravel インストールとか

 shell モジュールでコマンドを叩きます。args 以下の creates でファイルを指定し、存在した場合は何度も実行しないようにチェックします。commandモジュールだと、パイプとかリダイレクトが使えない(はず)です。

conf系のファイル編集

 最後の方でreplaceモジュールを使ってやってみてますが、本格的な細かい設定は困難かなと思います(同じのが複数行ある場合とか…)。ある程度まで終わらせた完成ファイルを作って、templateモジュールか何かで送ったほうがよさそう…。

 selinuxモジュールやtimezoneモジュールでの設定も行っています。他にもモジュールがたくさんあるので、大体何でもできるのかな…。

up

 Vagrantfile と Playbookがそろったので vagrant up します。Vagrant による仮想マシン構築後、下記のようなログが出力されます。ちゃんと指定したバージョンの Ansible でプロビジョンしてるのがわかります。

(前略)
Vagrant has automatically selected the compatibility mode '2.0'
according to the Ansible version installed (2.4.3.0).
Alternatively, the compatibility mode can be specified in your Vagrantfile:
https://www.vagrantup.com/docs/provisioning/ansible_common.html#compatibility_mode
testhost: Running ansible-playbook...
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [testhost]
TASK [SELinuxをコントロールするためのパッケージ導入] **********************************************
ok: [testhost]
TASK [SELinuxオフ] ***************************************************************
changed: [testhost]
[WARNING]: SELinux state temporarily changed from 'enforcing' to 'permissive'.
State change will take effect next reboot.
(以下略)

 Ansible の処理完了後(Vagrantfile の方に書いた)最後のプロビジョンであるhttpdの再起動が入ります。問題なければ Laravel のデフォルトページがドキュメントルートになってるはずなので、 vagrant up が終わればすぐにブラウザで確認できるはず…。

f:id:ajdev:20180215171743p:plain
Laravelデフォルトトップ

 Laravel がまだわかってないので、完全にインストールされてるか明言できないのが悲しいですが…とりあえず見えた!

 あとは .vagrant ディレクトリの奥にある鍵を使って SSH で入ってみて…

[root@testhost testblog]# cd /var/www/testblog
[root@testhost testblog]# php artisan --version
Laravel Framework 5.5.34

む。大丈夫そうかな。

やってみて

コマンド作業→プレイブックの展開が何となくわかった

 最初はめんどくさい&よくわかんないって感じでしたが、いつものコマンドをどうやって書くのかが何となくわかった。やっぱ最後までやってみないとダメだなー。
 今後やってみるときは、早く書けそうかなー、という気がします。

ベストプラクティス調べてみたい

 今回はプレイブック一つですが、長い…迷子にならない程度に分割したいところです。その後、開発/試験/本番などの展開もできるといい。

 とりあえずインストールまでできたっぽいので、Laravel のお勉強に戻ります。

RecentPost