1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AnsibleでREST APIリクエストする例

Last updated at Posted at 2020-12-22

AnsibleでREST APIリクエストする方法

Ansibleを使う時、当然Playbookを記述するわけですが、以下の観点からなるべくshellモジュールやcommandモジュールなどのコマンドを記述するモジュールを使わず、その対象機器に特化したモジュールを使えないか検討する必要があります。

  • Playbookとしての冪等性を担保するため
  • 宣言型の記述により、このPlaybookを流したらどういう状態になるか読んでもわかるようにするため

ただ、どうしても最適なモジュールがない場合は、Command系のモジュールの使用を検討することになりますが、対象機器がREST APIのインターフェースを持っている場合は、AnsibleからAPIをリクエストして機器を操作する方法も考えられます。

REST APIリクエストをするモジュール

uriというモジュールを利用する。
例えばGETする場合はこんなTask記述になる。

  tasks:
    - name: Get event list
      uri:
        url: "https://xxxxx/xxxxxx/xxxx" 
        headers:
          Accept: "xxxxxxx"
          Authorization: "xxxxxxxx"
        status_code: 200
        method: GET
        return_content: yes
      register: result_get

指定したURLに対してGETリクエストして、結果をresult_getへ保存する。REST APIは、Webサービスによって認証の仕組み(Tokenの送信)がほとんどの場合必要なので、ヘッダとして付与する。

REST APIリクエストする例

ここでは、超私的なニーズの元、手頃なサービスとしてTimeTreeのAPIを例として取り上げる。

実行環境

  • Ansible 2.9.4

手順

  1. App Consoleへのアクセスする
    TimeTreeの開発者向けApp Consoleアクセスする

  2. Personal Accesss Tokenを作成する
    accessToken.png

  3. 発行されたTokenを保存しておく。

  4. 自分のカレンダーIDを保存しておく。
    自分のカレンダーへアクセスした時のURLの最後の要素がカレンダーID。
    https://timetreeapp.com/calendars/<カレンダーID>
    ここまでで、TimeTreeへAPIでアクセスするために必要な情報として以下が揃った。

    • アクセストークン
    • カレンダーID
  5. AnsibleでAPIリクエスト
    このPlaybookは、指定したカレンダーに対して以下を行う。

    • 直近のデータを取得(デバッグ的に)
    • CSVからカレンダー登録するデータを読み込み
    • APIを使って一括登録
createEvents.yml
- name: create events
  hosts: localhost
  gather_facts: no
  connection: local
  vars:
    access_token: <Access Token>
    calender_id: <CalenderID>

  tasks:
    - name: Get event list
      uri:
        url: "https://timetreeapis.com/calendars/{{ calender_id }}/upcoming_events?timezone=Asia/Tokyo&days=3&include=creator,label,attendees" 
        headers:
          Accept: "application/vnd.timetree.v1+json"
          Authorization: "Bearer {{ access_token }}"
        status_code: 200
        method: GET
        return_content: yes
      register: result_get_events_list
    
    - name: debug
      debug:
        var: result_get_events_list
   
    - name: Read users from CSV file and return a list
      read_csv:
        path: data.csv
      register: data_schedules
      delegate_to: localhost  
  
    - name: create event
      uri:
        url: "https://timetreeapis.com/calendars/{{ calender_id }}/events"
        headers:
          Accept: "application/vnd.timetree.v1+json"
          Authorization: "Bearer {{ access_token }}"
          Content-Type: "application/json"
        body_format: json
        body: '{"data":{"attributes":{"category":"schedule","title":"xx予定","all_day":false,"start_at":"{{ item.date }}T{{ item.startAt }}.000+09:00","start_timezone":"Asia/Tokyo","end_at":"{{ item.date }}T{{ item.endAt }}.000+09:00","end_timezone":"Asia/Tokyo","description":"{{item.description}}"},"relationships":{"label":{"data":{"id":"<CalenderID>,9","type":"label"}}}}}'
        status_code: 201
        method: POST
        return_content: yes
      register: result_create_event
      with_items: "{{ data_schedules.list }}"

    - name: debug
      debug:
        var: result_create_event
data.csv
NO,date,startAt,endAt,description
1,YYYY-MM-DD,hh:mm:ss,hh:mm:ss,zzzzzzzzzzzzzzzz
2,YYYY-MM-DD,hh:mm:ss,hh:mm:ss,zzzzzzzzzzzzzzzz
:

Ansibleで実行

#ansible-playbook createEvents.yml

変数やURL、POSTするデータを全て一つのyamlに記述したのでキレイではないが、手っ取り早く一括API実行ができた。また、データ(CSV)を変えることで同じ手順をミスなく繰り返すことができるようになった。
エンタープライズでの運用では、運用対象がREST APIを持っている(Ansibleのモジュールはない)場合に、このようなデータだけが変わる定型運用を比較的簡単に自動化できる。

超私的なニーズ:
在宅勤務が続き、小学生娘が何時に家に帰ってくるかを把握したいけど学校から配布されるプリントを見るのが面倒だったので。もちろん会社のAnsibleの私的利用は厳禁です。

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?