はじめに
サーバ移行作業などで、旧サーバでバックアップを取得してダウンロードし、新サーバにアップロードするといった作業がよくあると思います。
通常だとバックアップを取得するためのシェルスクリプトを旧サーバに配置して実行、できたアーカイブファイルを新サーバに直接 or 一度ローカルにダウンロードして転送する流れになるかと思いますが、対象サーバの数が多くなると面倒です。
こういった作業にAnsibleを利用するとかなり楽になりますよ! というネタです。
今回は**「ローカルにあるスクリプトをリモートホスト(旧サーバ)で実行し、生成されたファイルをローカルにダウンロードし、別のリモートホスト(新サーバ)にアップロードする」**というシナリオをAnsibleでやってみます。
構成管理だけではない、Ansibleの利用方法をご紹介します。
概要
- Ansibleの
script
モジュールを利用すると、ローカル上のシェルスクリプトをリモートホストで実行できる - その際、
creates:
でファイルの存在をスクリプトの実行条件にできるので、何度も同じホストに対して実行されることはない - 旧サーバからのファイルダウンロードおよび新サーバへのファイルアップロードは
shell
モジュールでscp
コマンドをローカル実行する - 対象サーバはホスト名のみをインベントリに記載
- インベントリのホスト情報に対応した
ssh_config
を用意し、インベントリのホスト情報をscp
コマンドでも利用する
#前提
- Ansibe2.3系で動作確認しています
#sample
##ディレクトリ構成
ansible.cfg
ssh_config
site.yml
inventories/
|--adhoc_work
roles/
|--adhoc_work/
| |--tasks/
| | |--main.yml
| |--files/
| | |--your_script.sh #旧サーバに対して実行するシェルスクリプト
playbooks/
|--adhoc_work.yml
group_vars/
|--adhoc_work.yml
host_vars/
|--sourcehost01.yml
|--sourcehost02.yml
ansible.cfg
ssh_args = -F ssh_config
とすることで、Ansible実行時にカレントディレクトリのssh_config
を読み込むようにします。
[defaults]
hash_behaviour = merge
gathering = false
timeout = 300
[ssh_connection]
pipelining = True
control_path = /tmp/ansible-ssh-%%h-%%p-%%r
ssh_args = -F ssh_config
[privilege_escalation]
become = True
ssh_config
通常の.ssh/config
と同様に定義します。
Host
とインベントリに記載するホスト名を一致させます。
Host sourcehost01
HostName WW.WW.WW.WW
User XXXX
IdentityFile ~/.ssh/xxxx.pem
Host sourcehost02
HostName XX.XX.XX.XX
User XXXX
IdentityFile ~/.ssh/xxxx.pem
Host desthost01
HostName YY.YY.YY.YY
User XXXX
IdentityFile ~/.ssh/xxxx.pem
Host desthost02
HostName ZZ.ZZ.ZZ.ZZ
User XXXX
IdentityFile ~/.ssh/xxxx.pem
site.yml
---
- include: playbooks/adhoc_work.yml
inventory
[adhoc_work]
sourcehost01 #旧サーバ1
sourcehost02 #旧サーバ2
group_vars
インベントリの[adhoc_work]
グループ全体に適用される変数です。
今回のadhocな処理で共通のパラメータを定義します。
ここでは例としてアーカイブファイルのコピー先ディレクトリを定義しています。
---
destination:
path: /PATH/TO/DEST_DIR #アーカイブファイルのコピー先ディレクトリ(新サーバ)
host_vars
ホスト固有の変数を定義します。
ここでは例として旧サーバに対応する新サーバのホスト名を定義しています。
---
destination:
host: desthost01 #新サーバ1
---
destination:
host: desthost02 #新サーバ2
playbook
---
- name: adhoc task
hosts: adhoc_work
roles:
- ../roles/adhoc_work
Role
---
- name: リモートホストに対してローカルにあるシェルスクリプトを実行
script: your_script.sh
args:
creates: /tmp/your_archive.file #アーカイブファイルのパス(旧サーバ)。このファイルが存在した場合、スクリプトは実行されない
when: not ansible_check_mode
- name: バックアップファイル格納ディレクトリ作成(ローカル)
file:
path: "{{ inventory_dir }}/backup"
state: directory
delegate_to: localhost
check_mode: no
changed_when: no
become: no
- name: リモートホストからバックアップファイルをダウンロード
shell: "scp -F {{ inventory_dir }}/../ssh_config {{ inventory_hostname }}:/tmp/your_archive.file {{ inventory_dir }}/backup/{{ inventory_hostname }}_archive.file"
delegate_to: localhost
become: no
- name: リモートホストからダウンロードしたバックアップファイルを削除
file:
path: /tmp/your_archive.file
state: absent
- name: バックアップファイルアップロード to 新サーバ
shell: "scp -F {{ inventory_dir }}/../ssh_config {{ inventory_dir }}/backup/{{ inventory_hostname }}_archive.file {{ destination.host }}:{{ destination.path }}/."
delegate_to: localhost
become: no
実行
旧サーバ1に対して実行
$ ansible-playbook -i inventories/adhoc_work -l sourcehost01 site.yml
インベントリに定義してある旧サーバにまとめて実行
$ ansible-playbook -i inventories/adhoc_work site.yml
まとめ
Ansibleでの構成管理はハードルが高いという方は、このように運用作業にAnsibleを利用してみるというのはいかがでしょうか。