GNU/Linux >> Linux の 問題 >  >> Linux

Ansibleを使用してWebエンドポイントと対話する

私は常にAnsibleに関係する賢いことを探しています。 HTTPベースのアプリケーションプログラミングインターフェース(API)を活用するツールやサービスが非常に多いため、AnsibleのAPI駆動型サービスとプログラムでやり取りすることが貴重な機能であることは明らかです。これは高度な機能のように聞こえるかもしれませんが、この記事では、単純な環境でもAnsibleのURIモジュールのパワーとシンプルさからどのように利益を得ることができるかを示すユースケースを紹介します。

単純なエンドポイントとの対話

まず、AnsibleのHTTP機能を活用して、ウェブサーバーのアップグレード中にインテリジェントな決定を行うプレイブックについて説明します。以下のプレイブック:

  1. メンテナンススクリプトを実行します。
  2. ヘルスチェックAPIエンドポイントがHTTP503サービスを一時的に利用できないを返すことを確認します メッセージ。
  3. スクリプトを実行してアプリケーションをアップグレードします。
  4. メンテナンス後のスクリプトを実行して、ウェブサーバーに通常の応答を再開するように指示します。
  5. ヘルスチェックAPIを再チェックして、 200 OKで応答していることを確認します 。

プレイブックは次のとおりです:

---

- hosts: all
  tasks:
    - name: Run maintenance start script
      command:
        cmd: /usr/local/sbin/start_maintenance.sh

    - name: Confirm that 503 Unavailable response is returned
      uri:
        url: "http://{{ ansible_host }}/api/v1/healthcheck"
        status_code: 503

    - name: Update application
      command:
        cmd: /usr/local/sbin/update_app.sh

    - name: Run maintenance end script
      command:
        cmd: /usr/local/sbin/end_maintenance.sh

    - name: Confirm that 200 OK response is returned
      uri:
        url: "http://{{ ansible_host }}/api/v1/healthcheck"
        status_code: 200

AnsibleのURIモジュールを使用して/api/v1/healthcheckにアクセスしています サーバー上。最初のURI呼び出しでは、HTTP 503が必要です。 サーバーはメンテナンスモードであり、要求を処理していない必要があるため、返されるステータスコード。アップグレード後、URI呼び出しはHTTP 200を想定しています ステータスコード。ウェブサーバーが再び正常であることを示します。

この単純なアプローチにより、私のプレイブックの安全性が向上します。サーバーがメンテナンスモードに入ることができない場合、Ansibleはパッチを適用しません:

fsh$ ansible-playbook -i inventory.ini playbook-healthcheck.yml

PLAY [all] ***********************************************************************************

TASK [Gathering Facts] ***********************************************************************
ok: [nyc1-apiserver-1.example.com]

TASK [Run maintenance start script] **********************************************************
changed: [nyc1-apiserver-1.example.com]

TASK [Confirm that 503 Unavailable response is returned] *************************************
fatal: [nyc1-apiserver-1.example.com]: FAILED! => changed=false 
  connection: close
  content: ''
  content_length: '0'
  content_type: application/octet-stream
  cookies: {}
  cookies_string: ''
  date: Fri, 11 Sep 2020 18:35:08 GMT
  elapsed: 0
  msg: 'Status code was 200 and not [503]: OK (0 bytes)'
  redirected: false
  server: nginx
  status: 200
  url: http://nyc1-apiserver-1.example.com/api/v1/healthcheck

PLAY RECAP ***********************************************************************************
nyc1-apiserver-1.example.com : ok=2    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0  

パッチ適用後にサーバーが正しく復旧しない場合、Ansibleはエラーで失敗します:

fsh$ ansible-playbook -i inventory.ini playbook-healthcheck.yml

PLAY [all] ***********************************************************************************

TASK [Gathering Facts] ***********************************************************************
ok: [nyc1-apiserver-1.example.com]

TASK [Run maintenance start script] **********************************************************
changed: [nyc1-apiserver-1.example.com]

TASK [Confirm that 503 Unavailable response is returned] *************************************
ok: [nyc1-apiserver-1.example.com]

TASK [Update application] ********************************************************************
changed: [nyc1-apiserver-1.example.com]

TASK [Run maintenance end script] ************************************************************
changed: [nyc1-apiserver-1.example.com]

TASK [Confirm that 200 OK response is returned] **********************************************
fatal: [nyc1-apiserver-1.example.com]: FAILED! => changed=false 
  connection: close
  content: |-
    <html>
    <head><title>503 Service Temporarily Unavailable</title></head>
    <body>
    <center><h1>503 Service Temporarily Unavailable</h1></center>
    <hr><center>nginx</center>
    </body>
    </html>
  content_length: '190'
  content_type: text/html; charset=utf-8
  date: Fri, 11 Sep 2020 18:55:01 GMT
  elapsed: 0
  msg: 'Status code was 503 and not [200]: HTTP Error 503: Service Temporarily Unavailable'
  redirected: false
  server: nginx
  status: 503
  url: http://nyc1-apiserver-1.example.com/api/v1/healthcheck

PLAY RECAP ***********************************************************************************
nyc1-apiserver-1.example.com : ok=5    changed=3    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

これらは、ほとんどすべてのプレイブックに組み込むことができる簡単なチェックであり、破壊的な作業を実行する前に安全性の保証を強化したり、破壊的な作業が成功したと呼ぶ前に成功したことを確認したりできます。

返されたJSONの解析

前の例は、単純なHTTPステータスベースのヘルスチェックに最適です。ただし、通常は、ウェブエンドポイントからデータを取得してから、返されたデータを処理する必要があります。例:公開されたエンドポイントを介してアプリケーションのバージョンを確認し、最新でない場合にのみ更新を実行したい場合はどうすればよいですか?

私のデモアプリケーションには、まさにそのようなエンドポイントがあります。照会すると、アプリケーションの現在のバージョンが返されます。

fsh$ http nyc1-apiserver-1.example.com/api/v1/appVersion
HTTP/1.1 200 OK
Accept-Ranges: bytes
Connection: keep-alive
Content-Length: 24
Content-Type: application/json
Date: Fri, 11 Sep 2020 18:36:15 GMT
ETag: "5f5bc33b-18"
Last-Modified: Fri, 11 Sep 2020 18:34:35 GMT
Server: nginx

{
    "appVersion": "1.0.1"
}

:実行したHTTPコマンドに興味がありますか? HTTPieに関する私の仲間のsudoerJonathanRoemerの記事をチェックしてください。

このエンドポイントから返されたJSONを使用して、Ansibleプレイブックで決定を下すことができます。このハンドブックの以前のバージョンでは、常にアプリケーション更新スクリプトが実行されていました。ただし、希望するバージョン要件を満たしていない場合にのみアプリケーションを更新することで、これを改善できます。


---

- hosts: all
  vars:
    desired_app_version: "1.0.1"
  tasks:

    - name: Check API version
      uri:
        url: "http://{{ ansible_host }}/api/v1/appVersion"
      register: api_version_result

    - name: Perform maintenance tasks
      block:
        - name: Run maintenance start script
          command:
            cmd: /usr/local/sbin/start_maintenance.sh

        - name: Confirm that 503 Unavailable response is returned
          uri:
            url: "http://{{ ansible_host }}/api/v1/healthcheck"
            status_code: 503

        - name: Update application
          command:
            cmd: /usr/local/sbin/update_app.sh

        - name: Run maintenance end script
          command:
            cmd: /usr/local/sbin/end_maintenance.sh

        - name: Confirm that 200 OK response is returned
          uri:
            url: "http://{{ ansible_host }}/api/v1/healthcheck"
            status_code: 200

        - name: Check API version after updates
          uri:
            url: "http://{{ ansible_host }}/api/v1/appVersion"
          register: updated_api_version_result
          failed_when: updated_api_version_result['json']['appVersion'] != desired_app_version
      when: api_version_result['json']['appVersion'] != desired_app_version

このプレイブックでは、いくつかの便利なAnsibleの概念を紹介しています。まず、URIモジュールが/api/v1/appVersionに到達していることがわかります。 APIエンドポイントであり、このURI呼び出しの出力を変数に登録します。更新タスクはブロックに移動されました。これにより、タスクを論理的にグループ化できます。 whenの追加 句を指定すると、/api/v1/appVersionによって返されるように、現在のアプリのバージョンが目的のアプリのバージョンと異なる場合にのみ、このブロックが実行されます。 終点。最後に、更新プロセスに追加のチェックを追加しました。更新が実行されたら、/api/v1/appVersionをもう一度呼び出します。 エンドポイントは、更新が成功し、現在のアプリのバージョンが目的のバージョンと一致することを確認します。これはfailed_when構文を使用しており、タスクの特定の失敗基準を定義できます。

このAnsibleブロックロジックは平易な言葉で表現され、次のように述べています。「アプリの現在のバージョンが目的のバージョンのアプリと一致しない場合にのみ、アプリケーションのメンテナンススクリプトとインストールスクリプトを実行してください。更新が完了したら、アプリが実際に更新されていることを確認してください。」

ほんの数行のAnsibleコードを使用して、APIエンドポイントから返されたJSONを使用して、プレイブックでインテリジェントな決定を行うための強力でシンプルな方法を作成しました。

認証されたエンドポイントとの対話

これまで、認証を必要としないAPIエンドポイントとのやり取りについて説明してきました。ただし、おそらく、APIトークンなどの何らかの種類の認証を必要とするAPIとのやり取りに最も慣れているでしょう。 URIモジュールは、HTTPリクエストのヘッダーと本文を設定することでこれをサポートします。

[お楽しみいただけるかもしれません:自動化を容易にするための9つのAnsibleガイド]

監視システムの各ホストでアラートを無効にしてから再度有効にすることで、メンテナンスプレイブックをさらに一歩進めることができます。これには、 POSTを送信する必要があります 監視サーバー上のAPIエンドポイントへのリクエスト。リクエストには、JSONでエンコードされた本文内にAPIトークンとホストが含まれている必要があります。 Ansibleはこれを簡単にします。これが最終的なプレイブックです:

---

- hosts: all
  vars:
    desired_app_version: "1.0.1"
    api_token: "8897e9a6-b10c-42c8-83a2-c83e9c8b6703"
  tasks:

    - name: Check API version
      uri:
        url: "http://{{ ansible_host }}/api/v1/appVersion"
      register: api_version_result

    - name: Perform maintenance tasks
      block:
        - name: Disable host in monitoring
          uri:
            url: "http://nyc1-monitoring-1.example.com/api/v1/startMaintenance"
            method: POST
            headers:
              X-API-KEY: "{{ api_token }}"
            body_format: json
            body:
              host: "{{ ansible_host }}"

        - name: Run maintenance start script
          command:
            cmd: /usr/local/sbin/start_maintenance.sh

        - name: Confirm that 503 Unavailable response is returned
          uri:
            url: "http://{{ ansible_host }}/api/v1/healthcheck"
            status_code: 503

        - name: Update application
          command:
            cmd: /usr/local/sbin/update_app.sh

        - name: Run maintenance end script
          command:
            cmd: /usr/local/sbin/end_maintenance.sh

        - name: Confirm that 200 OK response is returned
          uri:
            url: "http://{{ ansible_host }}/api/v1/healthcheck"
            status_code: 200

        - name: Check API version after updates
          uri:
            url: "http://{{ ansible_host }}/api/v1/appVersion"
          register: updated_api_version_result
          failed_when: updated_api_version_result['json']['appVersion'] != desired_app_version

        - name: Re-enable host in monitoring
          uri:
            url: "http://nyc1-monitoring-1.example.com/api/v1/stopMaintenance"
            method: POST
            headers:
              X-API-KEY: "{{ api_token }}"
            body_format: json
            body:
              host: "{{ ansible_host }}"

      when: api_version_result['json']['appVersion'] != desired_app_version

現在、URIモジュールを使用してHTTP POSTを送信しています リクエスト(デフォルトの GET の代わりに) リクエスト)/api/v1/startMaintenanceへ および/api/v1/stopMaintenance nyc1-monitoring-1.example.comのエンドポイント 。これらのリクエストのヘッダーには監視サーバーのAPIトークンが含まれており、サーバーのホスト名は本文に含まれています。いずれかのリクエストが200以外で失敗した場合 ステータスコードの場合、Ansibleプレイブック全体が失敗します。

:実際には、APIトークンをプレイブックに直接配置するのではなく、AnsibleVaultなどを使用してAPIトークンを保存することをお勧めします。

この最後の一連のタスクにより、アップグレードワークフローを完全に自動化できます。バージョンチェックの実行、外部モニタリングとの対話によるシステムのアラートの無効化、パッチ適用の前後にサーバーが正しいHTTPステータスコードを返すことの確認です。これで、システムでアップグレードを実行するときに実行する一般的な手順の多くを自動化するエンドツーエンドのワークフローができました。

[Ansibleについてもっと知りたいですか? RedHatから無料の技術概要コースを受講してください。 Ansible Essentials:自動化の技術概要のシンプルさ。 ]

まとめ

この記事は、認証されていないAPIエンドポイントに対して基本的なWebチェックを実行する簡単なプレイブックから始まりました。 JSON応答を解析し、HTTPリクエストにカスタムヘッダーと本文のコンテンツを設定することで、認証されたAPIエンドポイントとやり取りする方法についても説明しました。 Ansibleを使用すると、Webサービスとのやり取りが簡単になります。このタイプのアプローチは、単純な環境でも使用できると確信しています。

詳細を学び、自分自身に挑戦したい場合は、次のアイデアを自分で実装してください。

  • URIモジュールを使用して、お気に入りのAPIベースのWebサービスと対話します。
  • クライアント証明書を使用して認証を行う方法を理解できるかどうかを確認してください。
  • Ansibleを使用してウェブサイトにフォームを送信する方法を学びます。

Linux
  1. rsyncを使用してWebサイトをミラーリングする

  2. FTPでWgetを使用してWebサイトを再帰的にダウンロード/移動する

  3. Ansibleを使用したマルチパス仮想マシン

  1. SSHを使用したSOCKSWebプロキシの作成

  2. Ansibleを使用してLinuxユーザーを作成する方法

  3. Curlを使用してWebリクエストを自動化しますか?

  1. Curlを使用したWebページのヘルスチェック?

  2. Linuxでのファイルパーミッションと例

  3. ddを使用してFFでファイルをパディングする方法は?