您的位置:首页 > 运维架构 > Nginx

ansible 用变量简单渲染nginx配置文件

2017-07-14 17:34 447 查看
我发现还是salt好,ansible封装的,好多不会。还不如直接写py来的干脆。

技术点
ConfigParser
with_dict: iplist
{% for key in item.value %}
` key ` weight=1;
{% endfor %}

实现效果
多主机域名,生成对应的域名文件,自动放入nginx中

最终版本
cat books.txt
a 172.1.1.211 ceshi 8015 8089 a
a 172.1.1.210 ceshi 8015 8089 a
b 172.1.1.210 ceshi 8015 8089 b

python nginx.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import ConfigParser
import string, os, sys

def ynameconf():
sfile = 'books.txt'
inventory = {}
with open(sfile, 'rb') as f:
for i in f.readlines():
ip = i.strip().split()[1]
yname = i.strip().split()[5]  # 域名
if not yname in inventory:
inventory[yname] = []
port= i.strip().split()[4]
ipport=ip+":"+port
inventory[yname].append(ipport)
return inventory

def ynameParser():
cf = ConfigParser.ConfigParser()
ynameyname=ynameconf()
print ynameyname
for k,v in ynameyname.iteritems():
general=k
cf.add_section(general)
cf.set(general, "pro_dir", k)
for i in range(len(v)):
ips="ip"+str(i+1)
cf.set(general,ips, v[i])
# cf.set(k, ','.join(v))
cf.write(open("vhost.fact", "w"))

ynameP=ynameParser()

cat /etc/foo.txt
{'a': ['172.1.1.211:8089', '172.1.1.210:8089'], 'b': ['172.1.1.210:8089']}

- hosts: ot5
remote_user: root
gather_facts: no
vars:
ipall: {'api':['172.1.1.2'],'api3':['172.29.1.1']}
- name: get
set_fact:
iplist: "{{ lookup('file', '/etc/foo.txt') }}"
tasks:
- name: copy
template: dest=/tmp/`item`.`key`.conf src=/etc/ansible/named.conf.j2
with_dict: iplist

./set
upstream {{ item.key }} {
{% for key in item.value  %}
{{ key }} weight=1;
{% endfor %}

check interval=2000 rise=2 fall=2 timeout=1000 type=http;
check_http_send "GET /  HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}

---

./conf
server {
listen  80;
server_name     `item`.`key`.com;
location / {
proxy_next_upstream http_500 http_502 http_503 http_504 error timeout invalid_header;
proxy_pass http://`item`.`key`; }
}


做的很垃圾
1.首先在ansible上形成vhost.fact
cat books.txt
w ip1 dev 8021 8688 api
w ip2 dev 8021 8688 api

w是tomcat应用名称,api是域名名称

nginx.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import ConfigParser
import string, os, sys

def ynameconf():
sfile = 'books.txt'
inventory = {}
with open(sfile, 'rb') as f:
for i in f.readlines():
ip = i.strip().split()[1]
yname = i.strip().split()[5]  # 域名
if not yname in inventory:
inventory[yname] = []
inventory[yname].append(ip)
return inventory

def ynameParser():
cf = ConfigParser.ConfigParser()
ynameyname=ynameconf()
for k,v in ynameyname.iteritems():
cf.add_section('general')
cf.set("general", "pro_dir", k)
cf.set("general", "ip1", v[0])
cf.set("general", "ip2", v[1])
# cf.set(k, ','.join(v))
cf.write(open("vhost.fact", "w"))

ynameP=ynameParser()

生成的vhost.fact的样子
[general]
pro_dir = api
ip1 = ip1
ip2 = ip2

还有很多问题
1.假如有三台以上机器怎么处理
2.多个域名怎么同时处理,搞到我想到了协程

2.写yml文件,就几行

mkdir -p /etc/ansible/nginx

├── hosts
├── roles
│   └── vhost
│       ├── default
│       ├── files
│       ├── handlers
│       │   └── main.yml
│       ├── meta
│       ├── tasks
│       │   ├── install.yml
│       │   └── main.yml
│       ├── templates
│       │   ├── set.conf
│       │   └── vhost.conf
│       └── vars
└── vhost.yml

主要tasks/install.yml
- name: mkdir
shell: mkdir -p /etc/ansible/facts.d
- name: copy vhost.fact
copy: src=/etc/ansible/vhost.fact dest=/etc/ansible/facts.d/vhost.fact
- name: flush
setup:
- name: copy
template: src=set.conf dest=/usr/local/tengine/conf/SET/{{ ansible_local.vhost.general.pro_dir }}.conf
- name: copy
template: src=vhost.conf dest=/usr/local/tengine/conf/conf.d/{{ ansible_local.vhost.general.pro_dir }}.conf

3.手动执行命令
#nginx域名渲染
cd /etc/ansible && python nginx.py
cd /etc/ansible/nginx/
#'host=nginx' 这个是nginx服务器名称
ansible-playbook -i /etc/ansible/hosts vhost.yml --extra-vars 'host=nginx'
ansible -i /etc/ansible/hosts nginx -m shell -a '/usr/local/tengine/sbin/nginx -c /usr/local/tengine/conf/nginx.conf -t'
ansible -i /etc/ansible/hosts nginx -m shell -a '/usr/local/tengine/sbin/nginx -c /usr/local/tengine/conf/nginx.conf -s reload'

达到的效果,利用ansible使两台机器立刻部署完tomcat后,然后加入到nginx中。
土。
[root@localhost ansible]# cat test3.yml
- hosts: ot3
remote_user: root
gather_facts: no
vars:
ip: ['172.1.1.2']
tasks:
- name: get
set_fact:
iplist: "{{ lookup('file', '/etc/foo.txt') }}"
- name: oup put the myjson of first
debug: var="{{ iplist }}"
- name: copy
template: dest=/tmp/named.conf src=/etc/ansible/named.conf.j2


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

{% for key in iplist %}
` key ` weight=1;
{% endfor %}

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`
{% for key in item.value %}
` key ` weight=1;
{% endfor %}

这样就会生成多个conf文件。

最后一个例子
---
- hosts: localhost
gather_facts: false
vars:
users:
- name: paul
uid: 1
hosts:
- host: apple
- host: berry
- name: pete
uid: 2
hosts:
- host: banana
- host: pear
- host: kiwi
tasks:
- set_fact:
args:
userslist:
name: '{{ item.0.name }}'
uid:  '{{ item.0.uid }}'
host: '{{ item.1.host }}'
with_subelements:
- users
- hosts

The original result for the set fact would be
"userslist": {
"host": "kiwi",
"name": "pete",
"uid": "2"
}
With this patch, one gets:
"userslist": [
{
"host": "apple",
"name": "paul",
"uid": "1"
},
{
"host": "berry",
"name": "paul",
"uid": "1"
},
{
"host": "banana",
"name": "pete",
"uid": "2"
},
{
"host": "pear",
"name": "pete",
"uid": "2"
},
{
"host": "kiwi",
"name": "pete",
"uid": "2"
}
]
 https://github.com/ansible/ansible/pull/8019

allow set_fact action plugin to work with loops

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ansible