てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] コマンド版で使用している Playbook を Ansible Tower / AWX に載せる前にチェックしたいポイント

はじめに

Ansible Tower / AWX は、GUI からジョブという実行単位を経由して、Playbook を実行します。

そのため、CLI からの対話的な操作は受け付けられません。

Ansible Tower / AWX に載せる前に他の方法に変える必要があります。

vars_prompt による対話的な変数設定は Survey へ

vars_prompt、は CLI からの対話的な入力を必要とします。Ansible Tower / AWX ではそのままでは利用できません。

その代わりに、Survey という機能で、GUI で変数の設定ができます。

参考: 26. Best Practices — Ansible Tower User Guide v3.7.0

無期限 の pause は使わない

pause という、処理を止めるモジュールがあります。

CLI からは止まってる途中でも Ctrl+C で強制終了できますが、Ansible Tower / AWX ではできません。

止める必要がある場合は、タイムアウトを設定します。

参考: 26. Best Practices — Ansible Tower User Guide v3.7.0

Playbook (ジョブ)を分割してもよいのであれば、2つのジョブの間に、期限なしの Approval Node を挟むワークフローにしても良いともいます。(Ansible Tower 3.6 以降)

参考: How to add approval steps to Ansible Tower workflows

Playbook Debugger

Playbook Debugger は、Playbook の実行を途中でとめて、変数の値を表示、変更したりできるデバッガです。 これも CLI からの入力を必要とします。

あくまで、Debugger は CLI から使うという役割分担となります。

[Ansible] つまずきながら進める Ansible 【Part2】ふりかえり

はじめに

2020/05/23 に、YouTube Live でつまずいきながら進める Ansible 【Part2】という配信をしました。 実際に作業しながらエラーと戦って進めるシリーズです。

前回の Part1(動画ふりかえりブログ)では、Ansible のインストール、インベントリファイルの作成、簡単な Playbook の作成を行いました。

Playbook は Cisco IOS の機器の、show ip route コマンドの実行コマンドを、ファイルに保存するというものでした。しかし、まだ余計な情報が多かったり、思った形式になっていませんでした。

また、いきなり Playbook を作成してしまいましたが、その前に疎通確認のステップをしたほうが良かったように思います。

Part 2 では、疎通確認と、Playbook の改善をしました。

つまずいたエラーと原因、対処をふりかえります。

動画

www.youtube.com


■ 疎通確認

ping モジュールを疎通確認として利用できない

ping モジュールは、ターゲットノード(接続先)で Python が利用できるか確認するモジュールです。

よく ansible コマンド(アドホックコマンド)と併用して、Ansible としての疎通確認(ICMP ではなく、ssh + python)に利用されます。

Cisco IOSping モジュールを利用したところ、接続情報が誤っているのにもかかからず ok となってしまった。

$ ansible -i inventory.ini all -m ping
rt01 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

原因

Ansible 2.9 からの仕様。

ネットワーク機器向けのコネクションプラグイン利用時に ping モジュールを使っても、ターゲットノードに接続しにいかないため、接続確認として機能しない。

参考: [Ansible] ネットワーク機器に接続する条件はバージョンやコネクションブラグインによって異なる - てくなべ (tekunabe)

対処

ping モジュールではなく、実際ににネットワーク機器に接続しに行くモジュールを利用する。

$ ansible -i inventory.ini all -m ios_facts
[WARNING]: default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards
rt01 | SUCCESS => {
    "ansible_facts": {
        "ansible_net_all_ipv4_addresses": [
            "192.168.1.11",
         // ...(略)...
        ],
        "ansible_net_system": "ios",
        "ansible_net_version": "15.8(3)M2",
        "ansible_network_resources": {},
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false
}

コマンドは任意だがここでは show version

$ ansible -i inventory.ini all -m ios_command -a "commands='show version'"
rt01 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "stdout": [
        // ...(略)...
    ],
    "stdout_lines": [
        [
            "Cisco IOS Software, IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.8(3)M2, RELEASE SOFTWARE (fc2)",
            "Technical Support: http://www.cisco.com/techsupport",
            "Copyright (c) 1986-2019 by Cisco Systems, Inc.",
            "Compiled Thu 28-Mar-19 14:06 by prod_rel_team",
            "",
           // ...(略)...
            "Configuration register is 0x0"
        ]
    ]
}

参考: Network Debug and Troubleshooting Guide — Ansible Documentation

gather_facts モジュールでも可能。

setup モジュールは、ネットワーク機器に接続しにいかないため、疎通確認としては利用不可。


■ コマンド実行結果の整形

コマンド実行結果のファイルに余計な情報がは入ってしまう

{"changed": false, "stdout": ["Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP\n       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area \n       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2\n       E1 - OSPF external type 1, E2 - OSPF external type 2\n       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2\n       ia - IS-IS inter area, * - candidate default, U - per-user static route\n       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP\n       a - application route\n       + - replicated route, % - next hop override, p - overrides from PfR\n\nGateway of last resort is not set\n\n      10.0.0.0/8 is variably subnetted, 3 subnets, 2 masks\nC        10.0.0.0/24 is directly connected, GigabitEthernet0/3\nL        10.0.0.1/32 is directly connected, GigabitEthernet0/3\nC        10.255.255.1/32 is directly connected, Loopback0\n      192.168.1.0/24 is variably subnetted, 2 subnets, 2 masks\nC        192.168.1.0/24 is directly connected, GigabitEthernet0/0\nL        192.168.1.11/32 is directly connected, GigabitEthernet0/0"], "stdout_lines": [["Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP", "       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area ", "       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2", "       E1 - OSPF external type 1, E2 - OSPF external type 2", "       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2", "       ia - IS-IS inter area, * - candidate default, U - per-user static route", "       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP", "       a - application route", "       + - replicated route, % - next hop override, p - overrides from PfR", "", "Gateway of last resort is not set", "", "      10.0.0.0/8 is variably subnetted, 3 subnets, 2 masks", "C        10.0.0.0/24 is directly connected, GigabitEthernet0/3", "L        10.0.0.1/32 is directly connected, GigabitEthernet0/3", "C        10.255.255.1/32 is directly connected, Loopback0", "      192.168.1.0/24 is variably subnetted, 2 subnets, 2 masks", "C        192.168.1.0/24 is directly connected, GigabitEthernet0/0", "L        192.168.1.11/32 is directly connected, GigabitEthernet0/0"]], "failed": false}

原因

register で保存したコマンド実行結果には、コマンド実行そのもの以外にもメタ情報が含まれるため。

対処

result の内容を確認して、必要な箇所である、result.stdout[0] を指定する。

Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
       a - application route
       + - replicated route, % - next hop override, p - overrides from PfR

Gateway of last resort is not set

      10.0.0.0/8 is variably subnetted, 3 subnets, 2 masks
C        10.0.0.0/24 is directly connected, GigabitEthernet0/3
L        10.0.0.1/32 is directly connected, GigabitEthernet0/3
C        10.255.255.1/32 is directly connected, Loopback0
      192.168.1.0/24 is variably subnetted, 2 subnets, 2 masks
C        192.168.1.0/24 is directly connected, GigabitEthernet0/0
L        192.168.1.11/32 is directly connected, GigabitEthernet0/0

調べる際は、Playbook Debugger で試行錯誤できるのが便利。

    - name: save to file
      copy:
        content: "{{ result.stdout[0] }}"
        dest: "show_ip_route_{{ inventory_hostname }}.log"
      debugger: always    # タスク実行時に無条件で Playbook Debugger を起動

Playbook Debugger の使い方は、書籍「Ansible 実践ガイド 第3版」のP368「7-4-4 Playbook Debugger」にも掲載されています(宣伝)。

book.impress.co.jp


■ show コマンドの追加

show running-config コマンドが実行できない

原因

権限不足。 ログインユーザーが一般ユーザーだったため、show ip route は実行できても、how running-config は実行できない。

対処

変数定義ファイル(今回は group_vars/ios.yml)に、権限昇格のための以下の変数を追加。

ansible_become: true 
ansible_become_method: enable
ansible_become_password: secret 

参考: IOS Platform Options — Ansible Documentation


Part 3 にむけて

次回の Part 3 では、以下のアンケートで2番目に多かった、ルーティングの設定をしてみたいと思います。

[Ansible] Ansible Tower 3.7.0 でワークフローノード作成モジュール(awx.awx.tower_workflow_job_template_node)が使えるようになった

はじめに

先日、Ansible Tower 3.7 がリリースされました。

ワークフロージョブテンプレートに対して、ワークフローノードを定義する awx.awx.tower_workflow_job_template_node が、Asnible Tower 3.6 系に対しては使えなかったのですが、3.7 に試したら使えるようになってました。(もともとの使い方がうまくなかったのであればすみません・・)

もともと AWX には使えていたので、同等の実装が入ったのだと思います。

簡単なサンプルで検証します。

利用するファイル

ワークフローを定義する変数ファイルと、それを利用する Playbook です。

  • 変数定義ファイル(抜粋)
workflow_templates:
  - name: wf_show
    desicription: show command workflow
    nodes:
      - identifier: node101   # 内部識別ID
        unified_job_template: jt_show   # 実行するジョブテンプレート
        success_nodes:  # 成功時に進めるノード(緑のリンク)
          - node201
          - node202
        failure_nodes:  # 障害発生時に進めるノード(赤のリンク)
          - node209
      - identifier: node201
        unified_job_template: jt_show
        success_nodes:
          - node301
      - identifier: node202
        unified_job_template: jt_show
        success_nodes:
          - node301
      - identifier: node209
        unified_job_template: jt_show
      - identifier: node301
        unified_job_template: jt_show
  • Playbook(タスク抜粋)
    - name: create workflow templates node
      awx.awx.tower_workflow_job_template_node:
        identifier: "{{ item.1.identifier }}"
        unified_job_template: "{{ item.1.unified_job_template | default(omit) }}"  # 実行するジョブテンプレート
        workflow_job_template: "{{ item.0.name }}"        # 関連付けるワークフロージョブテンプレート名
      loop: "{{ workflow_templates | subelements('nodes') }}"
      loop_control:
        label: "{{ item.1.identifier }}"

Ansible Tower 3.6 までのエラー

3.6 までは、こんなエラーになっていました。(抜粋)

TASK [create workflow templates node] ******************************************
failed: [tower36] (item=node101) => {"ansible_loop_var": "item", "changed": false, "item": [{"allow_simultaneous": true, "desicription": "show command workflow", "extra_vars": {"wf_var1": "hello_wf1"}, "name": "wf_show", "nodes": [{"failure_nodes": ["node209"], "identifier": "node101", "success_nodes": ["node201", "node202"], "unified_job_template": "jt_show"}, {"identifier": "node201", "success_nodes": ["node301"], "unified_job_template": "jt_show"}, {"identifier": "node202", "success_nodes": ["node301"], "unified_job_template": "jt_show"}, {"identifier": "node209", "unified_job_template": "jt_show"}, {"all_parents_must_converge": true, "identifier": "node301", "unified_job_template": "jt_show"}], "survey": {"description": "", "name": "", "spec": [{"default": "new_username", "max": 1024, "min": 0, "question_description": "追加ユーザ名を入力してください", "question_name": "Enter new user name", "required": true, "type": "text", "variable": "new_username"}, {"default": "password", "max": 32, "min": 0, "question_description": "パスワードを入力してください", "question_name": "Enter new user password", "required": true, "type": "password", "variable": "new_password"}, {"choices": "operator\nadministrator", "default": "operator", "question_description": "役割を選択してください", "question_name": "Enter new user role", "required": true, "type": "multiplechoice", "variable": "new_role"}]}, "survey_enabled": true}, {"failure_nodes": ["node209"], "identifier": "node101", "success_nodes": ["node201", "node202"], "unified_job_template": "jt_show"}], "msg": "Got a 400 response when trying to get one from workflow_job_template_nodes, detail: WorkflowJobTemplateNode has no field named 'identifier'"}

おそらく、WorkflowJobTemplateNode has no field named 'identifier' がポイントで、3.6 には API 仕様としてまだこのキーがなかったということだと思います。

Ansible Tower 3.7.0 の場合(正常)

3.7.0 は以下のように正常に実行できました。

TASK [create workflow templates node] ********************************************************************
changed: [tower37] => (item=node101)
changed: [tower37] => (item=node201)
changed: [tower37] => (item=node202)
changed: [tower37] => (item=node209)
changed: [tower37] => (item=node301)

参考までに、作成されたワークフローを掲載します。(実際は、前述のタスクのあとにノード間のリンクを定義するタスクを実行済み)

f:id:akira6592:20200521213953p:plain
作成されたワークフロー

おわりに

Ansible Tower の設定を自動化できる箇所が増えてよかったです。

[Ansible] 特定バージョンの collection をインストールするには

基本コマンド

collection をインストールするコマンドは ansible-galaxy collection install です。

たとえば、cisco.ios であれば以下のとおりです。

ansible-galaxy collection install cisco.ios

この場合、最新の安定版リリースがインストールされます。

古いバージョンや、バージョン番号に dev がつくような開発版をインストールするにはバージョン指定が必要です。

cisco.ios を例にして、2つの方法をご紹介します。


■ 方法1: コマンドラインで バージョン指定する

手軽な方法です。

バージョン 0.0.1 をインストールする場合

ansible-galaxy collection install cisco.ios:0.0.1

開発バージョン 0.0.3-dev78 をインストールする場合

ansible-galaxy collection install cisco.ios:==0.0.3-dev78 


■ 方法2: requirements.yml でバージョン指定する

requirements.yml という定義ファイルに collection 名やバージョンを指定して読み込む方法です。

開発バージョン 0.0.3-dev78 をインストールする場合

  • requirements.yml
collections:
  - name: cisco.ios
    version: 0.0.3-dev78

コマンド

ansible-galaxy collection install -r requirements.yml


余談

雰囲気で pip コマンドのように cisco.ios==0.0.1 と指定してうまく行かず、調べました。 : が必要なのですね。

参考

docs.ansible.com

AWS 上の Cisco CSR1000V インスタンスにユーザーデータを指定する

はじめに

AWS で EC2 インスタンス起動時にスクリプト実行させるユーザーデータという機能があります。

サーバーが対象であれば、普通にスクリプトを書くようにコマンドを羅列すればよいわけですが、仮想ルーターなどの仮想アプライアンスの場合は、個別の指定方法があるようです。

ここでは、Cisco CSR1000V のインスタンス作成時にユーザーデータを指定する方法を試します。

インスタンス作成

Maketplace で Cisco CSR1000V を選択、インスタンスタイプを選択後「インスタンスの詳細の設定」をクリックします(確認と作成ではなく)。

f:id:akira6592:20200519172936p:plain
インスタンスタイプの選択

続いて「インスタンスの詳細の設定」画面の下の方のユーザーデータ欄にユーザーデータを入力します。

f:id:akira6592:20200519172958p:plain
ユーザーデータ入力欄

今回は、Cisco 公式ドキュメントの書き方に従って以下を入力します。

hostname="sakana"
ios-config-1="username operator privilege 1 password testpass99"
ios-config-2="username admin privilege 15 password testpass99"

ホスト名の設定と、コンフィグを2行指定しています。 デフォルトでは、ec2-user というユーザーのみなので、もう2つユーザーを追加します。

その後、通常通りインスタンス作成を進めます。

確認

とりえず、デフォルトの ec2-user でログインします。

$ ssh ec2-user@IPアドレス -i hogehoge.pem

sakana#

ユーザーデータで指定したとおり、ホスト名が sakana になりました。

一旦ログアウトして、追加したユーザーでもログインできるか確認します。

  • ユーザー: admin
$ ssh admin@IPアドレス
Password:   # 指定したパスワードを入力


sakana#
sakana#
sakana#exit
  • ユーザー: operator
$ ssh operator@IPアドレス
Password:   # 指定したパスワードを入力


sakana>
sakana>

無事にログインできました。

おわりに

この手の仮想アプライアンスはユーザーデータを指定できないと思っていたのですが、ちゃんと調べたやり方がありました。 調べてみるものですね。

www.cisco.com

[Ansible] 変数優先順位の「20. role (and include_role) params」とは何なのか

はじめに

Ansible は、様々な場所に変数を定義できます。便利な半面、優先順位がどうだったか混乱してしまうこともあります。 調べたいときに確認するのが、以下の公式ドキュメントのページです。

docs.ansible.com

この中で、20. role (and include_role) params という、割と強めな定義方法が何なのか分かりませんでした。

以下のブログにもあるように、同じように感じてるかがいらっしゃるようです。

zaki-hmkc.hatenablog.com

ちゃんと調べてみると、以下の記事が参考になりました。 qiita.com

---
- name: "test ansible var precedence"
  hosts: all
# ...(略)..
  roles:
    - role: test_role
      var_test20: "This is 'role (and include_role) params'"

このように、roles ディレクティブを利用した際に、role と同じレベル定義した変数のことのようです。

この記事では、一応自分でも検証してみます。


検証

優先順位をあらためて確認すると、20. role (and include_role) params19. set_facts / registered vars より強いようです。

19. set_facts / registered vars
20. role (and include_role) params
21. include params
22. extra vars (always win precedence)

なので、set_fact より優先されることをもって確認したいと思います。

ファイル構成

test.yml から testrole ロールを呼び出す構成です。

.
├── roles
│   └── testrole
│       └── tasks
│           └── main.yml
└── test.yml
  • test.yml
---
- hosts: localhost
  gather_facts: false

  roles:
    - role: testrole
      vars:
        msg: I'm in roles vars  # 似て非なる定義(どれだろう・・優先度は低め)
      msg: I'm in roles param   # これが 20. role (and include_role) params のはず
  • roles/testrole/tasks/main.yml
---
- name: set_fact
  set_fact: 
    msg: "I'm in tasks/main set_fact" # 19. set_facts / registered vars
    
- name: debug
  debug:
    msg: "{{ msg }}"

実行

Playbook を実行します。

$ ansible-playbook -i localhost, test.yml 

PLAY [localhost] *************************************************************************************************

TASK [testrole : set_fact] ***************************************************************************************
ok: [localhost]

TASK [testrole : debug] ******************************************************************************************
ok: [localhost] => {
    "msg": "I'm in roles param"
}

PLAY RECAP *******************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

I'm in roles param が表示されました。set_fact より優先されたことが分かりました。

補足

さすがに 22. extra vars (always win precedence) には負けます。

$ ansible-playbook -i localhost, test.yml -e msg="extra_vars"

PLAY [localhost] *****************************************************************************************************

TASK [testrole : set_fact] *******************************************************************************************
ok: [localhost]

TASK [testrole : debug] **********************************************************************************************
ok: [localhost] => {
    "msg": "extra_vars"
}

PLAY RECAP ***********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


おわりに

混乱のもとになるので、ある程度定義場所は制限したほうが良いと思います。

[Ansible/AWX] AWX コマンドで git プロジェクトを更新する

はじめに

先日以下のツイートを拝見しました。煩わしさ同感です。

その後、以下の記事が公開され、GitLab 側から AWX の API を叩く方法が紹介されていました。

https://nnstt1.hatenablog.com/entry/2020/05/17/224049

GitLab に Playbook を push すると、自動で AWS 側のプロジェクトが更新されるので、実施漏れもなく良いと思いました。

一方で「そこまで仕込む程でもないけど、とにかく画面上で操作するのが手間」というレベル感の場合のあるかと思います。

この記事では、awx コマンドでプロジェクトを更新する方法(awx project update プロジェクト名)を紹介します。


awx コマンドのインストールと設定

インストールや認証情報の設定などは以下の記事を参照してください。

tekunabe.hatenablog.jp


動作検証

実際に試してみます。

Playbook の追加

まずリポジトリ上(今回は GitHub)に新しく Playbook を追加します。

ここでは show2.yml とします。

f:id:akira6592:20200518082122p:plain
show2.yml の追加

この時点では、該当プロジェクトを使用するジョブテンプレートでは、show2.yml は選択できません。

f:id:akira6592:20200518082245p:plain
更新前なのでまだ show2.yml を選択できない

awx コマンドでプロジェクト更新

ここで、awx コマンドでプロジェクト更新します。

書式は、awx project update プロジェクト名 です。

今回の該当のプロジェクト名は pj_tower-sample-nw です。

$ awx project update pj_tower-sample-nw
{
     "project_update": 1239,
     "id": 1239,
     "type": "project_update",
     "url": "/api/v2/project_updates/1239/",
     "summary_fields": {
          "organization": {
               "id": 2,
               "name": "test_org",
               "description": "test organization"
          },
          "project": {
               "id": 13,
               "name": "pj_tower-sample-nw",
               "description": "tower-sample-nw",
               "status": "pending",
               "scm_type": "git"
          },
          "unified_job_template": {
               "id": 13,
               "name": "pj_tower-sample-nw",
               "description": "tower-sample-nw",
               "unified_job_type": "project_update"
          },
          "created_by": {
               "id": 1,
               "username": "admin",
               "first_name": "",
               "last_name": ""
          },
          "modified_by": {
               "id": 1,
               "username": "admin",
               "first_name": "",
               "last_name": ""
          },
          "user_capabilities": {
               "delete": true,
               "start": true
          }
     },
     "created": "2020-05-17T23:23:07.364032Z",
     "modified": "2020-05-17T23:23:07.400366Z",
     "name": "pj_tower-sample-nw",
     "description": "tower-sample-nw",
     "local_path": "_13__pj_tower_sample_nw",
     "scm_type": "git",
     "scm_url": "https://github.com/akira6592/tower-sample-nw.git",
     "scm_branch": "master",
     "scm_refspec": "",
     "scm_clean": true,
     "scm_delete_on_update": true,
     "credential": null,
     "timeout": 0,
     "scm_revision": "",
     "unified_job_template": 13,
     "launch_type": "manual",
     "status": "pending",
     "failed": false,
     "started": null,
     "finished": null,
     "canceled_on": null,
     "elapsed": 0.0,
     "job_args": "",
     "job_cwd": "",
     "job_env": {},
     "job_explanation": "",
     "execution_node": "",
     "result_traceback": "",
     "event_processing_finished": false,
     "project": 13,
     "job_type": "check",
     "job_tags": "update_git,delete"
}

なお、 -f human` オプションを追加すると、出力がすっきりします。

$ awx project update pj_tower-sample-nw -f human
id   name               
==== ================== 
1240 pj_tower-sample-nw 

確認

もう一度、該当プロジェクトを使用するジョブテンプレートを確認すると、show2.yml が選択できるようになりました。

f:id:akira6592:20200518082437p:plain
show2.yml が選択できるようになった


おわりに

Playbook の開発段階などでは、繰り返し発生する作業は、GUI よりコマンドのほうが便利かと思います。

curlAPI 叩くのでもよいかもしれませんが、API だと対象オブジェクト(プロジェクトなど)を內部で管理している id で指定する必要があります。awx コマンドでは名前で指定できるので便利です。