[例題] Gitlab Omnibus を Ansible でインストール †
手動でのインストール手順 †
- Install and configure the necessary dependencies
sudo yum install curl policycoreutils openssh-server openssh-clients
sudo systemctl enable sshd
sudo systemctl start sshd
sudo yum install postfix
sudo systemctl enable postfix
sudo systemctl start postfix
sudo firewall-cmd --permanent --add-service=http
sudo systemctl reload firewalld
- Add the GitLab? package server and install the package
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
sudo yum install gitlab-ce
or
download rpm and
rpm -i gitlab-ce-XXX.rpm
- Configure and start GitLab?
sudo gitlab-ctl reconfigure
これを ansible playbook で実現 †
- name: Configure gitlab
hosts: testserver
become: True
gather_facts: False
tasks:
- name: Add EPEL repository
yum_repository:
name: epel
description: EPEL YUM repo
baseurl: http://download.fedoraproject.org/pub/epel/$releasever/$basearch/
- name: Add gpg key of EPEL
rpm_key: key=https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7 state=present
- name: Install Services
yum: name={{ item }} state=present
with_items:
- curl
- policycoreutils
- openssh-server
- openssh-clients
- postfix
- firewalld
- name: Start Services
service: name={{ item }} enabled=Yes state=started
with_items:
- sshd
- postfix
- firewalld
- name: Setup Firewall
firewalld: permanent=True service={{ item }} state=enabled permanent=yes
with_items:
- http
- https
notify: Reload firewall
# - name: Register gitlab-ce yum repo
# shell: curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
# args:
# creates: /etc/yum.repos.d/gitlab_gitlab-ce.repo
#
# - name: Install Gitlab-CE
# yum: name=gitlab-ce state=present
- name: Copy Gitlab-CE
copy: src=files/gitlab/gitlab-ce-8.9.3-ce.0.el7.x86_64.rpm dest=/tmp/
- name: Install Gitlab-CE
yum: name=/tmp/gitlab-ce-8.9.3-ce.0.el7.x86_64.rpm state=present
- name: Configure Gitlab-CE
command: gitlab-ctl reconfigure
handlers:
- name: Reload firewall
service: name=firewalld state=reloaded
実行結果
[~/sourcetree/AnsibleExam/gitlab]$ ansible-playbook gitlab.yml
PLAY [Configure gitlab] ********************************************************
TASK [Add EPEL repository] *****************************************************
changed: [testserver]
TASK [Add gpg key of EPEL] *****************************************************
changed: [testserver]
TASK [Install Services] ********************************************************
ok: [testserver] => (item=[u'curl', u'policycoreutils', u'openssh-server', u'openssh-clients', u'postfix', u'firewalld'])
TASK [Start Services] **********************************************************
ok: [testserver] => (item=sshd)
ok: [testserver] => (item=postfix)
changed: [testserver] => (item=firewalld)
TASK [Setup Firewall] **********************************************************
changed: [testserver] => (item=http)
changed: [testserver] => (item=https)
TASK [Copy Gitlab-CE] **********************************************************
changed: [testserver]
TASK [Install Gitlab-CE] *******************************************************
changed: [testserver]
TASK [Configure Gitlab-CE] *****************************************************
changed: [testserver]
RUNNING HANDLER [Reload firewall] **********************************************
changed: [testserver]
PLAY RECAP *********************************************************************
testserver : ok=9 changed=8 unreachable=0 failed=0
Done.
Playbook の全体構成 †
- playbook 全体の設定
- tasks に、実行モジュールを列挙します
- handers に、task の後処理を列挙します
- task の notify で指定した hander が (もしその task が正常終了した場合) 実行されます
- handler は notify を指定した task 実行直後ではなく、task が全て実行された後に行われることに注意!
playbook を少しづつ読み解く †
play全体の設定 †
- name: Configure gitlab
hosts: testserver
become: True
gather_facts: False
tasks
項目名 | デフォルト値 | 設定内容 |
name | | playの名称 |
hosts | | 実行ホストのパターン (必須) |
tasks | | 実行タスクのリスト (必須) |
vars | | 変数 → cf.Ansible Jinja2 template |
vars_file | | 変数定義 YAML ファイル → cf.Ansible Jinja2 template |
remote_user | | 接続ユーザ → cf.ansible.cfg で共通定義 |
bocome | False | remote_user と異なるユーザでタスクを実行するか? |
become_method | sudo | become=True のとき、異なるユーザになるためのコマンド。{sudo, su, pbrun, pfexec, doas} |
become_user | | タスクを実行するユーザ名 |
sudo | | Ansible2 からは become をつかう |
handlers | | タスク正常終了時に呼び出されるタスクのリスト |
include | | この play に include する YAML ファイル |
gather_facts | True | 実行タスクに関する情報 (CPU/OS/Memoryなど) を収集するか? → Ansible Jinja2 template#fact |
YUMにEPELの追加 †
- name: Add EPEL repository
yum_repository:
name: epel
description: EPEL YUM repo
baseurl: http://download.fedoraproject.org/pub/epel/$releasever/$basearch/
- name: Add gpg key of EPEL
rpm_key: key=https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7 state=present
yum install コマンドの実行 & ansible の loop 構文(with_item) †
- name: Install Services
yum: name={{ item }} state=present
with_items:
- curl
- policycoreutils
- openssh-server
- openssh-clients
- postfix
- firewalld
サービスの立ちあげ (systemctl) †
- name: Start Services
service: name={{ item }} enabled=Yes state=started
with_items:
- sshd
- postfix
- firewalld
firewalld の操作 & ansible の handler †
- name: Setup Firewall
firewalld: permanent=True service={{ item }} state=enabled permanent=yes
with_items:
- http
- https
notify: Reload firewall
...
handlers:
- name: Reload firewall
service: name=firewalld state=reloaded
- handler は、notify がある task の正常終了後に実行されるのではなく、すべての task が実行された後に実行されることに注意
コマンド実行 (shell vs command) とファイルコピー †
# - name: Register gitlab-ce yum repo
# shell: curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
# args:
# creates: /etc/yum.repos.d/gitlab_gitlab-ce.repo
#
# - name: Install Gitlab-CE
# yum: name=gitlab-ce state=present
- name: Copy Gitlab-CE
copy: src=files/gitlab/gitlab-ce-8.9.3-ce.0.el7.x86_64.rpm dest=/tmp/
- name: Install Gitlab-CE
yum: name=/tmp/gitlab-ce-8.9.3-ce.0.el7.x86_64.rpm state=present
- name: Configure Gitlab-CE
command: gitlab-ctl reconfigure
- shell は shell 経由でコマンドを実行 (bash curl ...) → パイプが使える
- command は 直に実行する (gitlab-ctl reconfigure)
- 使い分け : command のほうが安定して実行される。パイプやリダイレクトが必要なときだけ shell を使う
- コマンドを実行してファイルを作るのであれば create オプションで、できるはずのファイルを指定する。そのファイルが存在すると、shell/command を実行しない
rpm コマンドって、どうやって実行するんだっけ? †
- name: Install Gitlab-CE
yum: name=/tmp/gitlab-ce-8.9.3-ce.0.el7.x86_64.rpm state=present
yum モジュールで rpm ファイルを指定する
補遺 (ここで登場しなかった構文) †
with_items 以外 loop †
with_items | リストから要素を一つづつ取り出す |
with_dict | ディクショナリから (item.key , item.value) の組を一つづつ取り出す |
with_fileglob | ファイルパターンに会うファイル名を一つづつ取り出す (files/*.conf とか) |
with_nested | 複数のリストの順列組み合わせを一つづつ取り出す ({a,b}x{1,2,3}=>{a1,a2,a3,b1,b2,b3}) |
with_random_choice | リストから、要素をランダムに一つ取り出す |
with_first_found | リストから、最初の要素を取り出す |
タスクの終了結果による条件分岐 †
- shell : curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
register : result
- debug : msg = "コマンド実行失敗"
when : result | failed
- debug : msg = "状態変更"
when : result | changed
- debug : msg = "コマンド実行成功"
when : result | success
- debug : msg = "スキップ"
when : result | skipped
コマンド実行結果を register で変数にとっておいて、あとで when で評価できる。
コマンド実行結果は {failed, changed, success, skipped}
factによる条件分岐 †
-debut : msg = "RHELです"
when : ansible_os_family == "RedHat"
ファイルの存在確認による条件分岐 †
-stat : path=/etc/yum.repos.d/gitlab_gitlab-ce.repo
register : repo_file_status
-file : path=/etc/yum.repos.d/gitlab_gitlab-ce.repo owner=root group=root mode=400
when: repo_file_status.exists
stat でファイルのステータスを取得して、register で変数にとっておく。
後段の when で条件分岐を行う。
- statの実行結果
stat.uid | owner uid |
stat.pw_name | owner |
stat.gid | group gid |
stat.gr_name | group |
stat.exists | exist? |
stat.atime | last access time |
stat.mtime | last modify time |
stat.size | size |
stat.checksum | sha1 checksum |
stat.mode | permission (octal 777) |
- file moduleのパラメータ
path | パス名 |
src | state が link, hard のとき、リンク元 |
owner | |
group | |
mode | "544" or "u=rw,g=r,o=r" |
state | file, link, directory, hard, touch, absent |
モジュール指定で改行したい †
MEMO †
- インデントずれ注意
- firewalld タスクは firewalld (OSのサービス) が動いていないとエラーを出す
failed: [testserver] (item=http) => {"failed": true, "item": "http", "msg": "firewalld and its python 2 module are required for this module"}
failed: [testserver] (item=https) => {"failed": true, "item": "https", "msg": "firewalld and its python 2 module are required for this module"}
python側の問題か?と思って時間を無駄した
Ansible