天天看點

ansible 用變量簡單渲染nginx配置檔案allow set_fact action plugin to work with loops 

我發現還是salt好,ansible封裝的,好多不會。還不如直接寫py來的幹脆。

技術點

ConfigParser

with_dict: iplist

{% for key in item.value  %}

` key ` weight=1;

{% endfor %}

實作效果

多主機域名,生成對應的域名檔案,自動放入nginx中

<code>最終版本</code>

<code>cat books.txt</code>

<code>a </code><code>172.1</code><code>.</code><code>1.211</code> <code>ceshi </code><code>8015</code> <code>8089</code> <code>a</code>

<code>a </code><code>172.1</code><code>.</code><code>1.210</code> <code>ceshi </code><code>8015</code> <code>8089</code> <code>a</code>

<code>b </code><code>172.1</code><code>.</code><code>1.210</code> <code>ceshi </code><code>8015</code> <code>8089</code> <code>b</code>

<code>python nginx.py</code>

<code>#!/usr/bin/env python</code>

<code># -*- coding: utf-8 -*-</code>

<code>import</code> <code>ConfigParser</code>

<code>import</code> <code>string, os, sys</code>

<code>def</code> <code>ynameconf():</code>

<code>    </code><code>sfile </code><code>=</code> <code>'books.txt'</code>

<code>    </code><code>inventory </code><code>=</code> <code>{}</code>

<code>    </code><code>with </code><code>open</code><code>(sfile, </code><code>'rb'</code><code>) as f:</code>

<code>        </code><code>for</code> <code>i </code><code>in</code> <code>f.readlines():</code>

<code>            </code><code>ip </code><code>=</code> <code>i.strip().split()[</code><code>1</code><code>]</code>

<code>            </code><code>yname </code><code>=</code> <code>i.strip().split()[</code><code>5</code><code>]  </code><code># 域名</code>

<code>            </code><code>if</code> <code>not</code> <code>yname </code><code>in</code> <code>inventory:</code>

<code>                </code><code>inventory[yname] </code><code>=</code> <code>[]</code>

<code>            </code><code>port</code><code>=</code> <code>i.strip().split()[</code><code>4</code><code>]</code>

<code>            </code><code>ipport</code><code>=</code><code>ip</code><code>+</code><code>":"</code><code>+</code><code>port</code>

<code>            </code><code>inventory[yname].append(ipport)</code>

<code>    </code><code>return</code> <code>inventory</code>

<code>def</code> <code>ynameParser():</code>

<code>    </code><code>cf </code><code>=</code> <code>ConfigParser.ConfigParser()</code>

<code>    </code><code>ynameyname</code><code>=</code><code>ynameconf()</code>

<code>    </code><code>print</code> <code>ynameyname</code>

<code>    </code><code>for</code> <code>k,v </code><code>in</code> <code>ynameyname.iteritems():</code>

<code>        </code><code>general</code><code>=</code><code>k</code>

<code>        </code><code>cf.add_section(general)</code>

<code>        </code><code>cf.</code><code>set</code><code>(general, </code><code>"pro_dir"</code><code>, k)</code>

<code>        </code><code>for</code> <code>i </code><code>in</code> <code>range</code><code>(</code><code>len</code><code>(v)):</code>

<code>            </code><code>ips</code><code>=</code><code>"ip"</code><code>+</code><code>str</code><code>(i</code><code>+</code><code>1</code><code>)</code>

<code>            </code><code>cf.</code><code>set</code><code>(general,ips, v[i])</code>

<code>        </code><code># cf.set(k, ','.join(v))</code>

<code>        </code><code>cf.write(</code><code>open</code><code>(</code><code>"vhost.fact"</code><code>, </code><code>"w"</code><code>))</code>

<code>ynameP</code><code>=</code><code>ynameParser()</code>

<code>cat </code><code>/</code><code>etc</code><code>/</code><code>foo.txt</code>

<code>{</code><code>'a'</code><code>: [</code><code>'172.1.1.211:8089'</code><code>, </code><code>'172.1.1.210:8089'</code><code>], </code><code>'b'</code><code>: [</code><code>'172.1.1.210:8089'</code><code>]}</code>

<code>-</code> <code>hosts: ot5</code>

<code>  </code><code>remote_user: root</code>

<code>  </code><code>gather_facts: no</code>

<code>  </code><code>vars</code><code>:</code>

<code>    </code><code>ipall: {</code><code>'api'</code><code>:[</code><code>'172.1.1.2'</code><code>],</code><code>'api3'</code><code>:[</code><code>'172.29.1.1'</code><code>]}</code>

<code>  </code><code>-</code> <code>name: get</code>

<code>    </code><code>set_fact: </code>

<code>      </code><code>iplist: </code><code>"{{ lookup('file', '/etc/foo.txt') }}"</code>

<code>  </code><code>tasks:</code>

<code>  </code><code>-</code> <code>name: copy</code>

<code>    </code><code>template: dest</code><code>=</code><code>/</code><code>tmp</code><code>/</code><code>`item`.`key`.conf src</code><code>=</code><code>/</code><code>etc</code><code>/</code><code>ansible</code><code>/</code><code>named.conf.j2</code>

<code>    </code><code>with_dict: iplist</code>

<code>.</code><code>/</code><code>set</code>

<code>upstream {{ item.key }} {</code>

<code>    </code><code>{</code><code>%</code> <code>for</code> <code>key </code><code>in</code> <code>item.value  </code><code>%</code><code>}</code>

<code>    </code><code>{{ key }} weight</code><code>=</code><code>1</code><code>;</code>

<code>    </code><code>{</code><code>%</code> <code>endfor </code><code>%</code><code>}</code>

<code>     </code> 

<code>    </code><code>check interval</code><code>=</code><code>2000</code> <code>rise</code><code>=</code><code>2</code> <code>fall</code><code>=</code><code>2</code> <code>timeout</code><code>=</code><code>1000</code> <code>type</code><code>=</code><code>http;</code>

<code>    </code><code>check_http_send </code><code>"GET /  HTTP/1.0\r\n\r\n"</code><code>;</code>

<code>    </code><code>check_http_expect_alive http_2xx http_3xx;</code>

<code>}</code>

<code>-</code><code>-</code><code>-</code>

<code>.</code><code>/</code><code>conf</code>

<code>server {</code>

<code>        </code><code>listen  </code><code>80</code><code>;</code>

<code>        </code><code>server_name     `item`.`key`.com;</code>

<code>       </code><code>location </code><code>/</code> <code>{</code>

<code>      </code><code>proxy_next_upstream http_500 http_502 http_503 http_504 error timeout invalid_header;</code>

<code>      </code><code>proxy_pass http:</code><code>/</code><code>/</code><code>`item`.`key`;</code>

做的很垃圾

<code>&lt;span style</code><code>=</code><code>"text-decoration:line-through;"</code><code>&gt;</code><code>1.</code><code>首先在ansible上形成vhost.fact&lt;br&gt;cat books.txt&lt;br&gt;w ip1 dev </code><code>8021</code> <code>8688</code> <code>api&lt;br&gt;w ip2 dev </code><code>8021</code> <code>8688</code> <code>api&lt;br&gt;&lt;br&gt;w是tomcat應用名稱,api是域名名稱&lt;br&gt;&lt;br&gt;&lt;br&gt;nginx.py&lt;br&gt;</code><code>#!/usr/bin/env python&lt;br&gt;# -*- coding: utf-8 -*-&lt;br&gt;import ConfigParser&lt;br&gt;import string, os, sys&lt;br&gt;&lt;br&gt;def ynameconf():&lt;br&gt;    sfile = 'books.txt'&lt;br&gt;    inventory = {}&lt;br&gt;    with open(sfile, 'rb') as f:&lt;br&gt;        for i in f.readlines():&lt;br&gt;            ip = i.strip().split()[1]&lt;br&gt;            yname = i.strip().split()[5]  # 域名&lt;br&gt;            if not yname in inventory:&lt;br&gt;                inventory[yname] = []&lt;br&gt;            inventory[yname].append(ip)&lt;br&gt;    return inventory&lt;br&gt;&lt;br&gt;def ynameParser():&lt;br&gt;    cf = ConfigParser.ConfigParser()&lt;br&gt;    ynameyname=ynameconf()&lt;br&gt;    for k,v in ynameyname.iteritems():&lt;br&gt;        cf.add_section('general')&lt;br&gt;        cf.set("general", "pro_dir", k)&lt;br&gt;        cf.set("general", "ip1", v[0])&lt;br&gt;        cf.set("general", "ip2", v[1])&lt;br&gt;        # cf.set(k, ','.join(v))&lt;br&gt;        cf.write(open("vhost.fact", "w"))&lt;br&gt;&lt;br&gt;ynameP=ynameParser()&lt;br&gt;&lt;br&gt;生成的vhost.fact的樣子&lt;br&gt;[general]&lt;br&gt;pro_dir = api&lt;br&gt;ip1 = ip1&lt;br&gt;ip2 = ip2&lt;br&gt;&lt;br&gt;還有很多問題&lt;br&gt;1.假如有三台以上機器怎麼處理&lt;br&gt;2.多個域名怎麼同時處理,搞到我想到了協程&lt;br&gt;&lt;br&gt;2.寫yml檔案,就幾行&lt;br&gt;&lt;br&gt;mkdir -p /etc/ansible/nginx&lt;br&gt;&lt;br&gt;├── hosts&lt;br&gt;├── roles&lt;br&gt;│   └── vhost&lt;br&gt;│       ├── default&lt;br&gt;│       ├── files&lt;br&gt;│       ├── handlers&lt;br&gt;│       │   └── main.yml&lt;br&gt;│       ├── meta&lt;br&gt;│       ├── tasks&lt;br&gt;│       │   ├── install.yml&lt;br&gt;│       │   └── main.yml&lt;br&gt;│       ├── templates&lt;br&gt;│       │   ├── set.conf&lt;br&gt;│       │   └── vhost.conf&lt;br&gt;│       └── vars&lt;br&gt;└── vhost.yml&lt;br&gt;&lt;br&gt;主要tasks/install.yml&lt;br&gt;- name: mkdir&lt;br&gt;  shell: mkdir -p /etc/ansible/facts.d&lt;br&gt;- name: copy vhost.fact&lt;br&gt;  copy: src=/etc/ansible/vhost.fact dest=/etc/ansible/facts.d/vhost.fact &lt;br&gt;- name: flush&lt;br&gt;  setup: &lt;br&gt;- name: copy&lt;br&gt;  template: src=set.conf dest=/usr/local/tengine/conf/SET/{{ ansible_local.vhost.general.pro_dir }}.conf&lt;br&gt;- name: copy&lt;br&gt;  template: src=vhost.conf dest=/usr/local/tengine/conf/conf.d/{{ ansible_local.vhost.general.pro_dir }}.conf&lt;br&gt;&lt;br&gt;3.手動執行指令&lt;br&gt;#nginx域名渲染&lt;br&gt;cd /etc/ansible &amp;&amp; python nginx.py&lt;br&gt;cd /etc/ansible/nginx/&lt;br&gt;#'host=nginx' 這個是nginx伺服器名稱&lt;br&gt;ansible-playbook -i /etc/ansible/hosts vhost.yml --extra-vars 'host=nginx'&lt;br&gt;ansible -i /etc/ansible/hosts nginx -m shell -a '/usr/local/tengine/sbin/nginx -c /usr/local/tengine/conf/nginx.conf -t' &lt;br&gt;ansible -i /etc/ansible/hosts nginx -m shell -a '/usr/local/tengine/sbin/nginx -c /usr/local/tengine/conf/nginx.conf -s reload'&lt;br&gt;&lt;br&gt;達到的效果,利用ansible使兩台機器立刻部署完tomcat後,然後加入到nginx中。&lt;br&gt;土。&lt;br&gt;&lt;/span&gt;</code>

<code>&lt;span style</code><code>=</code><code>"text-decoration:line-through;"</code><code>&gt;[root@localhost ansible]</code><code># cat test3.yml&lt;br&gt;- hosts: ot3&lt;br&gt;  remote_user: root&lt;br&gt;  gather_facts: no&lt;br&gt;  vars:&lt;br&gt;    ip: ['172.1.1.2']&lt;br&gt;  tasks:&lt;br&gt;  - name: get&lt;br&gt;    set_fact: &lt;br&gt;      iplist: "{{ lookup('file', '/etc/foo.txt') }}"&lt;br&gt;  - name: oup put the myjson of first&lt;br&gt;    debug: var="{{ iplist }}"&lt;br&gt;  - name: copy&lt;br&gt;    template: dest=/tmp/named.conf src=/etc/ansible/named.conf.j2&lt;br&gt;&lt;/span&gt;</code>

[root@localhost ansible]# cat named.conf.j2

`iplist`

{% for key in iplist %}

dict

- hosts: ot5

  remote_user: root

  gather_facts: no

  vars:

    ipall: {'api':['172.1.1.2'],'api3':['172.29.1.1']}

  tasks:

  - name: copy

    template: dest=/tmp/`item`.`key`.conf src=/etc/ansible/named.conf.j2

    with_dict: "` ipall `"

cat /etc/ansible/named.conf.j2

`item`.`key`

這樣就會生成多個conf檔案。

最後一個例子

<code>&lt;span style</code><code>=</code><code>"text-decoration:line-through;"</code><code>&gt;</code><code>-</code><code>-</code><code>-</code><code>&lt;br&gt;</code><code>-</code> <code>hosts: localhost&lt;br&gt;  gather_facts: false&lt;br&gt;  </code><code>vars</code><code>:&lt;br&gt;    users:&lt;br&gt;      </code><code>-</code> <code>name: paul&lt;br&gt;        uid: </code><code>1</code><code>&lt;br&gt;        hosts:&lt;br&gt;          </code><code>-</code> <code>host: apple&lt;br&gt;          </code><code>-</code> <code>host: berry&lt;br&gt;      </code><code>-</code> <code>name: pete&lt;br&gt;        uid: </code><code>2</code><code>&lt;br&gt;        hosts:&lt;br&gt;          </code><code>-</code> <code>host: banana&lt;br&gt;          </code><code>-</code> <code>host: pear&lt;br&gt;          </code><code>-</code> <code>host: kiwi&lt;br&gt;  tasks:&lt;br&gt;    </code><code>-</code> <code>set_fact:&lt;br&gt;      args:&lt;br&gt;        userslist:&lt;br&gt;          name: </code><code>'{{ item.0.name }}'</code><code>&lt;br&gt;          uid:  </code><code>'{{ item.0.uid }}'</code><code>&lt;br&gt;          host: </code><code>'{{ item.1.host }}'</code><code>&lt;br&gt;      with_subelements: &lt;br&gt;        </code><code>-</code> <code>users&lt;br&gt;        </code><code>-</code> <code>hosts&lt;br&gt;        &lt;br&gt;        &lt;br&gt;        &lt;br&gt;The original result </code><code>for</code> <code>the </code><code>set</code> <code>fact would be&lt;br&gt;    </code><code>"userslist"</code><code>: {&lt;br&gt;        </code><code>"host"</code><code>: </code><code>"kiwi"</code><code>, &lt;br&gt;        </code><code>"name"</code><code>: </code><code>"pete"</code><code>, &lt;br&gt;        </code><code>"uid"</code><code>: </code><code>"2"</code><code>&lt;br&gt;    }&lt;br&gt;With this patch, one gets:&lt;br&gt;    </code><code>"userslist"</code><code>: [&lt;br&gt;        {&lt;br&gt;            </code><code>"host"</code><code>: </code><code>"apple"</code><code>, &lt;br&gt;            </code><code>"name"</code><code>: </code><code>"paul"</code><code>, &lt;br&gt;            </code><code>"uid"</code><code>: </code><code>"1"</code><code>&lt;br&gt;        }, &lt;br&gt;        {&lt;br&gt;            </code><code>"host"</code><code>: </code><code>"berry"</code><code>, &lt;br&gt;            </code><code>"name"</code><code>: </code><code>"paul"</code><code>, &lt;br&gt;            </code><code>"uid"</code><code>: </code><code>"1"</code><code>&lt;br&gt;        }, &lt;br&gt;        {&lt;br&gt;            </code><code>"host"</code><code>: </code><code>"banana"</code><code>, &lt;br&gt;            </code><code>"name"</code><code>: </code><code>"pete"</code><code>, &lt;br&gt;            </code><code>"uid"</code><code>: </code><code>"2"</code><code>&lt;br&gt;        }, &lt;br&gt;        {&lt;br&gt;            </code><code>"host"</code><code>: </code><code>"pear"</code><code>, &lt;br&gt;            </code><code>"name"</code><code>: </code><code>"pete"</code><code>, &lt;br&gt;            </code><code>"uid"</code><code>: </code><code>"2"</code><code>&lt;br&gt;        }, &lt;br&gt;        {&lt;br&gt;            </code><code>"host"</code><code>: </code><code>"kiwi"</code><code>, &lt;br&gt;            </code><code>"name"</code><code>: </code><code>"pete"</code><code>, &lt;br&gt;            </code><code>"uid"</code><code>: </code><code>"2"</code><code>&lt;br&gt;        }&lt;br&gt;    ]&lt;br&gt;    &lt;br&gt; https:</code><code>/</code><code>/</code><code>github.com</code><code>/</code><code>ansible</code><code>/</code><code>ansible</code><code>/</code><code>pull</code><code>/</code><code>8019</code><code>&lt;br&gt;&lt;</code><code>/</code><code>span&gt;</code>

本文轉自 liqius 51CTO部落格,原文連結:http://blog.51cto.com/szgb17/1947640,如需轉載請自行聯系原作者

繼續閱讀