用途別Tips

Last-modified: Sun, 28 Aug 2016 00:50:29 JST (419d)

ファイル、ディレクトリ操作

ディレクトリ作成

- name: make apache log directory
  file:
    path: /var/log/httpd/localhost.localdomain
    state: directory
    owner: root
    group: root
    mode: 0755

ディレクトリ削除

- name: /var/www/htmlを削除
  file:
    path: /var/www/html
    state: absent

ファイル作成(中身は空っぽ)

- name: create timezone file
  file:
    dest: /etc/timezone
    state: touch

ファイル削除

- name: Remove default vhost
  file:
    dest: /etc/httpd/conf.d/welcome.conf
    state: absent
  • ファイルのコピーには、copyモジュールを使います。ただし、サーバ内のコピーではなく、Ansibleを実行しているローカルー>リモート間でのコピーになります。逆方向の場合はsynchronizeモジュールを使います。要するにSCPしています。サーバ内部でのコピーや移動はcommandモジュールでコマンドを叩くしかない?
    srcには、role/filesからの相対パスになります。

ファイルをコピー

- name: add authorized key
  copy:
    src: public_keys/test
    dest: /home/test/.ssh/authorized_keys
    mode: 0600
    owner: test
    group: test

リモートのファイルをダウンロードする

  • リモートのファイルをダウンロードしたり、同期をとったりする場合、synchronizeモジュールを使います。
    モジュール名の通り、内部的にはrsyncです。

リモートにあるファイルをダウンロードする。

- name: ファイルをダウンロードする
  synchronize:
    mode: pull
    src: /tmp/data.tar.gz 
    dest: ./tmp

存在チェック

  • ファイルやディレクトリの存在チェックには、statモジュールを使います。
    これは、registerと組み合わせる事で、条件分岐に使えます。

デフォルトのバーチャルホスト設定を無効化する。

- name: welcome設定存在チェック
  stat: path=/etc/httpd/conf.d/welcome.conf
  register: welcome_stat
- name: デフォルトのバーチャルホスト設定削除
  command: mv /etc/httpd/conf.d/welcome.conf /etc/httpd/conf.d/welcome.conf.disable
  when: welcome_stat.stat.exists
  notify:
    - "restart apache"

ユーザ操作

ユーザ作成

パスワードは以下のコマンドで生成

python -c 'import crypt; print crypt.crypt("hogehoge", "$1$SomeSalt$")'
- name: create user test
  user:
    name: test
    password: "$1$SomeSalt$Drh7s/vUcl5XnIZ/Neglz1"
    state: present

Cron設定

Cron作成

- name: add cron
cron:
  name: "test cron"
  user: root
  minute: "0"
  hour: "6"
  job: "ls -lah > /tmp/list"
  state: present

ファイルをダウンロードする

ファイルをダウンロードする。

- name: Jenkinsリポジトリの取得
  get_url:
    url: http://pkg.jenkins-ci.org/redhat/jenkins.repo 
    dest: /etc/yum.repos.d/jenkins.repo

ファイルのダウンロード時チェックサムをチェックする。

- name: mod_ruidをダウンロード
  get_url: 
    url: http://jaist.dl.sourceforge.net/project/mod-ruid/mod_ruid2/mod_ruid2-0.9.8.tar.bz2
    sha256sum: f8a178daf3bccf86e7e50e3224efc52165200470dece7b701466c5fbf1944b19
    dest: /tmp/mod_ruid2-0.9.8.tar.bz2
    force: True

yum関連

yumでインストールする。

- name: Javaのインストール
  yum: name={{ item }} state=installed
  with_items:
     - java-1.7.0-openjdk
     - httpd

なお、nameの引数にサーバ内のrpmファイルパスを渡せば、ローカルのrpmをインストールすることが、URLを渡せば直接インストールすることができます。

yum updateをする。

- name: yum update
  yum: name=* state=latest

rpmキーをインポート

- name: Jenkinsリポジトリのキーをインポート
  rpm_key:
    key: http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key

リポジトリを追加

- name: Add repository
 yum_repository:
   name: epel
   description: EPEL YUM repo
   baseurl: http://download.fedoraproject.org/pub/epel/$releasever/$basearch/
   enabled: no

テンプレート関連

  • テンプレート関連モジュールとして、templateモジュールがあります。
    テンプレートにはJinja2が使われます。
    srcのパスは、role/templatesからの相対パスになります。

テンプレートファイルを展開し、リモートに配置する。

- name: template vhost.conf
  template: 
    src: etc/virtual.conf 
    dest: /etc/httpd/conf.d/virtual.conf
    mode: 0644
    owner: root
    group: root
    notify: "restart apache"

サービス関連

サービスを起動し、自動起動をセットする。

- name: Jenkins Start
  service: 
    name: jenkins 
    state: running
    enabled: yes 

サービスを再起動する。(ハンドラでよく使う)

- name: "restart syslogd"
  service: name=rsyslog
  state: restarted

コマンドの実行関連

  • コマンドを実行するモジュールとして、commandモジュールshellモジュールがあります。
    commandモジュールではパイプやリダイレクトなどが使えなかったりするので、そのような場合はshellモジュールを使います。
    なお、冪等性の確保は各自で行わないといけないので注意です。

/usr/local/srcへディレクトリを移動した後ファイルを解凍

- name: ファイルを解凍
  command: tar -xjf /tmp/mod_ruid2-0.9.8.tar.bz2
    chdir: /usr/local/src/

ディレクトリのみパーミッション変更

- name: ディレクトリのみ権限調整
  shell: find . -type d -print | xargs chmod 755
    chdir: /var/www/html/

サーバ内部でファイルのコピー

- name: タイムゾーンをJSTにする
  shell: cp /usr/share/zoneinfo/Japan /etc/localtime

ファイル編集関連

  • ファイル編集関連としては、一行編集するlineinfileモジュールreplaceモジュールがありますが、
    あまり凝ったことができないので、テンプレートを使って丸ごと置き換えるか、shellモジュールでawkなど自力で頑張るしかなさそうです。
    なお、lineinfileモジュールは存在しないファイルを指定するとエラーになります。

正規表現に一致する行を編集する。

- name: "php.iniの修正"
  lineinfile:
    dest: /etc/php.ini
    state: present
    backrefs: yes
    regexp: '{{ item.regexp }}'
    line: '{{ item.line }}'
  with_items:
    - regexp: '^;date.timezone ='
      line: 'date.timezone=Asia/Tokyo'
    - regexp: '^;mbstring.language = Japanese'
      line: 'mbstring.language = Japanese'
  notify:
    - "restart apache" 

空のファイルを作成し、最後の行に追記する。(insertafter:EOFはデフォなので省略可能)

- name: テスト用html作成
  file:
    dest: /var/www/html/index.html
    state: touch
    owner: apache
    group: apache
- name: テスト用html作成
  lineinfile:
    dest: /var/www/html/index.html
    line: "testweb"
    insertafter: EOF
    owner: apache
    group: apache

リポジトリを無効化する。

#ただし、該当するものすべてが置換されるので注意
- name: DisabeRepo
  replace: 
    dest: /etc/yum.repos.d/{{item}}
    regexp: "enabled=1" 
    replace: "enabled=0"
  with_items:
    - epel.repo
    - remi.repo

Apache関連

Apacheのモジュールを有効化

- apache2_module:
    state: present
    name: php

BASIC認証用にhtpasswdファイル作成

- htpasswd:
    path: /etc/httpd/htpasswd_basic_user
    name: basic_user
    password: testpass

タスクの実行結果を保持したい

  • タスクの実行結果を変数に保持して、次のタスク実行を制御したい時があります。
    そのような場合は、registerを使い、結果を変数に保存し、次のタスクのwhenで条件分岐させます。
    例えば、shellモジュールでファイルをリネームする時、1回目はファイルが存在するので良いのですが、2回目以降は対象となるファイルが存在しないのでエラーになります。
    ファイルの存在チェックを行い、ファイルが存在したらshellタスクを実行する。というようにします。具体例はデフォルトのバーチャルホスト設定を無効化する。を見てください。

変数を作成する。

  • タスク実行時、複数の条件で判定させたい時があります。whenだと一つしか条件が指定できないので、registerでそれぞれの結果を保持し、それをset_factモジュールを用いて、条件判定後の結果を変数にセットします。

Apacheのmod_ruid2をインストール

- name: mod_ruidをダウンロード
  get_url:
    url: http://jaist.dl.sourceforge.net/project/mod-ruid/mod_ruid2/mod_ruid2-0.9.8.tar.bz2
    sha256sum: f8a178daf3bccf86e7e50e3224efc52165200470dece7b701466c5fbf1944b19
    dest: /tmp/mod_ruid2-0.9.8.tar.bz2
    force: True
  register: downloaded_tarball
- name: 既にバイナリが無いかチェック
  stat: path=/usr/lib64/httpd/modules/mod_ruid2.so
  register: st
- name: コンパイルが必要かどうか?
  set_fact:
    need_to_build: "{{ st.stat.exists == False or st.stat.size == 0 or
                       downloaded_tarball | changed }}"
- name: ファイルを解凍
  command: tar -xjf /tmp/mod_ruid2-0.9.8.tar.bz2 -C /usr/local/src/
  when: need_to_build
- name: compile&install mod_ruid2
  command: apxs -a -i -l cap -c mod_ruid2.c chdir=/usr/local/src/mod_ruid2-0.9.8
  when: need_to_build

インベントリファイルについて

  • インベントリファイルでグループ共通変数を使えると便利なことがあります。
    例えば、webserverとstagingserverというグループがあるとします。
    これらは、group_versでそれぞれ独立して定義できますが、例えば共通のAPIサーバにアクセスするなどの場合、同じ定義をそれぞれしないといけません。その場合、次のように共通のグループを作ってあげるとよい。
    [webserver]
    192.168.0.xxx 以下省略
    [stagingserver:
    192.168.1.xxx 以下省略
    
    # グループ共通変数を読み込む
    [common_vars:children]
    webserver
    stagingserver
    こうすると、common_varsという名前でgroup_varsの中にファイルを作成すると、どちらのグループからも参照することができる。

MySQL関連

  • MySQL関連として、mysql_dbモジュールmysql_userモジュールがあります。
    ただし、このモジュールを使用する場合は、リモートサーバ側にMySQLのPythonライブラリ(MySQL-Python)やMySQLクライアントが必要になります。
    Pythonライブラリをインストールする際は、リモートサーバ上のPythonバージョンを確認したうえで、適切なバージョンのライブラリをインストールしましょう。参考

データベースの作成

- name: Create database
  mysql_db: 
    db: '{{ mysql_dbname }}' 
    state: present 
    encoding: utf8
    login_user: root
    login_password: '{{ mysql_root_password }}'

ユーザの作成

- name: Create database user
  mysql_user: 
    name={{ mysql_dbuser }}
    password="{{ mysql_dbpass }}"
    priv={{ mysql_dbname }}.*:ALL
    state=present
    host=%
    login_user=root
    login_password='{{ mysql_root_password }}'

DMPのインポート

- name: DBのインポート
  mysql_db:
    name : "database_name"
    state: import
    target: /tmp/all_data.sql #リモート上のパスなので注意
    login_user: "db_admin"
    login_password: "hogehoge"
    login_host: "localhost"

PostgreSQL関連

  • PostgreSQL関連モジュールとして、postgresql_dbモジュールpostgresql_userモジュールがあります。
    ただし、このモジュールを使用する場合は、リモートサーバ側にPostgreSQLのPythonライブラリ(python-psycopg2)やPostgreSQLクライアントが必要になります。
    なお、初回インストール時のinitdbや、接続に必要な設定(postgresql.confのlisten_addressesとかpg_hba.confとか)は設定してくれないので、事前に設定しないと動きません。

データベースの作成

- name : データベース作成
  postgresql_db: 
    name: "{{ pgsql_dbname }}"
    encoding: "UTF-8"
    login_user: postgres
  sudo_user: postgres
  sudo: yes

ユーザ作成

#NOSUPERUSERをつけるとコケる。https://groups.google.com/forum/#!topic/ansible-project/-tDBSPtByfM
- name: ユーザ作成
  postgresql_user: 
    db: "{{ pgsql_dbname }}"
    name: "{{ pgsql_dbuser }}"
    password: "{{ pgsql_dbpass }}"
    priv: ALL
    encrypted: yes
    state: present
    login_user: postgres
    role_attr_flags: "NOCREATEDB,NOCREATEUSER,NOCREATEROLE"
  sudo_user: postgres
  sudo: yes

その他

タスクの失敗を無視したい

  • タスクを実行する時、エラーになっても続行したい場合、ignore_errorsをTrueにすると、失敗しても無視されます。

MySQLのテストデータベースを削除

# RootのPW変更後実行するとエラーになるので、エラーを無視するようにしている。
- name: remove the MySQL test database
  action: mysql_db db=test state=absent login_user=root login_password=''
  ignore_errors: True

テンプレートファイル内で{}が使いたい。

  • シェルスクリプトなど{}をつかうファイルをJinja2テンプレートで作成すると、文法エラーが出て困ることがあります。
    そういうときは、適用させたくないブロックを{% raw %}、{% endraw %}で囲むと、テンプレートが適用されません。
    #!/bin/bash
    
    backup_dir=/var/www/html
    
    {% raw %}
    cd ${backup_dir}
    
    datetime=`date +%Y%m%d%H%M`
    backup_file=/backup/backup_${datetime}.tar.gz
    tar cvzfp ${backup_file} ./
    {% endraw %}

Ubuntuなどでsudoする際にパスワード入力で止まる。

  • ubuntuなどで、sudoする際にパスワード入力が出て止まることがあります。
    まぁちゃんとsudoの設定をすればいいのですが、その作業はAnsibleで出来ないという事になるので、出来ればスクリプト化したいですよね。
    その場合、セキュリティ的には微妙になるのですが、group_varsに
    ansible_sudo_pass: p@ssw0rd
    のようにパスワードを書くと自動入力されます。
    間違ってもgitとかで公開しちゃだめだぞ!!

Ansible実行時、UTF8じゃないと怒られる。

  • Ansible実行時、以下のようなメッセージが出ることがあります。
    ERROR! Unexpected Exception: 'utf8' codec can't decode byte 0x8a in position 82: invalid start byte
    これば、PlayBookがUTF-8じゃないときに出ますので、UTF-8で保存しましょう。
    特に日本語でコメント入れていたりすると結構な頻度で発生します(汗
    ググってもPythonの問題が出てきたりと割とはまります・・・

Ansible実行時、いちいちKnownHostsに登録するか聞いてくるのが面倒

  • SSH接続を公開鍵認証しているとき、カギを作り直したりサーバを作り直したときいちいち登録するか聞いてくるのが面倒になります。
    その時は、Ansibleの実行ユーザにて、以下の設定をすると聞いてこなくなります。
    vi ~/.ansible.cfg
    
    [default]
    host_key_checking = False

Counter: 568, today: 1, yesterday: 0

このページの参照回数は、568です。