この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
渡辺です。
2015年11月にRole を使ったAnsibleのチュートリアル書きました。 それから1年以上経ち、ノウハウも溜まってきたので、新しく書き直してみます。
セットアップ
Ansibleのインストールと、EC2インスタンスを2台起動しておきます。
ssh_configの作成
はじめにホスト情報をssh_config
に定義します。
ansible.cnfでssh_configを設定するでも書いたようにSSHで接続する時のユーザ名や秘密鍵の場所はssh_configを作成してまとめておくと便利です。
プロジェクトディレクトリにssh_config
を作成しましょう。
Host *
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Host test1a
HostName xx.xxx.xx.xxx
User ec2-user
IdentityFile ~/.ssh/dev.pem
Host test1c
HostName xx.xxx.xx.xxx
User ec2-user
IdentityFile ~/.ssh/dev.pem
ssh_config
を作成したならば、SSH接続できることを確認してください。
$ ssh -F ssh_config test1a
Warning: Permanently added 'xx.xxx.xx.xxx' (ECDSA) to the list of known hosts.
__| __|_ )
_| ( / Amazon Linux AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-ami/2016.09-release-notes/
4 package(s) needed for security, out of 8 available
Run "sudo yum update" to apply all updates.
作成したssh_config
はAnsible以外でも利用できるので、一緒にバージョン管理システムに登録しましょう。
inventoryの作成
inventoryファイルには、Ansibleでホストとホストのグループを定義します。 ホストグループを使えば複数のサーバを対象として、Ansibleを流すことができるので便利です。
プロジェクトディレクトリにhosts
という名前でファイルを作成します。
[test]
test1a
test1c
ここではホストグループtestに、ホストtest1aとtest1cを追加しました。
ホスト名はssh_config
で定義したホスト名を使用します。
ansible.cfgを配置する
Ansibleでプロジェクトディレクトリのssh_config
を利用するため、ansible.cfg
を作成します。
[defaults]
inventory = hosts
retry_files_enabled = False
[privilege_escalation]
become = True
[ssh_connection]
control_path = %(directory)s/%%h-%%r
ssh_args = -o ControlPersist=15m -F ssh_config -q
scp_if_ssh = True
合わせてオススメのオプションを設定しておきます。
Playbookを実行する
Playbook test.yml
を作成します。
- hosts: test
roles: []
現時点ではrolesは空配列で良いでしょう。
動作確認します。
$ ansible-playbook test.yml
PLAY [test] ********************************************************************
TASK [setup] *******************************************************************
ok: [test1a]
ok: [test1c]
PLAY RECAP *********************************************************************
test1a : ok=1 changed=0 unreachable=0 failed=0
test1c : ok=1 changed=0 unreachable=0 failed=0
ansible.cfg
でデフォルト値を設定しているため、実行時にinventoryの指定は不要です。
Roleの作成と実行
roles
ディレクトリを作成し、Roleを作成します。
Role system/lang を作成します。
Roleで実行するタスクは roles/[Role名]/tasks/main.yml
に記述してください。
# roles/system/lang/tasks/main.yml
---
- name: set LANG=ja_JP.UTF-8 in /etc/sysconfig/i18n
lineinfile:
dest: /etc/sysconfig/i18n
regexp: "^LANG="
line: "LANG=ja_JP.UTF-8"
backup: yes
このRoleでは、/etc/sysconfig/i18nを編集し、言語設定を変更します。
test.yml
を編集し、system/langをrolesに追加します。
- hosts: test
roles:
- system/lang
実行します。
$ ansible-playbook test.yml
PLAY [test] ********************************************************************
TASK [setup] *******************************************************************
ok: [test1c]
ok: [test1a]
TASK [system/lang : set LANG=ja_JP.UTF-8 in /etc/sysconfig/i18n] ***************
changed: [test1a]
changed: [test1c]
PLAY RECAP *********************************************************************
test1a : ok=2 changed=1 unreachable=0 failed=0
test1c : ok=2 changed=1 unreachable=0 failed=0
社内で共有しているRoleなどがあれば、コピーして使えます。 プロジェクト固有のRoleはそれぞれ作成してください。
グループ変数の追加
再利用可能なRoleは汎用化し、グループ変数で値を指定できるようにします。
まず、Roleで埋め込み変数を参照するように修正しましょう。
# roles/system/lang/tasks/main.yml
---
- name: "set LANG={{ system_lang }} in /etc/sysconfig/i18n"
lineinfile:
dest: /etc/sysconfig/i18n
regexp: "^LANG="
line: "LANG={{ system_lang }}"
backup: yes
system_lang
が埋め込み変数の変数名です。
変数名はグローバルスコープなので注意して名前をつけてください。 また、原則としてダブルクォーテーションで囲った中で利用しないと変数展開が行われないので注意します。
変数はグループ変数に定義すれば良いのですが、Roleで使う場合はデフォルト値があると便利です。
Roleのdefaults
ディレクトリにmain.yml
を作成し、デフォルト変数を定義しましょう。
# roles/system/lang/defaults/main.yml
---
system_lang: ja_JP.UTF-8
なお、varsディレクトリに作成した場合、グループ変数よりも優先されてしまいます。 非情に使い勝手悪いRoleになるので注意しましょう。
Playbookを実行してみます。
$ ansible-playbook test.yml
PLAY [test] ********************************************************************
TASK [setup] *******************************************************************
ok: [test1a]
ok: [test1c]
TASK [system/lang : set LANG=ja_JP.UTF-8 in /etc/sysconfig/i18n] ***************
ok: [test1a]
ok: [test1c]
PLAY RECAP *********************************************************************
test1a : ok=2 changed=0 unreachable=0 failed=0
test1c : ok=2 changed=0 unreachable=0 failed=0
デフォルト変数が適用されているため、サーバの状態は変わりません。
最後にグループ変数を作成します。
group_vars
ディレクトリを作成し、グループ名.ymlを作成します。
# group_vars/test.yml
---
system_lang: en_US.UTF-8
グループ変数はRoleのデフォルト変数よりも強いため、グループ変数の値が優先されます。
実行確認です。
$ ansible-playbook test.yml
PLAY [test] ********************************************************************
TASK [setup] *******************************************************************
ok: [test1a]
ok: [test1c]
TASK [system/lang : set LANG=en_US.UTF-8 in /etc/sysconfig/i18n] ***************
changed: [test1a]
changed: [test1c]
PLAY RECAP *********************************************************************
test1a : ok=2 changed=1 unreachable=0 failed=0
test1c : ok=2 changed=1 unreachable=0 failed=0
グループ変数が反映され、サーバの状態が更新されました。
なお、全ホストに有効な変数を定義する場合は、all.yml
に定義してください。
まとめ
ssh_config
とansible.cfg
を設定することで、パラメータも最小限にRoleをサーバに適用可能です。
再利用できる形にRoleを作成し、効率良いサーバ管理を行いましょう。