• ansible四


    ansible入门
    Ansible是一个配置管理和配置工具,使用SSH连接到服务器并运行配置好的任务,服务器上不需要安装任何其他软件,只需要开启SSH,客户端的ansible会完成所有其他的工作。

    首先安装Ansible:
    apt-get安装的版本很低,建议使用pip安装:
    sudo pip install ansible
    可能会提示什么:from pip import main ImportError: cannot import name main
    那就使用--user:pip install --user ansible

    在虚拟环境virtualenv中安装:

    sudo pip install -U virtualenv # 首先安装virtualenv
    # 然后进入一个ansible专门的文件夹,创建虚拟环境:
    virtualenv .venv
    source .venv/bin/activate
    # 进入了虚拟环境
    pip install ansible

    pip install -U ansible # 任何时候都可以这样更新ansible
    1
    2
    3
    4
    5
    6
    7
    8
    配置ansible:
    在ansible1里面,我们需要用到/etc/ansible里面的默认配置,但是像上面那样在虚拟环境里面安装ansible,那么我们完全不需要这些默认文件,我们可以在非本地路径下创建这些配置文件。

    管理服务器:Inventory
    我们需要创建一个inventory file用来定义管理哪个server,命名随意,一般为hosts:

    [web]
    192.168.22.10
    192.168.22.11
    1
    2
    3
    在web标签下我们需要管理两个server

    当我们在server上运行ansible against本地机,我们不需要关心Inventory file里面的内容
    当我们本地运行ansible against远程服务器时,Inventory file需要这样编写:

    [local]
    127.0.0.1

    [remote]
    192.168.1.2
    1
    2
    3
    4
    5
    接下来是建立本地与远程服务器之间连接的命令。


    Running Commands
    接下来我们针对服务器运行任务tasks,ansible是通过SSH去管理服务器的:

    # Run against localhost
    ansible -i ./hosts --connection=local local -m ping

    # Run against remote server针对远程服务器运行ansible
    ansible -i ./hosts remote -m ping
    1
    2
    3
    4
    5
    参数说明

    --connection=local的意思是不需要通过ssh连接,因为我们针对的就是本地,还可以是--connection=ssh意思是需要ssh连接。
    -i ./hosts指定Inventory file,告诉我们连接到哪里
    remote,local,all指明使用哪个标签下面的服务器清单,all表示针对每个服务器运行
    -m ping表示使用ping模块,会返回ping结果
    然后针对阿里云服务器进行了尝试,运行ansible -i ./hosts remote -m ping发现报错:

    39.107.74.200 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).",
    "unreachable": true
    }
    1
    2
    3
    4
    5
    感觉问题应该是这样的命令没有输入用户名和密码,尝试
    ansible -i ./hosts remote -m ping -u root --ask-pass 前提是使用sudo apt-get安装好了sshpass,然后返回结果:

    39.107.74.200 | SUCCESS => {
    "changed": false,
    "ping": "pong"
    }
    1
    2
    3
    4
    但是每次敲这么多命令就很复杂,更简单的方法是将用户名密码写入hosts文件里面:

    [remotr]
    29.107.74.200 ansible_ssh_user=root ansible_ssh_pass=123456
    1
    2
    然后就不需要额外的命令了


    Modules
    ansible使用模块来完成任务,比如安装软件,复制文件以及使用模板。
    模块aret the way to use absible, 因为模块可以使用上下文来确定完成任务需要做些什么。
    如果没有模块,我们只能运行shell命令,其实是使用的shell模块:

    ansible -i ./hosts remote -b --become-user=root all
    -m shell -a 'apt-get install nginx’
    1
    2
    -b 成为另一个用户
    --become-user=root 以用户root运行命令
    -m定义模块,这里使用的是shell模块
    -a给模块传递参数
    这样做并不好,因为这样只能完成bash脚本能够完成的任务


    我们还可以使用apt模块,这样能确保幂等(一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同)

    ansible -i ./hosts remote -b --become-user=root
    -m apt -a 'name=nginx state=installed update_cache=true'
    1
    2
    如果执行后显示的是change:False,就表明已经安装,没有对环境造成任何影响

    name=nginx表示需要安装的软件包名
    state=installed表示需要的结束状态
    update_cache=true表示是否更新软件包储存库缓存
    通过模块我们可以做我们想做的事,但是为了更好管理,我们把任务都放到playbook里面,就可以运行多个tasks


    Playbooks
    playbook可以运行多任务还有一些高级功能,playbook和roles(剧本和角色)都使用YAML文件定义:
    nginx.yml

    - hosts: remote
    become: yes
    become_user: root
    tasks:
    - name: install nginx
    apt:
    name: nginx
    state: present
    update_cache: true
    1
    2
    3
    4
    5
    6
    7
    8
    9
    YAML文件格式:用缩排方式呈现,结构通过缩进来表示,连续的项目使用-表示,键值对用:表示,不可以使用TAB.
    如何使用playbook呢?直接运行:
    ansible-playbook -i ./hosts nginx.yml


    Handlers
    handlers=tasks,处理程序可以做任务可以完成的任何事,但是只有当另一个task调用它的时候才会执行。
    我们添加notify指令到上面的playbook中:

    - hosts: remote
    become: yes
    become_user: root
    tasks:
    - name: Install Nginx
    apt:
    name: nginx
    state: present
    update_cache: true
    notify:
    - Start Nginx
    handlers:
    - name: Start Nginx
    service:
    name: nginx
    state: started
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    任务task运行后会通知名为start Nginx的处理程序:该handler处理使用服务service模块,可以启动停止重启等操作。

    所以handler和task的唯一区别就是task会自动调用,handler得等着task来调用它

    这里还有一个地方需要注意:如果这里nginx已经安装,那么nginx安装任务不会运行,handler也不会被调用。

    使用变量:
    首先定义变量:

    - hosts: local
    connection: local
    become: yes
    become_user: root
    vars:
    - docroot: /var/www/serversforhackers.com/public
    1
    2
    3
    4
    5
    6
    使用变量方法:

    file:
    path: '{{ docroot }}'
    1
    2
    使用Jinja模板,必须是单引号或者双引号


    roles(最终使用方法,比playbook更好配置)
    roles角色用于组织多个task并封装成完成这些任务需要的数据,但是真实的配置场景里面,我们需要很多变量,文件,模板之类的东西,虽然可以配合playbook使用,但是roles更好,因为它有一个目录结构来规范

    roles
    rolename
    - files
    - handlers
    - meta
    - templates
    - tasks
    - vars
    1
    2
    3
    4
    5
    6
    7
    8
    我们下面创建一个新的role例子,role的任务有:

    1. Add Nginx Repository- 使用apt_repository模块添加Nginx稳定PPA以获取最新的稳定版本的Nginx 。
    2. Install Nginx - 使用Apt模块安装Nginx。
    3. Create Web Root - 最后创建一个Web根目录。
    1
    2
    3
    在每一个子目录中,ansible都会自动找到并读取那个叫main.yml的文件。

    创建角色
    进入本地ansible-test文件夹,激活虚拟环境:

    mkdir nginx # 这里最好就使用roles这个名字
    cd nginx
    ansible-galaxy init nginx
    1
    2
    3
    然后进入nginx,会发现整个role目录已经建立好了。

    1. files
    里面放置我们需要复制到服务器中的文件


    2. handlers
    记得放在main.yml文件中:

    ---
    - name: Start Nginx
    service:
    name: nginx
    state: started

    - name: Reload Nginx
    service:
    name: nginx
    state: reloaded
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    前面提到了handler需要被task调用才起作用,我们可以在其他的YAML文件中调用它们


    3. meta
    这个目录里面的main.yml用于描述角色之间的依赖关系,比如nginx role依赖于ssl role,那么:

    ---
    dependencies:
    - {role: ssl}
    1
    2
    3
    这样调用nginx角色时,自动会先调用ssl角色
    如果无任何依赖:
    dependencies: []


    4. Template
    这里面不需要有main.yml文件,这里的文件使用的是Jinja2模板引擎的.j2文件
    比如我们新建一个文件为serversforhackers.com.conf.j2:

    server {
    # Enforce the use of HTTPS
    listen 80 default_server;
    server_name {{ domain }};
    return 301 https://$server_name$request_uri;
    }

    server {
    listen 443 ssl default_server;

    root /var/www/{{ domain }}/public;
    index index.html index.htm index.php;

    access_log /var/log/nginx/{{ domain }}.log;
    error_log /var/log/nginx/{{ domain }}-error.log error;

    server_name {{ domain }};

    charset utf-8;

    include h5bp/basic.conf;

    ssl_certificate {{ ssl_crt }};
    ssl_certificate_key {{ ssl_key }};
    include h5bp/directive-only/ssl.conf;

    location / {
    try_files $uri $uri/ /index.php$is_args$args;
    }

    location = /favicon.ico { log_not_found off; access_log off; }
    location = /robots.txt { log_not_found off; access_log off; }

    location ~ .php$ {
    include snippets/fastcgi.conf;
    fastcgi_pass unix:/var/run/php7.1-fpm.sock;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    这是一个标准的php应用的Nginx配置文件,里面有一些变量


    5. vars
    该目录需要有main.yml文件:

    ---
    domain: serversforhackers.com
    ssl_key: /etc/ssl/sfh/sfh.key
    ssl_crt: /etc/ssl/sfh/sfh.crt
    1
    2
    3
    4

    6. tasks
    这个是最重要的文件夹,使用role的时候,运行的文件就是该文件夹下面的main.yml文件:

    ---
    - name: Add Nginx Repository
    apt_repository:
    repo: ppa:nginx/stable
    state: present

    - name: Install Nginx
    apt:
    pkg: nginx
    state: installed
    update_cache: true
    notify:
    - Start Nginx

    - name: Add H5BP Config
    copy:
    src: h5bp
    dest: /etc/nginx
    owner: root
    group: root
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    运行角色 Run Role
    我们要对服务器运行一个或者多个role的时候,我们还是需要用到playbook,playbook需要和roles在同一个目录下面,然后创建一个主yml文件,在这个文件里面定义需要使用的角色以及是对哪个服务器执行的操作:
    新建 server.yml(这就是那个playbook):

    - hosts: local
    connection: local
    roles:
    - nginx
    1
    2
    3
    4
    然后老样子运行playbook:
    ansible-playbook -i ./hosts server.yml

    前面几大板块的关系:
    playbook >> roles >> tasks+handler+… >>modules
    总的playbook里面可能就几行,所有各部分的功能交给不同的role来完成。
    每个role里面是各种task并且调用handler支撑功能的。
    每个task和handler里面的功能是由各种模块modules实现的。


    我们使用ssh与托管节点(服务器)通信,默认使用sftp(使用SSH协议进行FTP传输的协议叫做SFTP,),如果不可用,需要在ansible.cfg文件中配置成scp方式

    这里不建议使用virtualenv虚拟环境来安装ansible

    Inventory文件
    对于每一个host可以选择连接类型和连接用户名:

    [targets]

    localhost ansible_connection=local
    39.107.74.200 ansible_connection=ssh ansible_ssh_user=root
    1
    2
    3
    4
    给整个组添加变量
    上面是给服务器单独配置变量,但是也可以给整个组配置变量:

    [remote:vars]
    ansible_connection=ssh

    [remote]
    host1
    host2
    1
    2
    3
    4
    5
    6
    只要需要配置的组的名字对上了,就可以获取配置

    将一个组变成另一个组的成员:

    [groupA]
    host1

    [groupB:children]
    groupA
    1
    2
    3
    4
    5
    各种参数说明:

    参数 说明
    ansible_ssh_host 远程主机名
    ansible_ssh_port ssh端口
    ansible_ssh_user ssh用户名
    ansible_ssh_pass ssh密码,建议使用–ask-pass
    ansible_sudo_pass sudo 密码,建议使用–ask-sudo-pass
    ansible_connection 与远程主机连接类型local ssh
    ansible_python_interpreter 目标主机python路径,适用于主机有多个python

    Ad-Hoc
    ansible 有两种方法完成任务,一个是as-hoc,一个是playbook,前者解决简单任务,后者复杂任务

    Ansible配置文件
    ansible的一些设置可以通过配置文件完成,大多数情况下,默认配置就足够了,配置被读取的顺序:

    ANSIBLE_CONFIG(环境变量)
    ansible.cfg(当前目录)
    .ansible.cfg(当前家目录)
    /etc/ansible/ansible.cfg
    1
    2
    3
    4
    下面是配置文件不同段的详解:
    多数为默认段,[defaults]中

    代码 说明
    ask_pass 控制playbook是否弹出询问密码,默认值为No
    ask_sudo_pass 是否弹出询问sudo密码
    command_warnings 当shell和命令行模块被默认模块简化的时,是否发出警告
    deprecation_warnings 设置为True,允许在输出结果中禁用‘不建议使用’警告
    forks 设置与主机通信时默认并行进程数,如果有很多主机,高数值会让跨主机行为更快,设置为100
    gathering 控制默认facts收集(远程系统变量),smart值代表没有facts的新host不会被扫描,在节省facts收集时比较有用
    inventory 默认库文件(hosts文件)位置
    library 默认模块的位置,library = ./library/,但是ansible知道如何搜寻多个用冒号隔开的路径,也会搜索playbook中的./library
    log_path ansible将会在选定位置记录执行信息
    module_lang 默认模块和计算机通信语言,默认为C语言
    module_name 是默认模块名,默认为command,但是不支持shell变量等,所以可能希望改为shell
    nocolor=0 为输出结果加上颜色,便于区分,如果想关闭设置为1
    remote_port 默认的远程端口,默认为22
    remote_tmp 使用默认路径希望像更换补丁一样使用模块
    remote_user 默认远程主机用户名
    roles_path 指的是’roles/’下的额外目录,用于playbook搜索Ansible roles.
    timeout ssh尝试超时时间
    host_key_checking 检测主机秘钥,禁用设为False
    [ssh_connection] 调整ssh通信连接

    代码 说明
    scp_if_ssh 设置为True,scp将代替用来为远程主机传输文件,没必要修改
    pipelining 开启将显著提高性能,在不通过实际文件传输的情况下执行ansible模块来使用管道特性,从而减少执行远程模块SSH操作次数

    Ansible Playbook
    1. 主机和用户:

    ---
    - hosts: webservers
    remote_user: yourname
    sudo: yes
    1
    2
    3
    4
    还可以sudo到不同的用户身份:
    sudo_user: postgres


    2. Tasks列表:
    modules具有幂等性,如果再一次执行module,module只会执行必ansible_ssh_connection=ssh要的改动,所以重复多次执行playbook也没有问题。

    基本task定义,使用key=value格式,大多数都是这样的:

    tasks:
    - name: make sure apache is running
    service: name=httpd state=running
    1
    2
    3
    特别的模块是command和shell,不使用key=value:

    tasks:
    - name: run this command and ignore the result
    shell: /usr/bin/somecommand
    ignore_errors: True
    1
    2
    3
    4
    action中可以使用变量,假设前面vars里面设置了变量’vhost‘

    tasks:
    - name: create a virtual host file for {{ vhost }}
    template: src=somefile.j2 dest=/etc/httpd/conf.d/{{ vhost }}
    1
    2
    3

    3. Handlers 在发生改变的时候执行操作
    因为module具有幂等性,如果远端系统被人改动,可以重放playbook达到恢复的目的,playbook本身有识别这种改动的功能,有一个基本的event system时间系统可以响应改动

    - name: template configuration file
    template: src=template.j2 dest=/etc/foo.conf
    notify:
    - restart memcached
    - restart apache
    handlers:
    - name: restart memcached
    service: name=memcached state=restarted
    - name: restart apache
    service: name=apache state=restarted
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    notify会在playbook每一个task结束的时候触发,即使有多个不同的task通知改动发生,notify也只会触发一次

    handlers一般用于重启服务,此外很少用到


    4. 执行一个playbook:
    ansible-playbook playbook.yml -f 10
    并行的级别为10

    5. include file
    在一个playbook中,include指令可以跟普通的task混合在一起使用:

    tasks:

    - include: tasks/a.yml
    - include: tasks/b.yml
    1
    2
    3
    4
    如果希望定义一个重启服务的handler,只需要定义一次,可以创建一个handlers.yml文件

    ---
    # this might be in a file like handlers/handlers.yml
    - name: restart apache
    service: name=apache state=restarted
    1
    2
    3
    4
    然后在主playbook中:

    handlers:
    - include: handlers/handlers.yml
    1
    2
    我们可以定义一个顶层playbook:

    - name: this is a play at the top level of a file
    hosts: all
    remote_user: root

    tasks:

    - name: say hi
    tags: foo
    shell: echo "hi..."

    - include: load_balancers.yml
    - include: webservers.yml
    - include: dbservers.yml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    Variables:
    1. 在playbook中直接定义变量:

    - hosts: webservers
    vars:
    http_port: 80
    1
    2
    3
    2. YAML陷阱,开头使用变量

    - hosts: app_servers
    vars:
    app_path: {{ base_path }}/22
    1
    2
    3
    这样是不行的,以变量开头需要将整行用双引号包起来。

    app_path: "{{ base_path }}/22"
    1
    3. 变量单独放到一个文件:

    ---
    - hosts: all
    remote_user: root
    vars:
    favcolor: blue
    vars_files:
    - /vars/external_vars.yml
    1
    2
    3
    4
    5
    6
    7
    变量文件:

    ---
    somevar: somevalue
    password: magic
    1
    2
    3

    条件选择:
    when语句:

    tasks:
    - shell: echo "only on Red Hat 6, derivatives, and later"
    when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6
    1
    2
    3
    在特定情况下运行task

    标准循环

    - name: add several users
    user: name={{ item }} state=present groups=wheel
    with_items:
    - testuser1
    - testuser2
    1
    2
    3
    4
    5

    Roles
    roles会自动加载tasks,handler
    创建roles:

    mkdir nginx # 这里最好就使用roles这个名字
    cd nginx
    ansible-galaxy init nginx
    1
    2
    3
    调用roles的方式:

    ---
    - hosts: webservers
    roles:
    - common
    - webservers
    1
    2
    3
    4
    5
    如果 roles/x/tasks/main.yml 存在, 其中列出的 tasks 将被添加到 play 中
    如果 roles/x/handlers/main.yml 存在, 其中列出的 handlers 将被添加到 play 中
    如果 roles/x/vars/main.yml 存在, 其中列出的 variables 将被添加到 play 中
    如果 roles/x/meta/main.yml 存在, 其中列出的 “角色依赖” 将被添加到 roles 列表中 (1.3 and later)
    所有 copy tasks 可以引用 roles/x/files/ 中的文件,不需要指明文件的路径。
    所有 script tasks 可以引用 roles/x/files/ 中的脚本,不需要指明文件的路径。
    所有 template tasks 可以引用 roles/x/templates/ 中的文件,不需要指明文件的路径。
    所有 include tasks 可以引用 roles/x/tasks/ 中的文件,不需要指明文件的路径。

    最后的项目结构应该是:

    production # inventory file for production servers 关于生产环境服务器的清单文件
    stage # inventory file for stage environment 关于 stage 环境的清单文件

    group_vars/
    group1 # here we assign variables to particular groups 这里我们给特定的组赋值
    group2 # ""
    host_vars/
    hostname1 # if systems need specific variables, put them here 如果系统需要特定的变量,把它们放置在这里.
    hostname2 # ""

    library/ # if any custom modules, put them here (optional) 如果有自定义的模块,放在这里(可选)
    filter_plugins/ # if any custom filter plugins, put them here (optional) 如果有自定义的过滤插件,放在这里(可选)

    site.yml # master playbook 主 playbook
    webservers.yml # playbook for webserver tier Web 服务器的 playbook
    dbservers.yml # playbook for dbserver tier 数据库服务器的 playbook

    roles/
    common/ # this hierarchy represents a "role" 这里的结构代表了一个 "role"
    tasks/ #
    main.yml # <-- tasks file can include smaller files if warranted
    handlers/ #
    main.yml # <-- handlers file
    templates/ # <-- files for use with the template resource
    ntp.conf.j2 # <------- templates end in .j2
    files/ #
    bar.txt # <-- files for use with the copy resource
    foo.sh # <-- script files for use with the script resource
    vars/ #
    main.yml # <-- variables associated with this role
    defaults/ #
    main.yml # <-- default lower priority variables for this role
    meta/ #
    main.yml # <-- role dependencies

    webtier/ # same kind of structure as "common" was above, done for the webtier role
    monitoring/ # ""
    fooapp/ # ""

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39

    Ansible常用模块
    1. ping
    检查指定节点机器是否能联通

    2. yum
    这个模块是RedHat和CentOS作为远端节点的OS的时候,用得最多的包管理工具

    3. apt
    这个模块是ubuntu和Debian作为远端节点的时候用的最多的包管理工具

    deb: 软件包名字,可选
    install_recommends: 默认为true,设置为False代表只下载不安装
    update_cache: yes相当于apt-get update
    name: apt要下载的软件名,指定版本可用name=git=1.6
    state: (present, adsent, latest) present表示为安装,然后是删除,在是安装位最新版本
    4. pip
    安装python库依赖项,必须参数为name或者requirements

    chdir: 执行pip前需要进入的目录
    name: 库名字
    requirements: requirements.txt文件路径,应该是远程系统的本地文件,就可以使用chdir将文件指定为相对定位
    version: 库版本
    extra_args: pip额外参数
    executable: 显式可执行文件或可执行文件的路径名
    virtualenv: 要安装到的virtualenv路径名
    virtualenv_command: 创建虚拟环境
    virtualenv_python: 用于创建虚拟环境的命令或路径名
    state:(present, lastest, absent)
    5. synchronize
    使用rsync同步文件,将主控方目录推送到指定节点的目录下

    delete: 删除不存在的文件
    src: 要同步到目的地的源主机的路径
    dest: 目的地上同步地址
    dest_port: 目的地机上的端口
    mode: push/pull,默认push,本机向远程传文件
    rsync_opts:
    6. copy
    在远程主机上面复制文件

    src: 复制到远程的文件在本地的地址,如果路径以/结尾,只复制目录里面的内容,如果没有,则包含目录在内的整个内容全部复制
    content: 代替src,可以直接设定指定文件的值
    dest: 复制到远程文件的路径
    directory_mode: 目录权限
    force:默认为yes,强制覆盖
    others: 所有file模块里面的选项
    mode: 0644
    7. user

    home:指定用户家目录,需要配合createhome使用
    groups: 指定用户组
    uid:
    password: 用户密码,不能使用明文密码
    name: 指定用户名
    createhome: 是否创建家目录,yes、no
    system: 是否为系统用户
    remove: 当state为absent的时候,remove=yes表示联同家目录一起删除
    state: present, absent
    shell: 指定用户的shell环境
    generate_ssh_key: 生成ssh秘钥
    ssh_key_bits: 指定创建ssh秘钥中的位数
    ssh_key_passphrase: ssh秘钥密码
    ssh_key_file: ssh秘钥文件
    ssh_key_type: ssh秘钥类型
    8. group

    gid: 指定的gid
    name: 指定用户名
    state: present, absent
    system: true,表示创建的是系统组
    9. service

    arguments: 命令选项
    enabled: 是否开机启动 yes
    name: 必选,服务名称
    runlevel: 运行级别
    sleep: restarted之间的间隔
    state: started/stopped/restarted/reloaded
    10. get_url
    用于从http,ftp,https服务器上面上下载文件,类似wget

    sha256sum: 下载后sha256验证
    timeout: 下载超时时间,默认为10s
    url: 下载的url
    url_password, url_username: 如果下载需要提供验证
    dest: 下载到哪里
    headers: 以key:value的格式自定义http标头
    11. file
    用于远程主机上面的文件操作

    force: 强制创建软连接
    group: 文件目录的属组
    mode: 文件目录的权限
    owner: 文件目录的属主
    path: 必选,文件目录的路径
    recurse: 递归的设置文件的属性
    src: 被连接的源文件路径,当state=link的时候
    dest: 被连接到的路径,当state=link的时候
    state: directory 如果目录不存在则创建目录
    file 如果文件不存在则创建
    link 创建软连接
    hard 创建硬链接
    touch 如果文件不存在则创建,如果存在则修改最后修改时间属性
    absent 删除文件目录或者取消连接文件
    # 创建一个目录,如果它不存在
    - file:
    path: /etc/some_directory
    state: directory
    mode: 0755
    1
    2
    3
    4
    5
    12. unarchive
    解压文件

    copy: 解压文件之前,是否现将文件复制到远程主机
    creates: 指定一个文件名,当该文件存在,解压不执行
    dest: 远程主机上解压文件的绝对路径
    list_files: yes会列出压缩包里面的文件
    mode: 解压后文件的权限
    src: 如果copy为yes,需要指定压缩文件的原路径
    group: 解压后文件属组
    owner: 解压后文件的属主
    13. shell

    chdir: 运行命令前切换到此目录
    将阿里云API封装成ansible module例子:
    #!/usr/bin/env python
    #coding=utf-8
    from ansible.module_utils.basic import AnsibleModule
    from aliyunsdkcore.client import AcsClient
    from aliyunsdkcore.request import CommonRequest

    def run_ecs_instance(accessKey, accessSecret, region, ImageId, InstanceType, SecurityGroupId, VSwitchId,
    InternetMaxBandwidthOut, HostName, Password, InternetChargeType, SystemDisk_Size, SystemDisk_Category, Amount, InstanceChargeType, ZoneId):
    client = AcsClient(accessKey, accessSecret, region)

    request = CommonRequest()
    request.set_accept_format('json')
    request.set_domain('ecs.aliyuncs.com')
    request.set_method('POST')
    request.set_protocol_type('https') # https | http
    request.set_version('2014-05-26')
    request.set_action_name('RunInstances')

    request.add_query_param('RegionId', region)
    request.add_query_param('ImageId', ImageId)
    request.add_query_param('InstanceType', InstanceType)
    request.add_query_param('SecurityGroupId', SecurityGroupId)
    request.add_query_param('VSwitchId', VSwitchId)
    request.add_query_param('InternetMaxBandwidthOut', InternetMaxBandwidthOut)
    request.add_query_param('HostName', HostName)
    request.add_query_param('Password', Password)
    request.add_query_param('InternetChargeType', InternetChargeType)
    request.add_query_param('SystemDisk.Size', SystemDisk_Size)
    request.add_query_param('SystemDisk.Category', SystemDisk_Category)
    request.add_query_param('Amount', Amount)
    request.add_query_param('InstanceChargeType', InstanceChargeType)
    request.add_query_param('ZoneId', ZoneId)

    response = client.do_action(request)
    # python2: print(response)
    print(str(response, encoding = 'utf-8'))
    return response

    def ansible_module_builder():
    #
    module_args = dict(
    action = dict(type='str', required=True),
    accessKey = dict(type='str', required=True),
    accessSecret = dict(type='str', required=True),
    region = dict(type='str', required=True),
    ImageId = dict(type='str', required=True),
    InstanceType = dict(type='str', required=True),
    SecurityGroupId = dict(type='str', required=True),
    VSwitchId = dict(type='str', required=True),
    InternetMaxBandwidthOut = dict(type='int', required=True),
    HostName = dict(type='str', required=True),
    Password = dict(type='str', required=True),
    InternetChargeType = dict(type='str', required=True),
    SystemDisk_Size = dict(type='int', required=True),
    SystemDisk_Category = dict(type='str', required=True),
    Amount = dict(type='int', required=True),
    InstanceChargeType = dict(type='str', required=True),
    ZoneId = dict(type='str', required=True)
    )

    module = AnsibleModule(
    argument_spec = module_args,
    supports_check_mode = True,
    )

    if module.params['action'] == 'createEcsInstance':
    result = run_ecs_instance(
    module.params['accessKey'],
    module.params['accessSecret'],
    module.params['region'],
    module.params['ImageId'],
    module.params['InstanceType'],
    module.params['SecurityGroupId'],
    module.params['VSwitchId'],
    module.params['InternetMaxBandwidthOut'],
    module.params['HostName'],
    module.params['Password'],
    module.params['InternetChargeType'],
    module.params['SystemDisk_Size'],
    module.params['SystemDisk_Category'],
    module.params['Amount'],
    module.params['InstanceChargeType'],
    module.params['ZoneId']
    )
    module.exit_json(**result)

    def main():
    ansible_module_builder()

    if __name__ == '__main__':
    main()
    ————————————————

    原文链接:https://blog.csdn.net/qq_43355223/article/details/88111875

    螃蟹在剥我的壳,笔记本在写我,漫天的我落在枫叶上雪花上,而你在想我。 --章怀柔
  • 相关阅读:
    Android系统的Binder机制之一——Service Manager
    Android系统的Binder机制之二——服务代理对象(1)
    电子书
    [ 具体数学 ] 1:递归式与封闭式
    线段树封装
    实验1——顺序表的合并
    配置终端VIM 文件
    编译原理:实验二、集合与线性表操作
    括号匹配检验
    Problem B: KMP算法综合应用余庆
  • 原文地址:https://www.cnblogs.com/lovezhr/p/14725895.html
Copyright © 2020-2023  润新知