Ansibleを使ってアリババクラウドリソースを作成する方法

この記事では、**Ansible**を使って**Ansible Alicloudモジュール**を使って**Alibaba Cloud**のリソースを作成する方法を紹介します。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/how-to-provision-alibaba-cloud-resources-with-ansible_594449)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

ソリューションアーキテクト、フィリップ・チョイ著

#はじめに
Ansibleは、市場に出回っている[DevOps](https://www.alibabacloud.com/solutions/devops?spm=a2c65.11461447.0.0.70dc2ccaSYK4sS)ツールの1つであり、開発者や運用者の間で広く採用されています。本ドキュメントでは、Ansibleのプレイブックを利用して[Elastic Compute Service](https://www.alibabacloud.com/product/ecs?spm=a2c65.11461447.0.0.70dc2ccaSYK4sS) (ECS)インスタンスを作成するなど、Ansibleを利用してAlibaba Cloud Resourcesをプロビジョニングする方法を解説します。

#プロビジョニング方法の比較
一般的に、Alicloudはユーザーがクラウドリソースを管理するために、Web Console、CLI、言語固有のSDK、RawAPIの4つの方法を提供しています。それぞれの方法には、使いやすさや自動化機能の面で長所と短所があります。以下のマトリックスでは、それぞれの長所と短所を説明しています。AnsibleはCLIとSDKの中間のようなもので、使いやすさや自動化機能の面でも優れています。

|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|

#Ansibleとは何か、そしてどのようにIaaSとクラウドをサポートしているのか？
AnsibleはIaaSの自動化の分野で広く使われているDevOpsツールの一つです。Ansible を使うことで、システム管理者や開発者はインフラをコードとして維持することができ、VMware のような伝統的なベンダーから Alibaba Cloud のような最新のクラウドベンダーまで、IaaS をサポートしています。以下に、市場における他のクラウドベンダーのサポートにおける Ansible の能力を比較したマトリックスを示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/5e450212-56b2-bc14-841f-79fe73657b38.png)

#テスト環境の設定
環境設定の概要を説明します。それが終わったら、次に例題を実行してansibleでECSインスタンスを作成します。

1、Ansibleをインストール
2、Alicloud ansible-providerをインストール

###Ansible のインストール
詳しくは[公式ドキュメント](http://docs.ansible.com/ansible/latest/intro_installation.html?spm=a2c65.11461447.0.0.70dc2ccaSYK4sS)を参照してください。私の場合は、CentOS 7のサーバーを使ってAnsibleをインストールしています。以下のコマンドで行うことができます。

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

###Alicloud Ansibleモジュールのインストール
デフォルトでは Ansible には Alicloud モジュールが搭載されていないため、Alicloud リソースをプロビジョニングするにはこのモジュールが必要になります。モジュールをインストールするには、[https://github.com/alibaba/ansible-provider](https://github.com/alibaba/ansible-provider?spm=a2c65.11461447.0.0.70dc2ccaSYK4sS) で説明されている手順に従ってください。

次のコマンドを実行して、CentOS 7マシンにモジュールをインストールします。

```
yum -y install python2-pip
pip install ansible_alicloud
```

#例を見てみましょう
###プレイブックの定義
プレイブックは、我々が作成したいリソースを含むテンプレートです。以下のURLからテンプレートの例を見つけることができます： http://philipchoi-test.oss-cn-hongkong.aliyuncs.com/example.yml

###結果の実行
プレイブックを実行するには、次のコマンドを使用します。

```
ansible-playbook $FILENAME.yml
```

ここでシミュレーションをしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/350f9231-8256-9bfb-d1ca-768ec7c41d70.png)

そして、ウェブコンソールからは、インスタンスが作成されていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/73582923-5939-9ca5-3032-1d7a57f982ff.png)

また、プレイブックにあるように、WebサーバのインストールとWebページの作成を定義したので、ページの取得もできるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/76b5e59f-eefc-18cc-6d37-83574db9462e.png)

#プレイブック実行中のコマンドエラー
###NTPタイムラグ
Ansibleのプレイブックを実行しているノードに大きなタイムラグが発生した場合、以下のようなエラーが発生することがあります。この問題を解決するには、タイムラグが発生しないようにntpサーバと時計を同期させてください。

```
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
```

#付録
###プレイブックの例
この例では、ECSインスタンスを1つ作成します(または複数のインスタンスを作成します。プレイブックの "count "変数にどれだけの数を入れたかによります)。ただし、自分で入力する必要があります。

1、アクセスキーとシークレットキーのペア
2、あらかじめセキュリティグループを作成し、セキュリティグループIDを指定する
3、事前に ssh-keypair を作成し、ssh-keypair ID を指定します。
4、あらかじめVPCを作成し、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 }}
```

###VPCを作成するタスク定義例
この例のタスクでは、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 }}'
```

###RDSを作成するタスク定義の例
この例のタスクでは、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
```

###SLBを作成するタスク定義の例
この例のタスクは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 }}'
```

###VPC、RDS、ECSを作成するためのスケルトンの例
1つのプレイブックでVPC、RDS、ECSを作成するためのスケルトンの例（注意：上記の各例を接着剤で接着して1つのプレイブックを作成する必要があります。)

```
- 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 ..
```

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*