読者です 読者をやめる 読者になる 読者になる

新人SEの学習記録

14年度入社SEの学習記録用に始めたブログです。気づけば社会人3年目に突入。

学習記録:Ansible

[学習記録] Ansible

参考書籍

入門Ansible

4章:大規模なplaybookを構築してみよう

他のplaybookを読み込む
  • include
    • 他のymlファイルを読み込める
    • 書かれたインデント階層に対して読み込まれる
    • tasks以下でincludeすればtaskファイルを分割可能
    • 以下の例だとhoge01~03.ymlが順次実行されていく
    • 最初からinclude前提にするとどう分割するか悩むので、大きくなってきたら分離するのでOK
---
- name: 全てを実行するplaybook
  hosts: all
  tasks:
    - name: echo doall
    - dmesg: msg="全てを実行します"

- include: hoge01.yml
- include: hoge02.yml
- include: hoge03.yml
推奨ディレクトリ構成
  • Ansibleでは以下のようなディレクトリ構成でファイルを配置することが推奨
    • あくまで推奨であって必須ではない
    • このベストプラクティスにとらわれずに使いやすい構成にするべき
.
|-- group_vars/     # グループごとの変数設定用ディレクトリ
|   |-- dbservers
|   `-- webservers
|-- host_vars/      # ホストごとの変数設定用ディレクトリ
|   |-- db01
|   |-- web01
|   `-- web02
|-- production     # 本番環境用inventoryファイル
|-- staging/       # staging環境用inventoryファイル
|-- site.yml       # site全体用playbook
|-- dbservers.yml  # db用playbook
|-- webservers.yml # web用playbook
`-- roles/         # ロール用ディレクトリ
  • group_vars, host_vars
    • 上記の構成で、dbserverというグループに属するホストdb01に対して操作を行う場合
    • group_vars/dbserversとhost_vars/db01の二つのファイルから変数が読み込まれる
まとめて再利用
  • role
    • 一連のtaskを共有するための仕組み
    • 必要な部分のみ共有するincludeに対し、roleは必要な情報を全てrole以下のディレクトリ内に格納
    • roleを使う指定をするだけで期待している動作を行える
    • roleのディレクトリ構造は以下の通り
    • 変数はvarsから、使用ファイルはfiles以下から検索される
roles   # rolesという名前である必要あり
|-- common/     # 共通role用ディレクトリ
|   |-- defaults    # 変数のデフォルト設定ディレクトリ
|   |    `-- main.yml
|   |-- files       # fileモジュール等で使用されるファイル類
|   |-- handlers    # ハンドラーtask用ディレクトリ
|   |    `-- main.yml
|   |-- meta        # メタ情報用ディレクトリ
|   |    `-- main.yml
|   |-- tasks       # task用ディレクトリ
|   |    `-- main.yml
|   |-- templates   # task用ディレクトリ
|   |    `-- var.js
|   `-- vars        # 変数用ディレクトリ
|        `-- main.yml
|-- app         # app role用ディレクトリ
`-- mysql       # mysql role用ディレクトリ
  • roleの使い方
    • roles以下を作成しておけば、下記のように使用可能
    • tasksとroles両方がplaybookにあった場合、role -> taskの順で実行される
    • roleの前後にtaskを実行したい場合、pre_tasksやpost_tasksを使う
    • varsセクションなどで与える変数名は{role名}_{変数名}のようにしておくと重複する可能性が低くなる
---
- hosts: webservers
  roles:
    - common
    - app
並列実行
  • fork
    • 対象ホストが多くなってくると実行に時間が掛かってくる
    • 標準では5台までしか並列に動作しないため、6台以上になるとかなり時間がかかる
    • -f, --forksオプションをつけて実行するか、ansible.cfg設定ファイルのforksを設定することで並列実行数を変更可能
    • 並列実行数を増やすと同時実行できるsshの数が増える
    • sshに必要なCPUやメモリは比較的少ないので、20から50くらいにしても多くの場合問題ない
$ ansible-playbook -f 50 large_hosts.yml
順々に実行する
  • serial
    • 複数台サーバがあり、設定を更新して再起動していく場合では並列実行すると全サーバが落ちてしまう
    • serialを適切に設定することで、サービス自体は落とさないまま設定を更新していくrolling upgradeが実現可能
---
- hosts: webservers
  users: root
  serial: 1
AWS EC2との連携
  • Ansibleは多くのクラウドに対応しており、AWSやDigital Oceanなどのインスタンスを立ち上げ可能
    • AWSなどを操作するのは管理ホスト側なので、local_actionを使用
    • 動的にホスト情報を追加するため、add_hostモジュールを使う必要がある
---
- hosts: localhost
  gather_facts: no
  tasks:
    - name: startup ec2 instance
      local_action:
        module: ec2
        instance_type: t1.small
        image: ami-c9562fc8
        group: your-group-name
        region: ap-northeast-1
        key_name: your-key-name
        wait: yes
        count: 1
      register: ec2
    - name: hostグループに新しいインスタンスを追加
      local_action:
        module: add_host
        hostname: "{{ item.public_ip }}"
        ansible_ssh_private_key_file: your-key-name
        groupname: launched
      with_items: ec2.instances
    - name: SSHが通じるまで待つ
      local_action:
        module: wait_for
        host: "{{ item.public_dns_name }}"
        port: 22
        delay: 60
        timeout: 320
        state: started
      with_items: ec2.instance

- hosts: launched
  user: ec2-user
  roles:
    - somerole
ホストのリストを動的に作成
  • dynamic_inventory
    • AWSなどのクラウドを使用している場合、ホストの作成と破棄が多くなり、inventoryファイルの管理が大変に
    • inventoryファイルとしてスクリプトを指定すると、Ansibleはスクリプトの実行結果をホストやグループ情報として扱う
    • ec2.pyとec2.iniを使うことでec2上のホストをansibleから扱うことが可能
$ ansible-playbook -i ec2.py -l secutiry_group_default deploy.yml
  • ec2.py
    • 上記の例では対象ホストを制限する-lオプションでsecurity groupを指定
    • インスタンスidやregionなどで自動的にグループ分けされるので任意のグループに対してplaybookを実行可能

5章:コマンドラインオプションを使ってみよう

ansible-playbookコマンドには多くのコマンドラインオプションが存在

ssh認証
  • -k, --ask-pass
    • sshの接続用パスワードを設定
  • --private-key=key
  • --ask-su-pass
    • suのパスワードを設定
  • -K, --ask-sudo-pass
    • sudoパスワードを設定
  • -S, --su
    • suで実行するよう指定
  • -s, --sudo
    • sudoで実行するよう指定
  • -R SU_USER, --su-user=SU_USER
    • su実行時にユーザを指定できる。デフォルトはroot
  • -U SUDO_USER, --sudo-user=SUDO_USER
    • sudo実行時のユーザを指定。デフォルトはroot
  • -u REMOTE_USER, --user=REMOTE_USER
    • ssh接続時のユーザ名を設定できる
対象ホストを制限する
  • limit
    • 実行対象ノードの指定は、通常hosts: allという形でplaybook内で設定
    • -lオプションを使うと、これを上書き可能
    • 実行対象について複雑な指定ができる
    • playbook内では検証環境を設定しておき、本番環境に対してデプロイ時にはコマンドラインで指定
# webグループに実行
$ ansible-playbook -l web deploy.yml

# webグループのうちweb02以外
$ ansible-playbook -l "web:\!web02" deploy.yml
実行するtaskを制限
  • tag
    • taskにtagsを付けておき、コマンドラインオプションで-tを指定
    • 一つのplaybook中で任意のtaskだけを実行できる
---
- tasks:
  - yum: name=httpd state=installed
    tags:
      - install
      - config
  - template: src=httpd.conf.j2 dest=/etc/httpd/httpd.conf
    tags:
      - config
  • -tあるいは--tagsをコマンドラインで指定すると、tagで設定されているtaskのみが実行される
$ ansible-playbook site.yml --tags "install"
dry-run実行
  • check
    • --checkを付けて実行すると、実際に実行はせずに変化が起きるかどうかだけを報告してくれる
    • いわゆるdry-run機能
    • check modeに対応しているモジュールであれば、どのような変化が起こるかを報告してくれる
$ ansible-playbook something.yml --check
taskを確認しながら実行
  • step
    • playbook中で実行されるtaskを一つ一つ確認しながら実行していきたい場合
    • その時には--stepを指定
    • 全てのtaskについて実行するかを聞いてくる(y/n/c)
    • yは実行、nはskipして次のtask実行、cはそのtask以降すべてのtaskを実行
差分表示
  • diff
    • --diffをつけて実行すると、変化した内容の差分表示ができる
    • checkと併せて使うことで、これからどう変化が起きるか実際に見てから動作させることが可能