在 Cloud Shell 中使用 Ansible 编排配置阿里云资源

简介

Ansible 是一个开源的用于自动执行资源的配置管理和应用程序部署产品。云命令行 Cloud Shell 已经为我们安装、配置完成 Ansible v2.8.5,我们可以直接使用。同时阿里云提供了 Ansible 的 阿里云模块

利用该该模块我们可以通过 Ansible 非常方便管理我们的阿里云资源,同时,我们还可以使用 Ansible 在环境中自动配置资源和部署应用。

本文就介绍了如何使用 Ansible 来管理阿里云资源以及部署应用。

你可以在 tutorial-cli-ansible 中查看本文中对应的 Ansible 配置代码,并通过 git clone 下载到本地执行。

推荐你直接去往 Cloud Shell 体验更直观的交互式教程:使用 Ansible 管理云资源。通过 Cloud Shell 编辑器来查看代码,并在 Cloud Shell 直接执行,而不需要繁琐的本地配置过程。

配置 Ansible

Cloud Shell 供我们免费使用,在其中,我们可以直接使用 Ansible 来管理云资源。Cloud Shell 内置了授权,并且默认配置好了阿里云模块,我们无需进行额外配置。默认 Cloud Shell 会使用临时 AK 帮我们配置好 AK 信息,同时默认 region 为cn-hangzhou

我们也可以如下方式自行配置阿里云模块。

export ALICLOUD_ACCESS_KEY="your_accesskey"

export ALICLOUD_SECRET_KEY="your_accesskey_secret"

export ALICLOUD_REGION="your_region"

如果需要在 Cloud Shell 以外的环境配置 Ansible,可以参考安装和配置Ansible

创建资源

在本文中,我们会通过 Ansible 编排创建 VPC、VSwitch、安全组和 ECS。其中 create.yml playbook 声明了编排配置信息。

- name: Create Resources
  hosts: localhost
  remote_user: root

  roles:
    - vpc
    - vswitch
    - security_group
    - ecs

其中,各资源的详细的配置如下:

  • 变量定义:group_vars/all,定义了 Ansible playbook 部署资源所需要的变量信息,包括 VPC 名称、ECS 镜像等等。

    # common parameters
    alicloud_region: "cn-hangzhou"
    alicloud_zone: "cn-hangzhou-i"
    
    # create vpc parameters
    vpc_cidr: "172.16.0.0/12"
    vpc_name: "Cloudshell_Tutorial_Cli_Ansible"
    vpc_description: "Create a new VPC resource via Ansible example."
    
    # create vswitch parameters
    vswitch_cidr: "172.16.1.0/24"
    vswitch_name: "Cloudshell_Tutorial_Cli_Ansible"
    vswitch_description: "Create a new VSwitch resource via Ansible example."
    
    # create security parameters
    group_name: "Cloudshell_Tutorial_Cli_Ansible"
    group_description: "Create a new security group resource via Ansible example."
    group_inboundRules:
      - ip_protocol: tcp
        port_range: 22/22
        source_cidr_ip: 0.0.0.0/0
        priority: 1
    
      - ip_protocol: tcp
        port_range: 80/80
        source_cidr_ip: 0.0.0.0/0
        priority: 1
    
    # create ECS instance parameters
    image_id: "centos_7_06_64_20G_alibase_20190711.vhd"
    instance_type: "ecs.t5-lc2m1.nano"
    instance_name: "Cloudshell_Tutorial_Cli_Ansible"
    instance_description: "Create a new ECS instance resource via Ansible example."
    host_name: "my-instance-from-ansible"
    password: "Test12345"
    
    allocate_public_ip: True
    internet_charge_type: "PayByTraffic"
    max_bandwidth_in: 200
    max_bandwidth_out: 50
    instance_tags: {created_from: cloudshell-tutorial-cli-ansible}
    
    system_disk_category: "cloud_ssd"
    system_disk_size: 20
    
    number_of_instances: 2
  • VPC:roles/vpc/tasks/main.yml,这里会先查询是否已经存在同名的 VPC,如果已经存在,则不会创建。

    - name: Get the existing vpc
      ali_vpc_facts:
        region: '{{alicloud_region}}'
        vpc_name: '{{vpc_name}}'
      register: vpcs
    
    - name: Create a new alicloud VPC resource
      ali_vpc:
        alicloud_region: '{{ alicloud_region }}'
        state: 'present'
        cidr_block: '{{ vpc_cidr }}'
        vpc_name: '{{ vpc_name }}'
        description: '{{ vpc_description }}'
      when: not vpcs.vpcs
      register: vpc
  • VSwitch:roles/vswitch/tasks/main.yml。VSwitch 创建依赖 VPC,这里会先根据定义的 vpc_name 获取对应 VPC。

    - name: Get the existing vpc
      ali_vpc_facts:
        region: '{{alicloud_region}}'
        vpc_name: '{{vpc_name}}'
      register: vpcs
    
    - name: Create a new alicloud VSwitch resource
      ali_vswitch:
        alicloud_region: '{{ alicloud_region }}'
        alicloud_zone: '{{ alicloud_zone }}'
        state: 'present'
        cidr_block: '{{ vswitch_cidr }}'
        vswitch_name: '{{ vswitch_name }}'
        description: '{{ vswitch_description }}'
        vpc_id: '{{vpcs.vpcs.0.id}}'
      register: vswitch
  • 安全组:roles/security_group/tasks/main.yml

    - name: Get the existing vpc
      ali_vpc_facts:
        region: '{{alicloud_region}}'
        vpc_name: '{{vpc_name}}'
      register: vpcs
    
    - name: Get the existing groups
      ali_security_group_facts:
        region: '{{alicloud_region}}'
        group_name: '{{ group_name }}'
        filters:
          vpc_id: '{{vpcs.vpcs.0.id}}'
      register: sgs
    
    - name: Creating security group
      ali_security_group:
        alicloud_region: '{{ alicloud_region }}'
        state: 'present'
        name: '{{ group_name }}'
        description: '{{ group_description }}'
        vpc_id: '{{vpcs.vpcs.0.id}}'
        rules: '{{ group_inboundRules }}'
      when: not sgs.groups
      register: group
  • ECS:roles/ecs/tasks/main.yml

    - name: Get the existing groups
      ali_security_group_facts:
        region: '{{alicloud_region}}'
        group_name: '{{ group_name }}'
        filters:
          vpc_id: '{{vpcs.vpcs.0.id}}'
      register: sgs
    
    - name: Creating an ECS instance
      ali_instance:
        alicloud_region: '{{ alicloud_region }}'
        alicloud_zone: '{{ alicloud_zone }}'
        image: '{{ image_id }}'
        type: '{{ instance_type }}'
        instance_name: '{{ instance_name }}'
        description: '{{ instance_description }}'
        host_name: '{{ host_name }}'
        password: '{{ password }}'
    
        allocate_public_ip: '{{ allocate_public_ip }}'
        internet_charge_type: '{{ internet_charge_type }}'
        max_bandwidth_in: '{{ max_bandwidth_in }}'
        max_bandwidth_out: '{{ max_bandwidth_out }}'
        instance_tags: '{{ instance_tags }}'
    
        security_groups: ['{{ sgs.groups.0.id }}']
        vswitch_id: '{{ vswitch.vswitch.id }}'
    
        system_disk_category: '{{ system_disk_category }}'
        system_disk_size: '{{ system_disk_size }}'
    
        state: 'present'
        count: '{{ number_of_instances }}'
      when: sgs.groups
      register: instance

更多 Ansible Playbook 的配置,可以参考 Ansible 的 Working With Playbooks

然后,我们就可以执行 create.yml 一键配置好我们编排的资源。

ansible-playbook create.yml

执行完后,可以在对应产品的控制台看到编排创建的资源。比如该示例中默认为我们创建了两台 ECS:

在 Cloud Shell 中使用 Ansible 编排配置阿里云资源

如果出现错误,请检查你的所需服务是否开通,以及你的账户是否实名认证同时账户余额大于 100 元。

动态 Inventory

当我们需要配置资源、部署应用的时候,就需要配置 Ansible Inventory。Ansible 可同时操作属于一个组的多台主机。组和主机之间的关系通过 Inventory 文件配置。Ansible Inventory 分为静态 Inventory 和动态 Inventory。当被管理主机比较少的情况下,直接在静态 Inventory 的 host 文件中管理即可;当主机越来越多,不断变化时,可以通过动态 Inventory 来管理。

阿里云提供了动态 Inventory,我们可以直接使用,通过阿里云动态 Inventory 动态获取指定过滤条件的主机信息。

环境准备

目前阿里云的动态 Inventory 还在被官方集成的过程中,我们需要手动安装依赖。

pip install ansible_alicloud_module_utils

下载与验证

首先我们需要下载阿里云动态 Inventory 文件,并赋予其可执行权限

wget https://raw.githubusercontent.com/alibaba/ansible-provider/master/contrib/inventory/alicloud.py;

chmod +x alicloud.py

同时,下载配套的配置文件

wget https://raw.githubusercontent.com/alibaba/ansible-provider/master/contrib/inventory/alicloud.ini

我们可以执行 Inventory 文件来验证配置。

./alicloud.py --list

执行完后,会返回所有地域的 Inventory 信息。其中对应的配置文件为 alicloud.ini,我们可以编辑 alicloud.ini 文件获取指定 Region 的信息。除此之外,还可通过 alicloud.ini 文件中的 instance_filters 过滤所有的主机信息。

需要注意的是,默认的 alicloud.ini 配置中,是使用 ECS 的 instance_id 作为 hostname 的,在 Ansible 使用时,会出现这个 hostname unreachable 的问题,因此我们可以手动将 alicloud.ini 中 hostname_variable = instance_id 这一行注释掉,注释掉后,会使用 ECS ip 作为 hostname

我们可以通过 Ansible ping 模块来验证和之前创建的两台 ECS 实例的连通性

ansible -i ./alicloud.py tag_created_from_cloudshell_tutorial_cli_ansible -m ping -u root -k

其中 tag_created_from_cloudshell_tutorial_cli_ansible 表示我们根据 created_from_cloudshell_tutorial_cli_ansible 的 tag 的过滤 ecs。执行命令后提示输入 SSH 密码,编排资源时,示例中默认设置的密码为:Test12345。结果如下所示:

在 Cloud Shell 中使用 Ansible 编排配置阿里云资源

部署应用

通过 Ansible 我们可以配置资源并部署应用,本文会部署 Nginx 到前文我们创建的 ECS 中。deploy.yml playbook 声明了部署配置信息。

- name: Deploy
  hosts: tag_created_from_cloudshell_tutorial_cli_ansible
  remote_user: root
  tasks:
      - name: install nginx
        yum: name=nginx state=present
      - name: start nginx
        service: name=nginx state=started

其中 tasks 中会安装并启动 Nginx,同时配置 hosts: tag_created_from_cloudshell_tutorial_cli_ansible,根据 created_from_cloudshell_tutorial_cli_ansible 的 tag 来过滤 ecs。执行命令后提示输入 SSH 密码,编排资源时,示例中默认设置的密码为:Test12345

ansible-playbook -i ./alicloud.py deploy.yml -u root -k

执行结果如下所示:

在 Cloud Shell 中使用 Ansible 编排配置阿里云资源

执行完后,Nginx 已经成功在我们的 ECS 实例上安装并启动,我们可以访问该 ECS 的公网 IP 查看。

在 Cloud Shell 中使用 Ansible 编排配置阿里云资源

销毁资源

通过 Ansible 也可以销毁资源。其中 destory.yml playbook 声明了销毁资源的配置信息。

- name: Destroy Resources
  hosts: localhost
  remote_user: root

  tasks:
    - name: Get the existing instances
      ali_instance_info:
        alicloud_region: '{{ alicloud_region }}'
        alicloud_zone: '{{ alicloud_zone }}'
        instance_names:
          - '{{ instance_name }}'
      register: instances

    - name: Delete the existing instances
      ali_instance:
        alicloud_region: '{{ alicloud_region }}'
        alicloud_zone: '{{ alicloud_zone }}'
        instance_ids: '{{ instances.ids }}'
        force: true
        state: absent
      when: instances.ids

    - name: Get the existing vpc
      ali_vpc_facts:
        region: '{{alicloud_region}}'
        vpc_name: '{{vpc_name}}'
      register: vpcs

    - name: Get the existing groups
      ali_security_group_facts:
        region: '{{alicloud_region}}'
        filters:
          vpc_id: '{{vpcs.vpcs.0.id}}'
      when: vpcs.vpcs
      register: sgs

    - name: Delete the existing security groups
      ali_security_group:
        region: '{{ alicloud_region }}'
        group_name: '{{ group_name }}'
        state: absent
      when: sgs.ids

    - name: Get the existing vswitches
      ali_vswitch_facts:
        region: '{{alicloud_region}}'
        filters:
          vpc_id: '{{vpcs.vpcs.0.id}}'
      when: vpcs.vpcs
      register: vsws

    - name: Delete the existing vswitch
      ali_vswitch:
        alicloud_region: '{{ alicloud_region }}'
        alicloud_zone: '{{ alicloud_zone }}'
        cidr_block: '{{ vswitch_cidr }}'
        vpc_id: '{{vpcs.vpcs.0.id}}'
        state: absent
      when: vsws.vswitches

    - name: Delete the existing vpc
      ali_vpc:
        alicloud_region: '{{ alicloud_region }}'
        vpc_name: '{{ vpc_name }}'
        cidr_block: '{{ vpc_cidr }}'
        state: absent
      when: vpcs.vpcs

我们可以执行以下命令来销毁前文创建的资源。

ansible-playbook destory.yml

总结

利用 Ansible 可以方便的编排和配置我们的阿里云资源,更多的交互式教程案例,可以参考开放平台开发者实验室。同时你也可以访问 Cloud Shell 帮助文档了解更多 Cloud Shell 的信息。

上一篇:较老版本的AFNetworking使用心得


下一篇:js 基础对象二