質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.37%

Ansibleで'dict object' has no attribute でgroup_varsの変数が利用できない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 7,103

tkkk

score 7

Ansible: ver2.1.0.0
ローカルからリモートサーバー上(さくらVPS)に対してAnsibleを使って環境構築の自動化をしようとしています。
すでに同じサーバー上にAnsibleを使ってNginxの構築は成功していますが、今回のpostgresqlのインストールを目的とした構築がうまくいきません。Nginxのときとの違いは、今回はgroup_varsの変数を利用して構築しようとしています。
現在、以下の構成で試していますが、うまくいきません。

ディレクトリ構成

├── group_vars
│   ├── all.yml
│   └── production
│       ├── all.yml
│       ├── secret.yml
│       ├── dbservers.yml
│       └── webserves.yml
├── hosts
│   └── production
│       └── production
├── roles
│   └── postgresql
│       └── tasks
│           └── main.yml
│   ├── ruby
│   └── nginx
│
├── dbserves.yml
├── webservers.yml
└── site.yml

主なソースコード

site.yml

---
- include: webservers.yml
- include: dbservers.yml

dbservers.yml

---
- hosts: dbservers
  roles:
    - postgresql

roles/postgresql/tasks/main.yml

---
- name: rpm install postgresql repos
  become: true
  yum:
    name: "{{ pg.rpm_url }}"

- name: install postgresql
  become: true
  yum:
    name: "{{ item }}"
    state: latest
  with_items:
    - "{{ pg.package_name }}-server"
    - "{{ pg.package_name }}-devel"
    - "{{ pg.package_name }}-contrib"
    - "{{ pg.package_name }}-libs"
    - python-psycopg2

- name: postgresql initdb
  become: true
  shell: "service postgresql-{{ pg.version }} initdb"

- name: start postgresql
  become: true
  service:
    name: "postgresql-{{ pg.version }}"
    state: started
    enabled: true

- name : create database
  postgresql_db:
    name: "{{ pg.dbname }}"
    login_user: postgres
  sudo_user: postgres
  sudo: true

- name: create user
  postgresql_user:
    db: "{{ pg.dbname }}"
    name: "{{ pg.dbuser }}"
    password: "{{ pg.dbpassword }}"
    priv: ALL
    state: present
    login_user: postgres
  sudo_user: postgres
  sudo: true

hosts/production/production

[ishikari-webservers]
target-host ansible_host=(IPを記入) ansible_port=21122 ansible_user=system_user ansible_ssh_private_key_file=/Users/admin/.ssh/sakura_git

[ishikari-dbservers]
target-host ansible_host=(IPを記入) ansible_port=21122 ansible_user=system_user ansible_ssh_private_key_file=/Users/admin/.ssh/sakura_git

[webservers:children]
ishikari-webservers

[dbservers:children]
ishikari-dbservers

[production:children]
webservers
dbservers

group_vars/production/dbservers.yml

---
pg:
  rpm_url: "http://yum.postgresql.org/9.5/redhat/rhel-7.1-x86_64/pgdg-centos95-9.5-1.noarch.rpm"
  version: 9.5
  package_name: postgresql95
  dbname: app_production
  dbuser: db_user
  # dbpasswordはgroup_vars/production/secret.yml ここには書かない

group_vars/production/secret.yml

---
pg:
  dbpassword: password

実行コマンド

ansible-playbook -i ansible/hosts/production ansible/dbservers.yml --vault-password-file ~/.vault_password

エラーメッセージ

TASK [postgresql : rpm install postgresql repos] *******************************
fatal: [target-host]: FAILED! => {"failed": true, "msg": "'dict object' has no attribute 'rpm_url'"}

rpm_urlなどのgroup_varsから読み込みたい変数がうまく読み込めません。
試しに、group_vars/production/dbservers.ymlの内容をまるまる roles/postgresql/vars/main.ymlとして実行するとdbpasswordの部分は直書きになってしまいますが、構築に成功します。

group_varsの変数の利用でなんとか解決できないでしょうか。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

シンプルな環境で試してみたのですが、単純にgroup_varsのグループフォルダに
複数の変数入りYAMLを置くだと変数ごと上書きされるみたいです。

自環境で試した感じではdbserver.ymlのインクルード後にsecret.ymlのインクルードが走り、
結果としてpg変数はsecret.ymlの中身のみになっていました。

Playbookと同じフォルダか、実行時のディレクリにansible.cfgを用意して、

[defaults]
hash_behaviour = merge

と書くとdict型の変数を複数のvars系ファイルをインクルードする際に、全体を上書きするのではなく
dictのキー単位でマージしてくれるみたいです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/08/21 09:29

    分かりやすい回答ありがとうございます。回答の内容で解決することができました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る