複数のシステムのステージとユーザーがいる複雑な環境があります。
ステージは、dev、intなどです。
各ステージにはアプリケーションのユーザーがいます。ユーザーをjohnと呼びましょう。これにより、ユーザーjohndがdevに、johniがintになります。
システム管理を抽象化するために、ステージ内のすべてのシステムが同じであるため、次のデータ構造を作成しました。
users:
john:
dev:
name: "johnd"
int:
name: "johni"
これで、LDAPからすべての種類の情報を収集し、set_factを使用してそれらを変数に格納する「collect_user_information」という役割があります。
- name: Get the userhome out of LDAP
Shell: 'getent passwd {{ users[ user ][ stage ].name }} | cut -d: -f6'
register: user_home
そしてset_fact:
- name: set facts for LDAP user
set_fact:
"{{user}}":
name: "{{ users[ user ][ stage ].name }}"
home: "{{ user_home.stdout }}"
変数をダンプするには、次を使用します。
- name: debug output for myuser
debug: var="{{user}}"
デバッグ出力は有望に見えます。
TASK [collect_user_information : debug output for user] *******
ok: [Host1] => {
"john": {
"home": "/home/johni",-
"name": "johni"
}
}
次に、ユーザーのホームを作成する役割を実行したいと思います。
- { role: create_user_home, user: "john" }
まず、変数のエントリをダンプします。
- name: debug role create_user_home output for variable user
debug: var=user
TASK [create_user_home : debug role create_user_home output for variable user] ***********
ok: [Host1] => {
"user": "john"
}
- name: debug role create_user_home output for variable john
debug: var={{ user }}
TASK [create_user_home : debug role create_user_home output for variable john] **********
ok: [Host1] => {
"john": {
"home": "/home/johni",-
"name": "johni"
}
}
ここで、このデータ構造を使用したいと思います。 「{{user.name}}」または「{{user ['name']}}」を参照することで値にアクセスできると思いますが、どちらも機能しません。
TASK [create_user_home : Create home directories for john] ***********************
fatal: [Host1]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'ansible.parsing.yaml.objects.AnsibleUnicode object' has no attribute 'home'\n\nThe error appears to have been in '/etc/ansible/roles/create_user_home/tasks/main.yml': line 37, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n#-------------------------------------------------------------------------------\n- name: Create home directories for john\n ^ here\n"}
さて、それはどのように機能しますか?
さて、私は自分で解決策を見つけました。
まず、データ構造に追加のレイヤー(myuser)を作成し、別の表記法を使用します。
- name: set facts for LDAP user
set_fact:
myuser: '{ "{{user}}": { "name": "{{ users[ user ][ stage ].name }}", "home": "{{ user_home.stdout }}", "gid": "{{ user_gid.stdout}}", "group": "{{ user_primarygroup.stdout }}" } }'
これにより、次のようなデバッグダンプが返されます。
TASK [collect_user_information : debug output for myuser] ***********
ok: [Host1] => {
"myuser": {
"john": {
"home": "/home/johni",
"name": "johni"
}
}
}
これで、データ構造の値を使用できるようになりました。 「ユーザー」が引数によってロールに渡されたことを忘れないでください。
- name: Create home directories for user
user:
name: "{{ myuser[ user ].name }}"
home: "{{ myuser[ user ].home }}"
Shell: "/bin/bash"
register: "create_user_home"
tags: [ 'user' ]
お役に立てば幸いです。
ここでは全体がトリッキーすぎます。たとえば、変数名がユーザー名である動的変数を定義する必要があります。 john
、john
は、.name
と.home
の2つのキーを含むdictです。
Dict name
のキーuser
を参照するuser.name
を参照しようとしたが、john
と呼ばれるdictを参照しなかったため、最初の試行は失敗しました。
ゴールデンディクトusers
がどこかに定義されているので、物事を複雑にする必要はありません。ホームディレクトリの名前は、いつでもusers[user][stage].name
およびuser_home.stdout
で参照できます。
構文が面倒だと思う場合。名前とホームディレクトリを保存する別のdictを作成することで、元のアプローチに戻ることができます。次の場合、user
は常にプロビジョニングしている現在のユーザーを指します。
- name: set facts for LDAP user
set_fact:
user:
name: "{{ users[username][stage].name }}"
home: "{{ user_home.stdout }}"
後続のタスクでuser.name
およびuser.home
を使用できるようにします。 4行目に注意してください。衝突を避けるために、ロールに渡すvarの名前をusername
に変更しました。
更新:
複数のユーザーのサポート:
- name: Get the user home out of LDAP
Shell: 'getent passwd {{ users[item][stage].name }} | cut -d: -f6'
register: homes
with_items: "{{ users }}"
# item.item is the username, item.stdout is the home dir
- debug: msg="{{ users[item.item][stage].name }}'s home is {{ item.stdout }}"
with_items: "{{ homes.results }}"
続きを読む ループでレジスタを使用 。