いまさらながらAnsibleを使ってみた
世の中もうDockerの時代なのかもしれませんが、ある案件で使うサーバーのプロビジョニングツールとしてAnsibleを使ってみました。
今まではChefを使っていましたがChefはRubyでガリガリ書けるので何でもできますが、メンテや構成管理情報を伝えるのに難があるかなと思ます。そこでシンプルという噂のAnsibleを使って、Ruby on Railsの動くサーバーを構築するAnsibleを書いてみました。
本家のドキュメント もちゃんとしてますし、ネット上にはたくさんの情報があるので楽に作れましたがそれでも何点か苦労したのでそこを中心に書きます。Playbooksは以下のようにroleに分けて書きました。
├── roles │ ├── apps │ │ ├── files │ │ │ ├── logrotate │ │ │ └── unicorn │ │ └── tasks │ │ └── main.yml │ ├── linux │ │ └── tasks │ │ └── main.yml │ ├── nginx │ │ ├── files │ │ │ └── logrotate │ │ ├── handlers │ │ │ └── main.yml │ │ ├── tasks │ │ │ └── main.yml │ │ └── templates │ │ └── recorder.j2 │ ├── postgresql │ │ └── tasks │ │ └── main.yml │ └── ruby │ └── tasks │ └── main.yml └── site.yml
1. Linux(Unbuntu)の基本設定
てこずったのは、locale の設定。localeの作成やtimezoneの設定はmoduleがあるのに、locale設定は無いので update-locale コマンドを使いました。コマンドを使うと問題になるのが、どうやって冪等にするか。 update-locale は毎回実行されても問題はありませんが、Ansibleの勉強をかねて調べました。
ansible_env.LANGでターゲット側の環境変数が参照できます。ただしLANGが無い場合エラーになるのでデフォルト値を設定しました。
- name: install tools apt: name={{ item }} update_cache=yes with_items: - git - language-pack-ja - name: create locale ja_JP.UTF-8 locale_gen: name: ja_JP.UTF-8 - name: set locale to ja_JP.UTF-8 command: update-locale LANG=ja_JP.UTF-8 when: ansible_env.LANG | default('') != 'ja_JP.UTF-8' - name: set timezone to Asia/Tokyo timezone: name: Asia/Tokyo - name: install and start NTP apt: name=ntp
2. Rubyのインストール
これはネット上の情報で出来ました。Rubyのバーション番号等のパラメター(変数)は他の場所で定義した方が良いかもしれませんが、とりあえず同一ファイルに定義しました。
今回は /usr/local/bin
にruby, gem … をインストールしたのですが、 gem module は user_install: no を設定しないと /usr/local/bin
に入らないのでハマりました
- name: define ruby version set_fact: workspace: /usr/local/src ruby_version: 2.4.1 ruby_download_url: http://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.1.tar.gz - name: install packages required to build ruby apt: "name={{ item }} state=present" with_items: - build-essential - zlib1g-dev - libssl-dev - libyaml-dev - libreadline6-dev - zlib1g-dev - libncurses5-dev - libffi-dev - libgdbm3 - libgdbm-dev - libsqlite3-dev - name: download ruby get_url: url: "{{ ruby_download_url }}" dest: "{{ workspace }}/ruby-{{ ruby_version }}.tar.gz" - name: extract ruby unarchive: src: "{{ workspace }}/ruby-{{ ruby_version }}.tar.gz" dest: "{{ workspace }}/" copy: no - name: build ruby command: > {{ item }} chdir={{ workspace }}/ruby-{{ ruby_version }} creates=/usr/local/bin/ruby with_items: - ./configure --disable-install-doc - make - make install - gem update --system - name: install bundler gem gem: name: bundler user_install: no
3. PostgreSQL
PostgreSQLはUbuntu16.04標準の9.5ではなく、 9.6を入れたかったので apt_repository , apt_key を設定しました。
また、ログインアカウントでpsqlを使えるようにしたかったので pg_hba.conf を書き換えています。その後のPostgreSQL再起動はnotifyだと非同期になるので serviceで行いました。ここの冪等もAnsibleの勉強になりました ^^;
- name: add PostgreSQL repositories apt_repository: repo: deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main state: present - name: add PostgreSQL key apt_key: url: https://www.postgresql.org/media/keys/ACCC4CF8.asc state: present - name: install PostgreSQL apt: name={{ item }} update_cache=yes with_items: - postgresql-9.6 - postgresql-client-9.6 - postgresql-contrib-9.6 - libpq-dev - python3-psycopg2 - name: configure PostgreSQL (authentication) replace: path: /etc/postgresql/9.6/main/pg_hba.conf regexp: '^local(\s.+?\s+)peer$' replace: 'local\1trust # peer #' register: pg_hba_file - name: restart PostgreSQL server service: name: postgresql state: restarted when: pg_hba_file.changed - name: add user to PostgreSQL postgresql_user: name: XXXXXX password: XXXXXX role_attr_flags: CREATEDB,NOSUPERUSER - name: add databases to PostgreSQL postgresql_db: name: XXXXXX owner: XXXXXX
4. Nginx
Nginx はネット上にあった情報でなんとかなりました
- name: define nginx values set_fact: conf_file: /etc/nginx/sites-available/XXXXXX site_name: XXXXXX ssl: false unicorn_socket: unix:/tmp/unicorn.XXXXXX.socket public_path: /home/apps/XXXXXX/current/public - name: install Nginx apt: name={{ item }} update_cache=yes with_items: - nginx - apache2-utils - name: set this-site configuration template: src: ../templates/XXXXXX.j2 dest: "{{ conf_file }}" notify: restart nginx - name: disbale default configuration file: path: /etc/nginx/sites-enabled/default state: absent notify: restart nginx - name: enable this-site configuration file: dest: /etc/nginx/sites-enabled/XXXXXX src: "{{ conf_file }}" state: link notify: restart nginx - name: set log rotation copy: src: ../files/logrotate dest: /etc/logrotate.d/nginx owner: root mode: 0644
5. アプリケーション
Ruby on Railsアプリケーション用の設定も簡単でした。ちなみにRails等のインストールはデプロイ時に行われるのでありません。
- name: make directory of application file: path: /home/apps/XXXXX state: directory owner: ubuntu group: ubuntu mode: 0755 - name: set unicorn configuration copy: src: ../files/unicorn dest: /etc/init.d/unicorn mode: 0755 - name: enable unicorn service service: name: unicorn enabled: yes use: service - name: set log rotation copy: src: ../files/logrotate dest: /etc/logrotate.d/unicorn owner: root mode: 0644
感想
出来たplaybookを見るとChefに比べ短くシンプルですね。あまり難しい事をしないならAnsibleは楽です。ただし冪等を頑張ると少したいへんかも・・・・