[email protected]一个高效的配置管理工具--Ansible configure management--翻译(六)

无书面许可请勿转载

高级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更易维护,并根据目标将他们分为多个部分。

[email protected]一个高效的配置管理工具--Ansible configure management--翻译(六),布布扣,bubuko.com

时间: 2024-10-12 22:25:45

[email protected]一个高效的配置管理工具--Ansible configure management--翻译(六)的相关文章

[email protected]一个高效的配置管理工具--Ansible configure management--翻译(七)

如无书面授权,请勿转载 Larger Projects Until now, we have been looking at single plays in one playbook file. This approach will work for simple infrastructures, or when using Ansible as a simple deployment mechanism. However, if you have a large and complicated

[email protected]一个高效的配置管理工具--Ansible configure management--翻译(十二)

如无书面授权,请勿转载 第五章 自定义模块 External inventories In the first chapter we saw how Ansible needs an inventory file, so that it knows where its hosts are and how to access them. Ansible also allows you to specify a script that allows you to fetch the inventor

Ansi[email protected]一个高效的配置管理工具--Ansible configure management--翻译(五)

无书面许可请勿转载 高级Playbook Extra variables You may have seen in our template example in the previous chapter that we used a variable called group_names . This is one of the magic variables that are provided by Ansible itself. At the time of writing there a

[email protected]一个高效的配置管理工具--Ansible configure management--翻译(四)

无书面许可请勿转载 由于第三章内容较长,我将分做几个部分来翻译. Advanced Playbooks So far the playbooks that we have looked at are simple and just run a number of modules in order. Ansible allows much more control over the execution of your playbook. Using the following techniques

[email protected]一个高效的配置管理工具--Ansible configure management--翻译(九)

如无书面授权,请勿转载 第四章 大型项目中Ansible的使用 New features in 1.3 There are two features in Ansible 1.3 that were alluded to previously in the chapter. The first feature is the metadata roles. They allow you to specify that your role depends on other roles. For ex

[email protected]一个高效的配置管理工具--Ansible configure management--翻译(十)

无书面许可,请勿转载 Custom Modules Until now we have been working solely with the tools provided to us by Ansible. This does afford us a lot of power, and make many things possible. However, if you have something particularly complex or if you find yourself u

[email protected]一个高效的配置管理工具--Ansible configure management--翻译(十一)

无书面授权,请勿转载 第五章 自定义模块 Using a module Now that we have written our very first module for Ansible, we should give it a go in a playbook. Ansible looks at several places for its modules: first it looks at the place specified in the library key in its con

[email protected]一个高效的配置管理工具--Ansible configure management--翻译(一)

未经书面许可,请勿转载 ---      Ansible is the simplest way to automate apps and IT infrastructure 这是Ansible官方站点的介绍,本着学习的态度我决定一边学习一边翻译Ansible configure management这本书.原文下载稍后放出 #一些自解释的文字,我会忽略.或者依照自己的理解简单翻译一下,并不是每行每句都是一一相应. Preface Since CFEngine was first created

[email protected]一个高效的配置管理工具--Ansible configure management--翻译(五)

无书面许可请勿转载 高级Playbook Extra variables You may have seen in our template example in the previous chapter that we used a variable called group_names . This is one of the magic variables that are provided by Ansible itself. At the time of writing there a