设为首页 收藏本站
查看: 2059|回复: 0

[经验分享] Ansible详细配置管理工具(六)

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2014-7-25 09:36:51 | 显示全部楼层 |阅读模式
高级playbook



    Finding files with variables  
    All modules can take variables as part of their arguments by dereferencing them  
    with {{ and }} . You can use this to load a particular file based on a variable.  
    For example, you might want to select a different config file for NRPE (a Nagios  
    check daemon) based on the architecture in use. Here is how that would look:  
    ---  
    #1  
    - name: Configure NRPE for the right architecture  
    #2  
    hosts: ansibletest  
    #3  
    user: root  
    #4  
    tasks:  
    #5  
    - name: Copy in the correct NRPE config file  
    #6  
    copy: src=files/nrpe.{{ ansible_architecture }}.conf  
    dest=/etc/nagios/nrpe.cfg  
    #7  
    In the copy and the template modules, you can also configure Ansible to look for a  
    set of files, and it finds them using the first one. This lets you configure a file to look  
    for; if that file is not found a second will be used, and so on until the end of the list  
    is reached. If the file is not found, then the module will fail. The feature is triggered  
    by using the first_available_file key, and referencing {{ item }} in the action.  
    The following code is an example of this feature:  
    ---  
    #1  
    - name: Install an Apache config file  
    #2  
    hosts: ansibletest  
    #3  
    user: root  
    #4  
    tasks:  
    #5  
    - name: Get the best match for the machine  
    #6  
    copy: dest=/etc/apache.conf src={{ item }}  
    #7  
    first_available_file:  
    #8  
    - files/apache/{{ ansible_os_family }}-{{  
    ansible_architecture }}.cfg  
    #9  
    - files/apache/default-{{ ansible_architecture }}.cfg  
    - files/apache/default.cfg  
    #11  
    Remember that you can run the setup module from the Ansible  
    command-line tool. This comes in handy when you are making heavy  
    use of variables in your playbooks or templates. To check what facts will  
    be available for a particular play, simply copy the value of the host line  
    and run the following command:  
    ansible [host line] -m setup  
    On a CentOS x86_64 machine, this configuration would first look for the file  
    RedHat-x86_64.cfg upon navigating through files/apache/ . If that file did not  
    exist, it would look for file default-x86_64.cfg upon navigating through file/  
    apache/ , and finally if nothing exists, it'll try and use default.cfg .  


使用变量查找文件

所有的Ansible模块都可以使用{{ }}这种形式将变量做为他的一部分参数。这样你就可以利用变量来加载不同的配置。比如你希望根据不同架构来加载不同nrpe配置,代码如下:

---
- name: Configure NRPE for the right architecture
hosts: ansibletest
user: root
tasks:
- name: Copy in the correct NRPE config file
copy: src=files/nrpe.{{ ansible_architecture }}.conf
dest=/etc/nagios/nrpe.cfg

在copy和template模块中,Ansible可以让那个你配置去查找一个文件集,第一个被找到的文件将被使用,若找不到则继续知道找到匹配的为止,若循环完毕还是没有找到对应的文件,那么模块不会被运行。使用first_available_file关键字和在action中使用{{ item }}来完成以上功能,示例代码如下:

---
- name: Install an Apache config file
hosts: ansibletest
user: root
tasks:
- name: Get the best match for the machine
copy: dest=/etc/apache.conf src={{ item }}
first_available_file:
- files/apache/{{ ansible_os_family }}-{{
ansible_architecture }}.cfg
- files/apache/default-{{ ansible_architecture }}.cfg
- files/apache/default.cfg


注意:在你大量使用模板和变量之前,你可以使用setup模块来确认一些fact(比如上面这个例子主要是因为不同的操作系统apache的配置文件名和格式都不一样)。

在centos X86_64的机器上,他首先会查找RedHat-x86_64.cfg,因为他的架构是x86_64,如果找不到就找default-x86_64.cfg,如果再找不到就用default.cfg。



    Environment variables  
    Often Unix commands take advantage of certain environment variables. Prevalent  
    examples of this are C makefiles, installers, and the AWS command-line tools.  
    Fortunately, Ansible makes this really easy. If you wanted to upload a file on the  
    remote machine to Amazon S3, you could set the Amazon access key as follows. You  
    will also see that we install EPEL so that we can install pip, and pip is used to install  
    the AWS tools.  
    ---  
    #1  
    - name: Upload a remote file via S3  
    #2  
    hosts: ansibletest  
    #3  
    user: root  
    #4  
    tasks:  
    #5  
    - name: Setup EPEL  
    #6  
    command rpm -ivh  
    #7  
    http://download.fedoraproject.org/pub/epel/6/i386/epel-  
    release-6-8.noarch.rpm  
    creates=/etc/yum.repos.d/epel.repo  
    #8  
    - name: Install pip  
    #9  
    yum: name=python-pip state=installed  
    - name: Install the AWS tools  
    pip: name=awscli state=present  
    #10  
    #11  
    #12  
    - name: Upload the file  
    #13  
    shell: aws s3 put-object --bucket=my-test-bucket --key={{  
    ansible_hostname }}/fstab --body=/etc/fstab --region=eu-  
    west-1  
    #14  
    environment:  
    #15  
    AWS_ACCESS_KEY_ID: XXXXXXXXXXXXXXXXXXX  
    #16  
    AWS_SECRET_ACCESS_KEY: XXXXXXXXXXXXXXXXXXXXX  
    #17  
    Internally, Ansible sets the environment variable into the Python code;  
    this means that any module that already uses environment variables  
    can take advantage of the ones set here. If you write your own modules,  
    you should consider if certain arguments would be better used as  
    environment variables instead of arguments.  
    Some Ansible modules such as get_url , yum , and apt will also use environment  
    variables to set their proxy server. Some of the other situations where you might  
    want to set environment variables are as follows:  
    ?     Running application installers  
    ?     Adding extra items to the path when using the shell module  
    ?     Loading libraries from a place not included in the system library search path  
    ?     Using an LD_PRELOAD hack while running a module  


Environment 环境变量

unix的一些命令经常配合环境变量来运行,典型的例子比如,C makefiles, installers, 和 AWS这些命令行工具。幸运的是使用Ansible做到这一点,非常简单。比如:当我们要上传一个文件到S3服务器的时候,我们需要提AWS_SECRET_ACCESS_KEY,我们的脚本代码如下:

---
- name: Upload a remote file via S3
hosts: ansibletest
user: root

tasks:
- name: Setup EPEL
command rpm -ivh
http://download.fedoraproject.org/pub/epel/6/i386/epel-
release-6-8.noarch.rpm
creates=/etc/yum.repos.d/epel.repo


- name: Install pip
yum: name=python-pip state=installed


- name: Install the AWS tools
pip: name=awscli state=present


- name: Upload the file
shell: aws s3 put-object --bucket=my-test-bucket --key={{
ansible_hostname }}/fstab --body=/etc/fstab --region=eu-
west-1
environment:
AWS_ACCESS_KEY_ID: XXXXXXXXXXXXXXXXXXX
AWS_SECRET_ACCESS_KEY: XXXXXXXXXXXXXXXXXXXXX

我们先使用epel来安装pip,然后使用ip来安装aws最后设置shell环境变量然后上传文件。

注意:我们在ansible内部把这些环境变量放入到python的代码中,这样就可以让任何使用环境变量的模块都可以使用这里的设置了。如果你要编写自己的模块,你可以把参数作为环境变量放到这里将比使用参数更好哦!

另外像get_url , yum , 和 apt还会使用环境变量中的代理设置。下面是其他一些需要使用环境变量的场景:

    安装一个应用程序
    在使用shell模块的时候加入新的path
    加载不存在系统默认搜索路径的库
    运行的模块需要使用动态链接库的时候



    External data lookups  
    Ansible introduced the lookup plugins in Version 0.9. These plugins allow Ansible to  
    fetch data from outside sources. Ansible provides several plugins, but you can also  
    write your own. This really opens the doors and allows you to be flexible in your  
    configuration.  
    Lookup plugins are written in Python and run on the controlling machine. They are  
    executed in two different ways: direct calls and with_* keys. Direct calls are useful  
    when you want to use them like you would use variables. Using the with_* keys is  
    useful when you want to use them as loops. In an earlier section we covered with_  
    fileglob , which is an example of this.  
    In the next example, we use a lookup plugin directly to get the http_proxy value from  
    environment and send it through to the configured machine. This makes sure that the  
    machines we are configuring will use the same proxy server to download the file.  
    ---  
    #1  
    - name: Downloads a file using the same proxy as the controlling  
    machine  
    #2  
    hosts: all  
    #3  
    tasks:  
    #4  
    - name: Download file  
    #5  
    get_url: dest=/var/tmp/file.tar.gz  
    url=http://server/file.tar.gz  
    #6  
    environment:  
    #7  
    http_proxy: "{{ lookup('env', 'http_proxy') }}"  
    #8  

外部数据查找

Ansible在0.9版本的时候引入了lookup插件。这些插件可以让Ansible从外部数据源获取数据。Ansible提供了好多插件,但是你还是可以自己写,这真的是非常开放,可以你非常灵活的配置。

lookup插件用python编写,并运行在控制主机上。它有2中执行方式:直接调用和使用with_*关键字;当你想像使用变量那样使用的时候可以用直接调用的方式,如果你想像循环那样使用则可以选择with_*关键字这种方式,之前前我们有一个例子中使用了ith_fileglob就是这种方式。

下面的例子我们直接从环境变量中获取http_proxy然后发送给远程主机,以确保他们使用同样的下载代理。

---
- name: Downloads a file using the same proxy as the controlling
machine
hosts: all


tasks:
- name: Download file
get_url: dest=/var/tmp/file.tar.gz
              url=http://server/file.tar.gz
environment:
http_proxy: "{{ lookup('env', 'http_proxy') }}"

注意:你也可以在lookup插件中使用变量,他不会在查找到之后马上被赋值,而是保存在一个宏里面,你每次运行的时候再查找一次。如果你用的某些值经常会变的时候,这就非常有用了。

使用with_*格式可以让你历遍列表中的所有值,任何插件都可以,而他们返回的列表通常都很有用。下面的例子展示如何注册动态的app farm,它可以为每个虚拟机添加一个新的任务,并在每个虚拟机上运行。

---
- name: Registers the app server farm
hosts: localhost
connection: local
vars:
hostcount: 5


tasks:
- name: Register the webapp farm
local_action: add_host name={{ item }} groupname=webapp
with_sequence: start=1 end={{ hostcount }} format=webapp%02x

lookup适用的从场景有:

    复制apache的整个配置文件夹到conf.d这种形式的文件夹下面
    根据环境变量来调整哪些playbook需要运行
    从DNS TXT 记录获取配置
    把一个命令的输出放如一个变量



    Storing results  
    Almost every module outputs something, even the debug module. Most of the  
    time the only variable used is the one named changed . The changed variable helps  
    Ansible decide whether to run handlers or not and which color to print the output  
    in. However, if you wish you can store the returned values and use them later in the  
    playbook. In this example we look at the mode in the /tmp directory and create a  
    new directory called /tmp/subtmp with the same mode.  
    ---  
    - name: Using register  
    hosts: ansibletest  
    user: root  
    tasks:  
    - name: Get /tmp info  
    file: dest=/tmp state=directory  
    register: tmp  
    - name: Set mode on /var/tmp  
    file: dest=/tmp/subtmp mode={{ tmp.mode }} state=directory  
    Some modules, like we see in the previous file module, can be configured to simply  
    give information. Combining this with the register feature, you can create playbooks  
    that can examine the environment and calculate how to proceed.  
    Combining the register feature and the set_fact module allows you  
    to perform data processing on data you receive back from modules. This  
    allows you to compute values and perform data processing on these values.  
    This makes your playbooks even smarter and more flexible than ever.  
    Register allows you to make your own facts about hosts from modules already  
    available to you. This can be useful in many different circumstances:  
    ?     Getting a list of files in a remote directory and downloading them all  
    with fetch  
    ?     Running a task when a previous task changes, before the handlers run  
    ?     Getting the contents of the remote host SSH key and building a  
    known_hosts file  

保存结果

几乎所有的模块都会输出一些东西,debug模式中也是如此。多数情况下只有变量被标记是否被改变了,这可以帮助Ansible来决定是否要调用处理程序handle、输出哪种颜色的信息。如果你想保存返回变量的值,保存之后在以后的playbook中使用。下面的例子向你展示,我们先查找/tmp目录的信息,将信息注册为变量,然后利用这个变量为子目录的全新赋值:

---
- name: Using register
hosts: ansibletest
user: root

tasks:
- name: Get /tmp info
file: dest=/tmp state=directory
register: tmp


- name: Set mode on /var/tmp
file: dest=/tmp/subtmp mode={{ tmp.mode }} state=directory

像file这样的模块可以被配置为简单的给出一些信息,然后结合register注册模块,我们可以创建出根据环境变量来决定如何执行的playbook!

注意:结合register注册模块和set_fact模块,你可以根据模块返回的值来处理数据,这将让我们的playbooks变得更加聪明、更加灵活。

register注册模块允许你从主机上可用的模块中注册你自己的fact,这在以下场景中非常有用:

    从远程主机上获取一个目录列表并下载他们
    在handlers处理程序运行之前,根据前一个任务的改变内容运行一个新任务
    获取远程主机的ssh的key的内容,合成一个known_hosts文件



    Debugging playbooks  
    There are a few ways in which you can debug a playbook. Ansible includes both  
    a verbose mode, and a debug module specifically for debugging. You can also use  
    modules such as fetch and get_url for help. These debugging techniques can also  
    be used to examine how modules behave when you wish to learn how to use them.  


Debugging playbooks

有很多方法可以debug一个playbook。Ansible包含一个详细模式和一个专用调试模块。你可以像其他模块的帮助一样使用调试模式的帮助。这些debugging技术还可以让你在想学习如何使用他们的时候,熟悉他们的行为方式。



    The debug module  
    Using the debug module is really quite simple. It takes two optional arguments,  
    msg and fail . msg sets the message that will be printed by the module and fail , if  
    set to yes , indicates a failure to Ansible, which will cause it to stop processing the  
    playbook for that host. We used this module earlier in the skipping modules section  
    to bail out of a playbook if the operating system was not recognized.  
    In the following example, we will show how to use the debug module to list all the  
    interfaces available on the machine:  
    ---  
    - name: Demonstrate the debug module  
    hosts: ansibletest  
    user: root  
    vars:  
    hostcount: 5  
    tasks:  
    - name: Print interface  
    debug: msg="{{ item }}"  
    with_items: ansible_interfaces  
    The preceding code gives the following output:  
    PLAY [Demonstrate the debug module] *********************************  
    GATHERING FACTS *****************************************************  
    ok: [ansibletest]  
    TASK: [Print IP address] ********************************************  
    ok: [ansibletest] => (item=lo) => {"item": "lo", "msg": "lo"}  
    ok: [ansibletest] => (item=eth0) => {"item": "eth0", "msg": "eth0"}  
    PLAY RECAP **********************************************************  
    ansibletest  
    : ok=2  
    changed=0  
    unreachable=0  
    failed=0  
    As you can see the debug module is easy to use to see the current value of a variable  
    during the play.  


Debug 模式

使用debug模式非常简单,只需要2个可选的参数,msg和fail。msg 设置模块和fail来打印消息,当msg设置为yes时,表明Ansible有failure会导致playbook停止在这台主机上运行。通常我们在脚本的开始处来检测操作系统是否可以被认出。下面的例子中,我们将展示如何使用debug模块来列机器上所有可用的接口:

---
- name: Demonstrate the debug module
hosts: ansibletest
user: root
vars:
hostcount: 5
tasks:
- name: Print interface
debug: msg="{{ item }}"
with_items: ansible_interfaces

上面的脚本输出如下:

PLAY [Demonstrate the debug module] *********************************
GATHERING FACTS *****************************************************
ok: [ansibletest]
TASK: [Print IP address] ********************************************
ok: [ansibletest] => (item=lo) => {"item": "lo", "msg": "lo"}
ok: [ansibletest] => (item=eth0) => {"item": "eth0", "msg": "eth0"}
PLAY RECAP **********************************************************
ansibletest
: ok=2
changed=0
unreachable=0
failed=0



    The verbose mode  
    Your other option for debugging is the verbose option. When running Ansible  
    with verbose, it prints out all the values that were returned by each module after it  
    runs. This is especially useful if you are using the register keyword introduced  
    in the previous section. To run ansible-playbook in verbose mode, simply add  
    --verbose to your command line as follows:  
    ansible-playbook --verbose playbook.yml  


详细模式

另外一个选择是debugging详细模式。当使用详细模式时,他会打印出每个模块运行后所有的返回值。这在使用register关键字的时候特别有用。使用详细模式的方法非常简单,在命令后加一个--verbose就可以了:

ansible-playbook --verbose playbook.yml



    The check mode  
    In addition to the verbose mode, Ansible also includes a check mode and a diff  
    mode. You can use the check mode by adding --check to the command line, and  
    --diff to use the diff mode. The check mode instructs Ansible to walk through the  
    play without actually making any changes to remote systems. This allows you to  
    obtain a listing of the changes that Ansible plans to make to the configured system.  
    It is important here to note that the check mode of Ansible is not  
    perfect. Any modules that do not implement the check feature are  
    skipped. Additionally, if a module is skipped that provides more  
    variables, or the variables depend on a module actually changing  
    something (like file size), then they will not be available. This is an  
    obvious limitation when using the command or shell modules.  
    The diff mode shows the changes that are made by the template module. This  
    limitation is because the template file only works with text files. If you were to  
    provide a diff of a binary file from the copy module, the result would almost be  
    unreadable. The diff mode also works with the check mode to show you the planned  
    changes that were not made due to being in check mode.  


检查模式

除了详细模式,Ansible还有检查模式和差异模式。你可以用--check和--diff来运行他们,检查模式会检查脚本的运行,但是不会在远程受管主机上执行任何改变配置的操作,它返回一个可能改变的列表。

注意:检测模式不是全能的,那些不做任何改变配置操作的模块会直接被忽略,另外基于变量的模块也会被忽略,那些基于上一个任务改变而运行的模块也会被忽略。它主要用于检查command和shell模块的可行性。
差异模块可以现实出被模板模块改变的内容,但是这仅限于text文件,如果你指向的是一个binary可执行文件,那么结果永远是不可达。差异模块和检查模块一样不会对远程主机有任何改变。



    The pause module  
    Another technique is to use the pause module to pause the playbook while you  
    examine the configured machine as it runs. This way you can see changes that the  
    modules have made at the current position in the play, and then watch while it  
    continues with the rest of the play.  

暂停模块

另外一种debug技术是使用暂停模块,当你要检测远程受管主机上的脚本运行的时候,使用暂停模块来暂停playbook,这样你可以看到当前步骤模块所做的改变,并继续监视知道结束。



    Summary  
    In this chapter we explored the more advanced details of writing playbooks. You  
    should now be able to use features such as delegation, looping, conditionals, and fact  
    registration to make your plays much easier to maintain and edit. We also looked at  
    how to access information from other hosts, configure the environment for a module,  
    and gather data from external sources. Finally we covered some techniques for  
    debugging plays that are not behaving as expected.  
    In the next chapter we will be covering how to use Ansible in a larger environment.  
    It will include methods for improving the performance of your playbooks that may  
    be taking a long time to execute. We will also cover a few more features that make  
    plays maintainable, particularly splitting them into many parts by purpose.  


本章小节

这一章我们介绍了更多在写playbooks时候的高级细节。你现在应该可以使用委派、循环、条件、fact注册来是你的plays更加易于维护和编写。我们还介绍了如何访问其他机器的信息、为模块配置环境变量、从外部数据源收集信息。最后我们还介绍了一些debugging技术。

下一章我们将介绍如何在一个大的环境中使用Ansible,这包括如何改进playbooks的运行性能以减少运行时间。我们还将介绍更多的特性,关于如何使得plays更易维护,并根据目标将他们分为多个部分。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-22677-1-1.html 上篇帖子: Ansible详细配置管理工具(五) 下篇帖子: Ansible详细配置管理工具(七) 管理工具
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表