web-dev-qa-db-ja.com

1つのロールでset_fact変数を作成し、別のロールで使用します

複数のシステムのステージとユーザーがいる複雑な環境があります。

ステージは、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"}

さて、それはどのように機能しますか?

5
iamcheko

さて、私は自分で解決策を見つけました。

まず、データ構造に追加のレイヤー(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' ]

お役に立てば幸いです。

1
iamcheko

ここでは全体がトリッキーすぎます。たとえば、変数名がユーザー名である動的変数を定義する必要があります。 johnjohnは、.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 }}"

続きを読む ループでレジスタを使用

0
Chris Lam