モジュール
setup
ansible.builtin.setup – Gathers facts about remote hosts — Ansible Documentation
facts変数を収集する。
ad-hocで実行する方が多いかも?
$ ansible -i inventory.ini all -m setup
assert
ansible.builtin.assert – Asserts given expressions are true — Ansible Documentation
- name: assert sample
vars:
hoge: "zzz"
foo: "bar"
baz: False
ansible.builtin.assert:
that:
- "hoge is defined"
- foo is defined
- baz is defined and baz
fail_msg: "'hoge','bar' must be defined, 'baz' must be true"
register: assert_result
that
で指定した各値がtrueでなければタスクが失敗する。
変数ではなく文字列で指定するので、:
を含む文字はYAMLのキーとしてparseされてしまうため、ダブルクォートなどで囲む必要がある。
- name: assert
ansible.builtin.assert:
that:
- 'sample_text | regex_search("could not found: foobar")'
uri
HTTPをしゃべる。
以下はAWX/AAPで通知テストをkickするRESTを叩くタスク。
basic認証+HTTPSでSSL検証無効の設定で、レスポンスコードが200
or201
or202
を期待している。
ansible.builtin.uri:
method: POST
url: "https://{{ aap_address }}/api/v2/notification_templates/{{ notify_id }}/test/"
url_username: "{{ username }}"
url_password: "{{ password }}"
validate_certs: false
force_basic_auth: true
status_code: [200, 201, 202]
lineinfile
ansible.builtin.lineinfile – Manage lines in text files — Ansible Documentation
lineinfile:
path: lineinfile.txt
regexp: '^port: 80'
line: 'port: 8080'
lineinfile.txtファイルの中の^port: 80
に 最後に マッチする行をport: 8080
に変更。
port: 8080
が有る場合は、他に^port: 80
にマッチしてもそれは対象外。
最初に マッチする行を対象にする場合はfirstmatch: true
を指定。
ファイル内にマッチする行が見つからなかった場合は、デフォルトではファイル末尾に追記される。
ファイル末尾以外に追記したい場合は、insertafter
またはinsertbefore
を使うことで、指定行直下・または直前に挿入できる。
insertafter
とinsertbefore
は指定できるのはどちらか片方。(両方同時指定は不可)
blockinfile
マーカー行が複数ある場合は、「ファイル内一番末尾の開始マーカー・終了マーカー」の間が処理対象になった。(ansible 2.10 / ansible 2.11で確認)
# /share/www configure begin
1
# /share/www configure end
# /share/www configure begin
2
# /share/www configure end
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
# /share/www configure begin
3
# /share/www configure end
こんな入力ファイルに対して
- name: blockinfile sample
blockinfile:
path: blockinfile-test.txt
marker_begin: begin
marker_end: end
marker: '# /share/www configure {mark}'
block: |
...
を実行すると、更新されるのは 3
の部分のみ。
(複数のbegin行がある場合は最後のものが使用される)
入力ファイルが以下の場合は、1
から3
までの範囲が更新される。
(end行も複数ある場合は最後のものが使用される)
# /share/www configure begin
1
# /share/www configure end
2
# /share/www configure end
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
3
# /share/www configure end
これなら一度で確かめられた。
↓のファイルなら、blockinfileが更新するのは3
から5
まで。
# /share/www configure begin
1
# /share/www configure begin
2
# /share/www configure begin
3
# /share/www configure end
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
4
# /share/www configure end
5
# /share/www configure end
replace
after
/before
で「ここからここまでの間」を指定できる。
- name: replace sample
replace:
path: duplicate-test.txt
regexp: ^[0-9]+$
replace: zzz
after: '# /share/www configure begin'
before: '# /share/www configure end'
入力ファイルが↓のように複数マッチする場合は
# /share/www configure begin
1
# /share/www configure begin
2
# /share/www configure begin
3
# /share/www configure end
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
4
# /share/www configure end
5
# /share/www configure end
1
から3
までが対象だった。(after
もbefore
も最初にマッチした部分が対象)
redhat_subscription
RHELのサブスクリプション割り当てを行う。 開発者ライセンスならプールIDは1個しかないので
- name: subscription
community.general.redhat_subscription:
state: present
username: "{{ rh_username }}"
password: "{{ rh_password }}"
auto_attach: true
ですべて完了する。
制限ネットワーク環境のRHEL7でproxy経由でサブスクリプション登録とDockerインストール - zaki work log
これでいうとsubscription-manager register
してsubscription-manager attach --pool=****
まで終わった状態になる。
alternatives
community.general.alternatives
でalternatives
コマンドを使ったコマンド切り替え設定を行う。
- name: alternatives python
community.general.alternatives:
name: python
link: /usr/bin/python
path: /usr/bin/python3
become: true
これで、/usr/bin/python
-> /etc/alternatives/python
-> /usr/bin/python3
へのリンクがpython
という名前で登録される。
コマンドとしては以下と同等。
(priority
はデフォルト50)
# update-alternatives --install /usr/bin/python python /usr/bin/python3 50
パッケージ
dnf
CentOS7(yum環境)に使える? => NG
fatal: [cloud-dev]: FAILED! => changed=false
msg: Could not import the dnf python module using /usr/bin/python (2.7.5 (default, Nov 16 2020, 22:23:17) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]). Please install `python3-dnf` or `python2-dnf` package or ensure you have specified the correct ansible_python_interpreter. (attempted ['/usr/libexec/platform-python', '/usr/bin/python3', '/usr/bin/python2', '/usr/bin/python'])
results: []
ただし、CentOS7でsudo yum install python2-dnf
を入れると動く。
dnfモジュールでパッケージインストールし、CentOS7上でrpm -qa
とかしても確認できる。
yum
Fedora34 / RHEL8に使える? => OK
apt_repository
- name: add apt repository
ansible.builtin.apt_repository:
repo: deb [arch=arm64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu focal stable
filename: docker
これで以下のファイルが作成される。
$ cat /etc/apt/sources.list.d/docker.list
deb [arch=arm64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu focal stable
このとき、/etc/apt/sources.list.d/docker.list
以外のファイルですでに同じ設定がある場合はdocker.list
は作成されずにok
となる。
ファイル
state
file
対象ファイルがない場合はエラーになる。
逆手にとってファイル存在チェックに使える(その場合エラーは無視するようにする必要はある)
以下は/var/tmp/ansible-file
が無い場合に最初のタスクが失敗(ignore_errors
により無視)し、次のタスクでfile not exist
が出力される。ファイルがある場合は最初のタスクは成功し、続くタスクはwhen
の条件を満たさないためスキップされる。
- name: exist file?
file:
path: /var/tmp/ansible-file
state: file
register: result
ignore_errors: true
- debug:
msg: file not exist
when: result is failed
failed_when
を使うなら以下
- name: dounaru
file:
path: /var/tmp/ansible-file
state: file
register: result
failed_when: false
- debug:
msg: file not exist
when: result.state == "absent"
モード
- name: create file
file:
path: /var/tmp/file_permission
mode: "0755"
state: directory
これなら
$ ll -d /var/tmp/file_permission/
drwxr-xr-x. 2 zaki zaki 6 7月 31 10:27 /var/tmp/file_permission/
mode | 実体 |
---|---|
"0755" (str) |
drwxr-xr-x |
0755 (int) |
drwxr-xr-x |
"755" (str) |
drwxr-xr-x |
755 (int) |
d-wxrw--wt |
755
にすると、10進数の755入力を8進数と解釈し1363
としてモード設定される動作になる。
モード設定は8進数の数値か文字列型の数値が入力なのと、先頭ゼロの数値は8進数としてYAMLが解釈するので、先頭ゼロを付けずにintの数値を指定すると想定外の動作になる。
fetch
ターゲットノードのファイルをコントロールノードへコピーする。
ディレクトリは不可。(src
のパスがディレクトリの場合は失敗する)
fatal: [fedora-node]: FAILED! => changed=false
file: /home/zaki/src/docker-images/
msg: remote file is a directory, fetch cannot work on directories
ドキュメントのsrcパラメタの項にも記載あり。
This must be a file, not a directory.
fetchモジュールの使い方全般ははてブに書いた。
[Ansible] fetchモジュールを使ってリモートのファイルを実行ノードへ転送・集約する - zaki work log
slurp
ターゲットノード上のファイルの中身を取得する。
fetchと異なりファイルシステム上へ保存せずにオンメモリ処理。
base64エンコードされているのででコードして使用する。
- name: get private key
ansible.builtin.slurp:
src: /home/ec2-user/.ssh/id_rsa
register: ssh_private_key
- name: create repository credential on awx
awx.awx.credential:
name: git-repository-credential
organization: Default
credential_type: Source Control
inputs:
username: ec2-user
ssh_key_data: "{{ ssh_private_key.content | b64decode }}"
make
/path/to/awx-operator
ディレクトリ上でmake deploy IMG=zakihmkc/awx-operator:0.17.0
を実行するタスクであれば以下の通り。
- name: deploy awx-operator
community.general.make:
chdir: /path/to/awx-operator
target: deploy
params:
IMG: zakihmkc/awx-operator:0.17.0
ターゲットファイル作成済みでmake
が何も処理しない場合は、実行ステータスはok
となる。
meta
再接続
たとえば、OSユーザーのグループを更新した場合、通常であればログインし直さなければ変更が反映されない。
Ansibleも同様で、タスクでグループの更新を行っても、後続のタスクは接続が維持されているため、更新されたグループの状態でタスクが実行されない。
この場合、metaモジュールのreset_connection
を使って再接続を行い、変更を反映して後続のタスクを実行できる。
- name: グループを変更するタスク
...
- name: refresh connection
ansible.builtin.meta: reset_connection
- name: 変更したグループ前提のタスク
...
playの終了
プログラムにおけるexit(0)
みたいなやつ。
任意のタイミングでplayを正常終了させることができる。
tasks:
- name: task1
debug:
msg: task1
- name: task2
debug:
msg: task2
- name: end play
ansible.builtin.meta: end_play
- name: task3
debug:
msg: task3
このplaybookの内容でAnsible実行すると、以下の通りtask3は実行されずに終了する。
PLAY [localhost] ****************************************************************
TASK [task1] ********************************************************************
ok: [localhost] =>
msg: task1
TASK [task2] ********************************************************************
ok: [localhost] =>
msg: task2
TASK [end play] *****************************************************************
PLAY RECAP **********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
インベントリの再読み込み
ダイナミックインベントリでホスト情報を再収集したい場合、など。
- name: refresh inventory
ansible.builtin.meta: refresh_inventory
[Ansible] 任意のタイミングでダイナミックインベントリのホスト情報収集を行う - zaki work log
Docker
push image
docker_image
を使用しパラメタにpush: true
を指定。
- name: push container image
community.docker.docker_image:
name: quay.io/ansible/awx-ee
repository: zakihmkc/awx-ee:0.6.0
push: true
source: local
このタスクの場合は、ローカルにあるquay.io/ansible/awx-ee
イメージをDocker Hubへzakihmkc/awx-ee:0.6.0
としてpush
する。
このとき、zakihmkc/awx-ee:0.6.0
が既にローカルにある場合はtagの上書きが発生しないため、pushされない。ここでpushしたい場合は、tag設定を上書きするforce_tag: true
も追加する。
git
ansible.builtin.git:
repo: https://github.com/zaki-lknr/awx_build_and_deploy.git
version: feature/awx-ver-21.13.0
dest: /var/tmp/work-dir
destのディレクトリは事前に作成しておく。
GitモジュールはCLIのgit clone
と異なり、上の例でいうとawx_build_and_deploy
サブディレクトリは作成されない。
ssh
openssh_keypair
ssh key pair作成
community.crypto.openssh_keypair:
path: "{{ ansible_env.HOME }}/.ssh/id_rsa"
size: 4096 # default
type: rsa # default
register: ssh_keypair_result
authorized_key
authorized_keys
への公開鍵登録
ansible.posix.authorized_key:
user: "{{ ansible_env.USER }}"
key: "{{ ssh_keypair_result.public_key }}"
# key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
delegate_to: localhost
run_once: true
pause
sleepする
- name: sleep
ansible.builtin.pause:
seconds: 10
単純なsleepでなく、最大で指定時間だけwaitがかかり、その間にCtrl-c
押下で「即再開 or 処理中断」の選択が可能になる。
a
で中断した場合はそこで処理が終了する。
TASK [sleep] *************************************************************************
Pausing for 10 seconds
(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)
Press 'C' to continue the play or 'A' to abort
fatal: [localhost]: FAILED! =>
msg: user requested abort!
debug
msg
を使えば(変数を含め)任意の文字列をプリントする。
変数だけで良ければvar
を使う方が楽。
---
- hosts: localhost
gather_facts: false
vars:
val1: 1234
tasks:
- debug:
var: val1
ただしvar
の場合はリスト出力は不可
debug:
var:
- val1
- val2
# 不可