【Ansible】初心者が Syntax Error while loading YAML.、did not find expectedで嵌った場合と対処法

スポンサーリンク
Ansible
スポンサーリンク

Ansibleで試しにplaybook実行したらSyntax Errorが起きた

私はインフラ基盤を担当しているくせにAnsibleをちゃんと自分で設定して動かしたことがない。
これはイカンと作った下記検証環境にAnsibleをインストールしてplaybookを見様見真似で書いたところ、以下のエラーが発生した。

[root@TEST-01 ansible]# ansible-playbook -i ./hosts test-ansible2.yml --syntax-check
 [WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
 ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
 JSON: No JSON object could be decoded
 Syntax Error while loading YAML.
   did not find expected '-' indicator
 The error appears to be in '/etc/ansible/test-ansible2.yml': line 4, column 1, but may
 be elsewhere in the file depending on the exact syntax problem.
 The offending line appears to be:
 connection: local
 tasks:
 ^ here

※hostsファイルの記載(追記した内容)は末尾に以下のみ
 [test-local]
 localhost
※playbookの名前はtest-ansible2.yml
※環境はCentOS7、ansible-2.9.17-1.el7.noarchを利用

原因と対処法

結論

今回の私の場合は、であるがplaybookとなるYAMLの記述お作法をよくわかっておらず、適切にインデントを記載出来ていないことが原因だった。

今回私が用意したplaybookは以下の通り。
apacheとtomcatとインストールし、プロセスを起動し自動起動をオンにする、という内容である。
アカンplaybookなので真似なさらないように

---
- hosts: test-local
  connection: local
tasks:
- name: install httpd
yum:
name: httpd
state: latest

- name: run httpd
service:
name: httpd
state: started
enabled: yes

- name: install tomcat
yum:
name: tomcat
state: latest

- name: run tomcat
service:
name: tomcat
state: started
enabled: yes

詳しい方が見ればすぐわかると思うが・・・YAMLは構造をインデント(半角スペース)で表現する
つまり正しい記載はこうなる。

---
- hosts: test-local
  connection: local
  tasks:
    - name: install httpd
      yum:
        name: httpd
        state: latest

    - name: run httpd
      service:
        name: httpd
        state: started
        enabled: yes

    - name: install tomcat
      yum:
        name: tomcat
        state: latest

    - name: run tomcat
      service:
        name: tomcat
        state: started
        enabled: yes

解説

playbook上、

  1. 指定したホストグループに対して(ターゲットディレクティブ)
  2. 指定したタスク郡を実行する(タスクディレクティブ)
  3. 各タスクは個別にモジュールなど実行内容を規定していく

という流れ(構造)になっており、固まり(ディレクティブ)毎にインデント(字下げ)を行う
インデントは半角スペース2つで行う。

アカン例では、tasks以降全くインデントを行っていなかったのでSyntax Errorとなった。

余談。ERROR! conflicting action statements: state, yumも出た

原因と対処法で記載した修正playbookは最終的に問題ない形にしたものだが、試行錯誤途中で以下のエラーも出た。

[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 5, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 10, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 16, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 21, column 5, found a duplicate dict key (name). Using last defined value only.
ERROR! conflicting action statements: state, yum

The error appears to be in '/etc/ansible/test-ansible2.yml': line 5, column 5, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  tasks:
  - name: install httpd
    ^ here

「ERROR! conflicting action statements: state, yum」となっている。
また、「duplicate dict key (name)」ということで、nameが重複しているらしい。
このエラーが出たplaybookは以下である。

---
- hosts: test-local
  connection: local
  tasks:
  - name: install httpd
    yum:
    name: httpd       ★ダメなところ
    state: latest      ★ダメなところ

  - name: run httpd
    service:
    name: httpd       ★ダメなところ
    state: started      ★ダメなところ
    enabled: yes       ★ダメなところ

  - name: install tomcat
    yum:
    name: tomcat       ★ダメなところ
    state: latest       ★ダメなところ

  - name: run tomcat
    service:
    name: tomcat       ★ダメなところ
    state: started      ★ダメなところ
    enabled: yes       ★ダメなところ

見れば分かる通り、tasksの中でyum/service以下のインデントが正しくない
エラーとなっているyum/serviceはそれぞれの処理内容(name、state,enabled)をインデントしないといけない。
そのため、前述の修正Playbookの内容となる。

最後に、そもそもAnsibleでplaybook実行前に確認すべきと思われること

ansibleでplaybookを実行する際に、今回のような構文エラーはよくあることだと思う。
playbookの構文チェックは以下のように行うことができる。

--syntax-checkを使って構文チェックを行う

今回私が実施したコマンドについているオプション「--syntax-check」はplaybookの文法が正しいかどうかを確認する。基本的に新規作成したplaybookではこれを事前に行うことが必要だと思う。

-vvvvを使って詳細ログを出力させる

上の構文チェックオプションに加えて、-vオプションを併用することによってさらに詳細ログが表示される。
この-vはvの数を増やすことによってより詳細になっていく(v~vvvvまでレベルが4段階ある)

例えば、余談で書いたplaybookで-vオプションをつけていくと以下のように変化していく。
※青字部分が-vで増える箇所

-v(v一個の場合)
コンフィグファイルは/etc/ansible/ansible.cfgだよ、という注記が出てくる

[root@TEST-01 ansible]# ansible-playbook -i ./hosts test-ansible2.yml --syntax-check -v
Using /etc/ansible/ansible.cfg as config file
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 5, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 10, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 16, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 21, column 5, found a duplicate dict key (name). Using last defined value only.
ERROR! conflicting action statements: state, yum

The error appears to be in '/etc/ansible/test-ansible2.yml': line 5, column 5, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  tasks:
  - name: install httpd
    ^ here

-vv(v二個の場合)
動作しているansibleのバージョン、コンフィグ、モジュールなどの情報が出てくる

[root@TEST-01 ansible]# ansible-playbook -i ./hosts test-ansible2.yml --syntax-check -vv
ansible-playbook 2.9.17
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 2.7.5 (default, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
Using /etc/ansible/ansible.cfg as config file
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 5, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 10, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 16, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 21, column 5, found a duplicate dict key (name). Using last defined value only.
ERROR! conflicting action statements: state, yum

The error appears to be in '/etc/ansible/test-ansible2.yml': line 5, column 5, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  tasks:
  - name: install httpd
    ^ here

-vvv(v三個の場合)
このへんになってくると自身で用意したhostsファイルのダメなところなどを指摘してくれる。

[root@TEST-01 ansible]# ansible-playbook -i ./hosts test-ansible2.yml --syntax-check -vvv
ansible-playbook 2.9.17
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 2.7.5 (default, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
Using /etc/ansible/ansible.cfg as config file
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
Parsed /etc/ansible/hosts inventory source with ini plugin
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 5, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 10, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 16, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 21, column 5, found a duplicate dict key (name). Using last defined value only.
ERROR! conflicting action statements: state, yum

The error appears to be in '/etc/ansible/test-ansible2.yml': line 5, column 5, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  tasks:
  - name: install httpd
    ^ here

-vvvv(v四個の場合)
最大レベルになるとより詳細に処理注記が表示される。

[root@TEST-01 ansible]# ansible-playbook -i ./hosts test-ansible2.yml --syntax-check -vvvv
ansible-playbook 2.9.17
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 2.7.5 (default, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
Using /etc/ansible/ansible.cfg as config file
setting up inventory plugins
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Not replacing invalid character(s) "set([u'-'])" in group name (test-local)
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
Not replacing invalid character(s) "set([u'-'])" in group name (test-local)
Parsed /etc/ansible/hosts inventory source with ini plugin
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 5, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 10, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 16, column 5, found a duplicate dict key (name). Using last defined value only.
[WARNING]: While constructing a mapping from /etc/ansible/test-ansible2.yml, line 21, column 5, found a duplicate dict key (name). Using last defined value only.
ERROR! conflicting action statements: state, yum

The error appears to be in '/etc/ansible/test-ansible2.yml': line 5, column 5, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  tasks:
  - name: install httpd
    ^ here

以上!

コメント

タイトルとURLをコピーしました