Ansible 乱记


playbooks可以包含多个plays(就是多个hosts锻),这样就可以在多个group之间切换:
- hosts: webservers
  user: root


  tasks:


xxxxxx

- hosts: databases
  ruser: root
  sudo: yes
  tasks:
xxxxxx
remote_user:



hosts行可以是一个或者多个group或者host,使用冒号分割。
user行是在远程机器执行命令的用户,你也可以给单个task指定执行用户,参数是remote_user.
sudo行允许你在远程以另外一个用户执行命令,默认是root。你也可以在单个task中使用sudo,而非整个play,如果你的sudo是需要密码的,则在允许playbook时在命令行需要提供--ask-sudo-pass参数



每个play可以包含多个tasks,task的执行是顺序的,一次一个。
每个task应该有一个name,它会在运行playbook时输出。


modules是幂等的,这意味着你可以多次执行他们,但结果是一样的。


command和shell模块是唯一两个可以不用K/V模式参数的模块,command和shell模块是在意命令执行状态返回码的,shell: /usr/bin/somecommand || /bin/true
如果action行的参数太长,则可以用空格分割开他们,你在var section下面建立的变量在action行也可以使用,name行也可以使用,格式是 "{{ xxx }}",这些变量在templates中也可以使用



在一个基本的playbook中,所有的task都列在play下面,列表看起来有点过于长,其实我们可以使用include命令来解决


handler是一系列的tasks,它和一般的task没有任何区别,它通过name被notify引用,在notify字段指定的task会引用handler定义的task,notify字段会在playbook的最后一个task之后被触发,而且只会被触发一次。



开始的时候,你可能把所有的task都写在一个playbook中,但有时候你想重用一些模块,这时候就麻烦了。你可以把task文件切分成小的task文件,然后在一个文件中引用其他task文件。


playbooks也可以include其他playbook,这时候其他的playbook会插入到当前位置。其实task、handlers、var都可以这样引用,这其实就是roles的功能。



如果你想在多个play或者playbooks之间重用task列表,你可以使用include。例如:
定义task:task/foo.yml
---
# possibly saved as tasks/foo.yml


- name: placeholder foo
  command: /bin/foo


- name: placeholder bar
  command: /bin/bar


在playbook通过include引用:
tasks:


  - include: tasks/foo.yml


你甚至可以传输变量到include,在include的文件内部,变量使用{{ xxx }}来定义
tasks:
  - include: wordpress.yml wp_user=timmy
  - include: wordpress.yml wp_user=alice
  - include: wordpress.yml wp_user=bob


在1.4版本之后,你还可以一次传输多个变量,使用列表或者字典
tasks:
 - { include: wordpress.yml, wp_user: timmy, ssh_keys: [ 'keys/one.txt', 'keys/two.txt' ] }


在1.0开始,你也可以通过其他语法把变量传输进include包含的文件中
tasks:
  - include: wordpress.yml
    vars:
        wp_user: timmy
        ssh_keys:
          - keys/one.txt
          - keys/two.txt



include也可以用在handlers上,例如有个重启apache的handler
handlers.yml:
---
# this might be in a file like handlers/handlers.yml
- name: restart apache
  service: name=apache state=restarted


然后在其他handler中引用:
handlers:
  - include: handlers/handlers.yml




现在我们已经见识过task和handlers来组织我们的playbook,但那种才是最好的组织方式?那就是roles。roles可以按照已知的文件目录结构自动的加载vars、task、handles。如何在roles中使用自己的modules,和扩展task、handlers一样,你可以在同级目录下新建一个library目录

roles能够根据层次型的目录结构自动的加载变量、文件、tasks、handlers等等。roles将变量、文件、tasks、module放置在单独的目录中,然后通过include可以把它们快速的集结在一起。

1  一般顶级目录是以roles命名
2  在roles目录下会分部着各种功能角色的目录,就是使目标机器变成什么状态。例如:db、web等等
3  在功能角色目录下分散着一系列目录,用来实现具体的实现步骤。这些目录就是playbook一般用到的资源,例如:files、handlers、tasks、templates、vars、meta、default、library等目录。用不到的功能可以不用创建相应的目录。
4  最后一步,在总的playbook中通过include集结这些功能角色


tasks:该目录必须包含一个main.yml文件,这个文件里面定义了该功能角色的tasks列表,是实现该功能角色的主要文件,可以用include来包含其他tasks文件
handlers:该目录包含一个main.yml文件,定义该功能角色用到的handler。
vars:该目录包含一个main.yml文件,用于定义该功能角色用到的变量,只对当前role有用
meta:设定role和role直接的依赖关系,包含在main.yml文件中
library:该功能角色自定义的模块
files:任何copy tasks都可以从该目录中引用相关文件,而不用指定绝对路径,任何script tasks也可以从该目录中引用相关脚本,而不用指定绝对路径。其实就是copy和script引用文件的目录
template:template模块会自动在该目录下寻找相关的jinja2模板
default:为当前角色设定默认变量用到的目录,包含在mian.yml文件中

site.yml
webservers.yml
fooservers.yml
roles/
   common/
     files/
     templates/
     tasks/
     handlers/
     vars/
     defaults/
     meta/
     library/
   webservers/
     files/
     templates/
     tasks/
     handlers/
     vars/
     defaults/
     meta/

在playbook中可以这样引用:
---
- hosts: webservers
  roles:
     - common
     - webservers

可以在配置文件的roles_path中设置role的搜索路径


也可以给roles传输参数,例如:
---
- hosts: webservers
  roles:
    - common
    - { role: foo_app_instance, dir: '/opt/a',  port: 5000 }
    - { role: foo_app_instance, dir: '/opt/b',  port: 5001 }



你也可以指定task在role之前或者之后生效:
- hosts: webservers

  pre_tasks:
    - shell: echo 'hello'

  roles:
    - { role: some_role }

  tasks:
    - shell: echo 'still busy'

  post_tasks:
    - shell: echo 'goodbye'



变量的定义:


在playbook中可以如下定义变量:
- hosts: webservers
  vars:
    http_port: 80


也可以从facts中获取信息,例如{{ ansible_devices.sda.model }}
如果你不想知道你hosts上的facts信息,你可以关闭他们的收集:
- hosts: whatever
  gather_facts: no


If a remotely managed system has an “/etc/ansible/facts.d” directory, any files in this directory ending in ”.fact”, can be JSON, INI, or executable files returning JSON, and these can supply local facts in Ansible. /etc/ansible/facts.d/preferences.fact



命令行传变量
ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"


Registered Variables:
当你执行一个命令的时候,这个命令产生的结果可以保存到一个变量,这时候可以把这个结果从一个模块传输到另一个模块。
- hosts: web_servers


  tasks:


     - shell: /usr/bin/foo
       register: foo_result
       ignore_errors: True


     - shell: /usr/bin/bar
       when: foo_result.rc == 5




条件语句
when:
tasks:
  - name: "shutdown Debian flavored systems"
    command: /sbin/shutdown -t now
    when: ansible_os_family == "Debian"


tasks:
  - command: /bin/false
    register: result
    ignore_errors: True
  - command: /bin/something
    when: result|failed
  - command: /bin/something_else
    when: result|success
  - command: /bin/still/something_else
    when: result|skipped


with_items:


role和include中的when:
- hosts: webservers
  roles:
     - { role: debian_stock_config, when: ansible_os_family == 'Debian' }


- include: tasks/sometasks.yml
  when: "'reticulating splines' in output"



Register Variables:
- name: registered variable usage as a with_items list
  hosts: all
  tasks:


      - name: retrieve the list of home directories
        command: ls /home
        register: home_dirs


      - name: add home dirs to the backup spooler
        file: path=/mnt/bkspool/{{ item }} src=/home/{{ item }} state=link
        with_items: home_dirs.stdout_lines
        # same as with_items: home_dirs.stdout.split()




如何访问其他机器的变量:
hostvars变量允许你查询另一个节点的变量,包括facts收集那台的数据。例如,你想用另一个节点的fact的数据:{{ hostvars['test.example.com'(节点)]['ansible_distribution'] }}


group_names is a list (array) of all the groups the current host is in
{% if 'webserver' in group_names %}
   # some part of a configuration file that only applies to webservers
{% endif %}



groups is a list of all the groups (and hosts) in the inventory. This can be used to enumerate all hosts within a group
{% for host in groups['app_servers'] %}
   # something that applies to all app servers.
{% endfor %}


loops:
- name: add several users
  user: name={{ item }} state=present groups=wheel
  with_items:
     - testuser1
     - testuser2


- name: add several users
  user: name={{ item.name }} state=present groups={{ item.groups }}
  with_items:
    - { name: 'testuser1', groups: 'wheel' }
    - { name: 'testuser2', groups: 'root' }




lookup_plugins主要是用来实现扩展playbook里面各种的字符串和变量的扩展


print json.dumps({"web":{"hosts":["10.10.10.66"],"vars":{"todo":"this server whill restart"}},"nginx":{"hosts":["10.10.10.69"],"va
rs":{"todo":"this nginx is restart"}}})


ansible inventory的返回格式,web相当于/etc/ansible/hosts里面的[web]标题,hosts相当于[web]下面的主机list,vars相当于变量。


ansible -i /xxx/xxx.py group -m xxx -a xxx



Callbacks 是一个有趣的插件类型,允许ansible响应事件的时候调用额外的callback插件
范例:https://github.com/ansible/ansible/blob/devel/plugins/callbacks/log_plays.py


/opt/ansible/lib/ansible/module_utils



如果有用sudo,切sudo有密码,则需要加上以下参数
ansible-playbook  -i ./hosts --ask-sudo-pass test.yml


你可能感兴趣的:(ansible)