×
Community Blog How to Provision Alibaba Cloud Resources with Ansible

How to Provision Alibaba Cloud Resources with Ansible

In this article, we will show you how to use Ansible to create Alibaba Cloud resources through the Ansible Alicloud Module.

By Philip Choi, Solutions Architect

This article will show you how to create Alibaba Cloud resources using Ansible through the Ansible Alicloud Module.

Introduction

Ansible is one of the DevOps tools that is available in the market and widely being adopted among developer and operators. This document will describe how one can provision Alibaba Cloud Resources by using Ansible, such as creating an Elastic Compute Service (ECS) instance by using an Ansible playbook.

Comparison of Provisioning Methods

In general, Alicloud provides 4 ways for user to manage their cloud resources, namely Web Console, CLI, language-specific SDK, and RawAPI. Each of the method has its own pros and cons in terms of user-friendliness or automation capability. The following matrix describe each of the pros and cons of each methods. Ansible is something between CLI and SDK in terms of user friendliness as well as automation capability.

Medium User friendliness Automation Capability Product Coverage
Console Anyone, intuitive No way All
CLI Probably OK, for experienced sysadmin Works, but not perfect ECS/VPC/RDS/SLB/Storage
Ansible Probably OK, for experienced sysadmin who can script Better than CLI and more manageable ECS/VPC/RDS/SLB/Storage
SDK Probably OK, for experienced developer Flexible, but quite a bit of effort All
Raw API Not user friendly at all Very capable, but extensive effort All

What Is Ansible and How Does It Support IaaS and the Cloud?

As mentioned Ansible is one of the DevOps tools being widely used in the IaaS automation space. It allows sysadmins or developers to maintain their infrastructure as a code, supporting IaaS from traditional vendors like VMware to modern cloud vendors like Alibaba Cloud. Below is a comparison matrix on Ansible's capability in supporting other cloud vendors in the market.

4

Setting Up the Test Environment

Here is the overview of setting up the environment. After it is done, we can then run the example to create a ECS instance through ansible.

  1. Have Ansible installed
  2. Have Alicloud ansible-provider installed

Install Ansible

Please refer to the official documentation for details. In my case, I am using a CentOS 7 server to install the Ansible. You can do so with the following command.

yum -y install \ https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install ansible

Install Alicloud Ansible module

By default Ansible doesn't ship with Alicloud module, in order to provision Alicloud resources we will need this module. To install the module, please follow the steps documented in https://github.com/alibaba/ansible-provider

Run the following command to install the module on a CentOS 7 machine.

yum -y install python2-pip
pip install ansible_alicloud

Go through a Deployment Example

Define the Playbook

Playbook is the template which contains the resources that we want to create. You can find the example template from below url: http://philipchoi-test.oss-cn-hongkong.aliyuncs.com/example.yml

Run the Results

To run the playbook, use the following command

ansible-playbook $FILENAME.yml

Here is a simulation run.

1

And from the web console, we can see that the instance is created.

2

Also, as from our playbook, we defined installation of web server and creation of web page, we can now fetch the page too.

3

Command Error during Playbook Execution

NTP Time Lag

In case the node running the Ansible playbook have a major time lag, the following error may occur. To solve the problem, sync the clock with ntp server to avoid any time lag.

TASK [make sure ingress port 22 and 80 are allowed] ******************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Error in get_all_security_groups: ECSResponseError: , HTTP Status: 400 Error:IllegalTimestamp The input parameter \"Timestamp\" that is mandatory for processing this request is not supplied. RequestID: 9FAC5E19-46E3-4A72-A879-422A691585BC,\nNone"}
    to retry, use: --limit @/root/test.retry

Appendix

Example Playbook

This example will create one ECS instance (or multiple instance, depends how much number you put into the "count" variable in the playbook),. However, you will need to input your own:

  1. Access key and secret key pair
  2. Create the security group in advance and provide the security-group ID
  3. Create the ssh-key pair in advance and provide the ssh-keypair ID
  4. Create the VPC in advance and provide the vswitch ID
- name: basic provisioning example
  hosts: localhost
  vars:
    alicloud_access_key: YOUR_ACCESS_KEY_HERE # replace it with your Alicloud Access Key
    alicloud_secret_key: YOUR_SECRET_KEY_HERE # replace it with your Alicloud Secret Key
    alicloud_region: cn-hongkong # replace it with the region you plan to use
    image: centos_7_02_64_20G_alibase_20170818.vhd # replace it with the image to use
    instance_type: ecs.n4.small # replace it with the flavor type
    vswitch_id: vsw-YOUR_VSWITCH_ID_HERE # replace it with the Vswitch ID
    assign_public_ip: True # set to false in case you dont need public ip
    max_bandwidth_out: 10
    host_name: PREFERRED_HOSTNAME # hostname
    system_disk_category: cloud_efficiency
    system_disk_size: 50
    internet_charge_type: PayByTraffic
    group_id: sg-YOUR_SG_ID_HERE # replace with the security-group-id
    sg_action: join
    key_name: SSH_KEY_NAME # replace with the ssh key
    count: 2 # number of instances to create
    user_data: |
      #!/bin/sh
      yum -y install httpd
      systemctl start httpd
      echo "Server Up at $(date -R)!" | tee /var/www/html/index.html

  tasks:
    - name: make sure ingress port 22 and 80 are allowed
      alicloud_security_group:
        alicloud_access_key: '{{ alicloud_access_key }}'
        alicloud_secret_key: '{{ alicloud_secret_key }}'
        group_id: '{{ group_id }}'
        alicloud_region: '{{ alicloud_region }}'
        rules:
          - ip_protocol: tcp
            port_range: 22/22
            source_cidr_ip: '0.0.0.0/0'
            policy: accept
          - ip_protocol: tcp
            port_range: 80/80
            source_cidr_ip: '0.0.0.0/0'
            policy: accept

    - name: launch ECS instance in VPC network
      alicloud_instance:
        alicloud_access_key: '{{ alicloud_access_key }}'
        alicloud_secret_key: '{{ alicloud_secret_key }}'
        alicloud_region: '{{ alicloud_region }}'
        image: '{{ image }}'
        system_disk_category: '{{ system_disk_category }}'
        system_disk_size: '{{ system_disk_size }}'
        instance_type: '{{ instance_type }}'
        vswitch_id: '{{ vswitch_id }}'
        assign_public_ip: '{{ assign_public_ip }}'
        internet_charge_type: '{{ internet_charge_type }}'
        max_bandwidth_out: '{{ max_bandwidth_out }}'
        group_id: '{{ group_id }}'
        key_name: '{{ key_name }}'
        host_name: '{{ host_name }}'
        #password: '{{ password }}'
        user_data: '{{ user_data }}'
        count: '{{ count }}'
        instance_tags:
          Name: created_through_ansible
      register: status

    - name: Poll instance information
      alicloud_instance_facts:
        alicloud_access_key: '{{ alicloud_access_key }}'
        alicloud_secret_key: '{{ alicloud_secret_key }}'
        alicloud_region: '{{ alicloud_region }}'
        instance_ids: '{{ status.instance_ids }}'
      register: all_instances

    - set_fact:
        instances_info: []

    - set_fact:
        instances_info: "{{ instances_info + [ { 'id': item.id, 'host_name': item.host_name, 'public_ip': item.public_ip }] }}"
      with_items: "{{ all_instances.instances }}"
      no_log: true
      
    - name: print instance information
      debug:
        msg: "ECS instance {{ item.host_name }} created, id: {{ item.id }}. IP: {{ item.public_ip }} . URL http://{{ item.public_ip }}/"
      with_items: "{{ instances_info }}

Example Task Definition to Create VPC

This example task will create a VPC.

- name: create vpc
  hosts: localhost
  connection: local
  vars:
   alicloud_access_key: YOUR_ACCESS_KEY_HERE # replace it with your Alicloud Access Key
   alicloud_secret_key: YOUR_SECRET_KEY_HERE # replace it with your Alicloud Secret Key
    alicloud_region: cn-hongkong
    state: present
    cidr_block: 192.168.0.0/16
    vpc_name: Demo_VPC
    description: Demo VPC
  tasks:
    - name: create vpc
      alicloud_vpc:
        alicloud_region: '{{ alicloud_region }}'
        state: '{{ state }}'
        cidr_block: '{{ cidr_block }}'
        vpc_name: '{{ vpc_name }}'
        description: '{{ description }}'

Example Task Definition to Create RDS

This example task will create a RDS.

- name: create rds instance
  hosts: localhost
  vars:
    alicloud_access_key: <your-alicloud-access-key-id>
    alicloud_secret_key: <your-alicloud-access-secret-key>
    alicloud_region: cn-beijing
  tasks:
    - name: create instance
      alicloud_rds_instance:
        alicloud_access_key: '{{ alicloud_access_key }}'
        alicloud_secret_key: '{{ alicloud_secret_key }}'
        alicloud_region: '{{ alicloud_region }}'
        state: present
        engine: MySQL
        engine_version: 5.6
        instance_class: rds.mysql.t1.small
        instance_storage: 30
        instance_net_type: Internet
        security_ips: 10.23.12.24/24
        instance_charge_type: Postpaid

Example Task Definition to Create SLB

This example task will create a SLB.

- name: create server load balancer
  hosts: localhost
  connection: local
  vars:
    alicloud_region: cn-beijing
    alicloud_access_key: <your-alicloud-access-key-id>
    alicloud_secret_key: <your-alicloud-access-secret-key>
    load_balancer_name: demo_slb
    internet_charge_type: paybytraffic
    state: present
  tasks:
    - name: create server load balancer
      alicloud_slb_lb:
        alicloud_access_key: '{{ alicloud_access_key }}'
        alicloud_secret_key: '{{ alicloud_secret_key }}'
        alicloud_region: '{{ alicloud_region }}'
        load_balancer_name: '{{ load_balancer_name }}'
        internet_charge_type: '{{ internet_charge_type }}'
        state: '{{ state }}'

Example Skeleton to Create VPC, RDS and ECS

An example skeleton to create VPC, RDS and ECS in one playbook (Notes, you will need to glue each of the above examples together to form one playbook)

- name: create server stack
  hosts: localhost
  connection: local
  vars:
    alicloud_region: cn-beijing
    alicloud_access_key: <your-alicloud-access-key-id>
    alicloud_secret_key: <your-alicloud-access-secret-key>
    .. line skipped ..
  tasks:
    - name: create VPC
      alicloud_vpc:
        .. line skipped ..

    - name: create RDS
      alicloud_rds_instance:
        .. line skipped ..

    - name: create ECS
      alicloud_instances:
        .. line skipped ..
2 1 1
Share on

Alibaba Clouder

2,599 posts | 763 followers

You may also like

Comments

Raja_KT March 18, 2019 at 4:31 pm

Good sharing. Handy for all to copy and paste the code and make changes if necessary.

5234553447704699 April 1, 2019 at 9:40 am

Hi I keep getting this error when trying to provision via Ansible payload_myWKe2/__main__.py", line 561, in mainnAttributeError: 'ECSConnection' object has no attribute 'get_all_security_groups'n", "module_stdout": "", "msg": "MODULE FAILUREnSee stdout/stderr for the exact error", "rc": 1