LoginSignup
21
17

More than 5 years have passed since last update.

Ansibleならローカルのシェルスクリプトをリモートホストで実行できて便利

Posted at

はじめに

サーバ移行作業などで、旧サーバでバックアップを取得してダウンロードし、新サーバにアップロードするといった作業がよくあると思います。

通常だとバックアップを取得するためのシェルスクリプトを旧サーバに配置して実行、できたアーカイブファイルを新サーバに直接 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を読み込むようにします。

ansible.cfg
[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とインベントリに記載するホスト名を一致させます。

ssh_config
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

site.yml
---
- include: playbooks/adhoc_work.yml

inventory

inventories/adhoc_work
[adhoc_work]
sourcehost01 #旧サーバ1
sourcehost02 #旧サーバ2

group_vars

インベントリの[adhoc_work]グループ全体に適用される変数です。
今回のadhocな処理で共通のパラメータを定義します。
ここでは例としてアーカイブファイルのコピー先ディレクトリを定義しています。

group_vars/adhoc_work.yml
---
destination:
  path: /PATH/TO/DEST_DIR  #アーカイブファイルのコピー先ディレクトリ(新サーバ)

host_vars

ホスト固有の変数を定義します。
ここでは例として旧サーバに対応する新サーバのホスト名を定義しています。

host_vars/sourcehost01.yml
---
destination:
  host: desthost01 #新サーバ1
host_vars/sourcehost02.yml
---
destination:
  host: desthost02 #新サーバ2

playbook

playbooks/adhoc_work.yml
---
- name: adhoc task
  hosts: adhoc_work
  roles:
    - ../roles/adhoc_work

Role

roles/adhoc_work/tasks/main.yml
---
- 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を利用してみるというのはいかがでしょうか。

21
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
17