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

AnsiblePlaybookの作成方法

数週間前、私はAnsibleを使用して、サポートする複数の組織の管理タスクを簡素化し始めました。さらに、私は特に、8台または9台のホストからなる自分のフリートの管理を簡素化したいと考えていました(正確な数は頻繁に変更されます)。 Linuxを使い始めてから、Bashスクリプトを使用してすべての自動化を行ってきました。スクリプトを使用して、他の更新自動化スクリプト、システムおよびユーザー構成ファイル、Fedoraの新しいリリースへのアップグレード、および新しいFedoraリリースへの更新の配布を自動化しました。そして、これには、1時間ごとに発生するような小さなアドホックタスクがすべて含まれているわけではありません。

スクリプトは、私の管理の自動化において引き続き重要な役割を果たします。ただし、Ansibleは多くのタスクを引き継ぐことができ、複雑なスクリプトよりもはるかに優れているように見えます。 プレイブックがすべてです 、そしてこの記事では、システムの違いを考慮しながらシステムの更新を実行できるものを作成します。

最近、Ansibleを使用した最初の日について書きました。その記事をまだ読んでいない場合は、この記事を続ける前に読んでおくことをお勧めします。この記事は、Ansibleの使用について非常に基本的な知識があることを前提としています。上記のリンクで私の記事を読んだことがあれば、このテキストを問題なくたどることができるはずです。

この記事は2部に分かれていますので、必ず後半をお読みください。このセクションでは、いくつかの重要なAnsibleの概念と用語を定義し、コメントについて説明し、プレイブックの最初のプレイを実装します。パート2は、残りの2つの演劇、いくつかのフォローアップ情報、および私のリソースリストに続きます。

この記事のプレイブックでは、デフォルトの組み込みモジュール以外のAnsibleモジュールまたはコレクションをインストールする必要はありません。このプレイブックはAnsible2.9.14でテストされています。

[読者も気に入りました:リポジトリを追加し、Ansibleの方法でパッケージをインストールします]

プレイブックとは何ですか?

この記事を書いている間、私は今年の仮想AnsibleFestのいくつかのセッションも見ていました。私が見ている間、私は自分自身のプレイブックの説明を作成しました。それは私にとって意味のあるものです。この説明には、いくつかのプレゼンターからのプレイブックの知恵の一部と、私が読んだいくつかの本やブログ投稿が含まれています。

これが私の定義です:

Ansible Playbookは、1台以上のコンピューターの望ましい状態を人間が作成した説明です。 Ansibleはプレイブックを読み取り、コンピューターの実際の状態をプレイブックで指定された状態と比較し、それらのコンピューターをプレイブックに記載されている状態に適合させるために必要なタスクを実行します。

更新

最新のLinuxホストにアップデートをインストールすることはほぼ一定の作業であり、継続的に行われるセキュリティ修正と機能改善の数によって重要になっています。 kernel、glibc、systemdなどの特定のソフトウェアが更新された場合は、ホストも再起動する必要があります。マニュアルページデータベースの更新など、いくつかの追加タスクも実行する必要があります。

クールなスクリプトを使用して更新のインストールを自動化しましたが、一部のホストは他のホストとは少し異なる方法で処理する必要があります。たとえば、ファイアウォールと電子メール/ Web / DHCP/DNSサーバーを同時に更新したくありません。サーバーが再起動すると、ファイアウォールは自身の更新を続行するために必要な情報を取得できず、ネットワーク内の他のホストも取得できません。ファイアウォールがダウンすると、外部Fedoraリポジトリーへのアクセスが私のサーバーと他のすべての内部ホストに失われます。つまり、他のホストで更新を開始する前に、これら2つのホストが再起動するのを待つ必要があります。

そのため、ファイアウォールでスクリプトを開始して終了するのを待ってから、サーバーに移動して終了するのを待ってから、小さなコマンドラインプログラムを実行して更新スクリプトを順番に実行することで、これらの更新を実行していました。残りのホスト。これらの依存関係をスクリプトに書き込むこともできましたが、Ansibleを使用した最初の数日間は、Ansibleにすでにこれらの機能があり、タスクをはるかに簡単にする多くの機能があることを示しました。本当に—はるかに簡単です。そして全体的に速く、私からの介入はありません。

Ansible戦略

Ansibleは、ホストを管理するためにハブ戦略を使用します。 Ansibleソフトウェアは、コントローラーとして機能するホストにインストールされます。クライアント側のAnsibleソフトウェアは存在しないため、リモートホストにインストールする必要はありません。

Ansibleは、ほぼすべてのLinuxディストリビューションにすでにインストールされているSSHを使用して、リモートホストと通信します。システム管理者はホストへのリモートアクセスにパスワードを使用することを選択できますが、それは確かにAnsibleのようなツールの効率とハンドオフの性質を低下させます。そのため、他のほとんどの管理者と同様に、公開鍵と秘密鍵のペア(PPKP)を使用します。これは、パスワードよりも安全であり、管理者の介入なしに1〜数千のリモートホストのタスクを自動化できます。

AnsibleはSSH経由でリモートホストにコマンドを送信し、その結果を使用してコマンドの成功を判断します。また、これらの結果を使用して、条件付きの whenを使用して次のアクションコースを決定することもできます。 ステートメント。

要件の定義

他のプログラムと同じように、C、Python、Bash、またはその他の言語で記述されているかどうかにかかわらず、私は常に一連の要件から始めます。あなたは私の本、SysAdminsのためのLinux哲学を読んだことがありますか?これは、Ansibleなどのツールにも当てはまります。いつ到着したかを特定できるように、どこに行くかを定義する必要があります。

これらは私のAnsibleプレイブックの要件です:

Play 1:Ansibleコントローラー

  1. まず、Ansibleコントロールノードにアップデートをインストールします。
  2. マニュアルページデータベースを更新します。
  3. 必要に応じて電源を切ります。これは、適切な再起動を行わない奇妙なマザーボードのため、私のコントロールノードと他のホストでは異なります。
  4. 再起動後にログインし、プレイブックを再実行します。コントロールノードはすでに目的の状態にあるため、それ以上のアクションは実行されず、Play2が開始されます。

Play 2:サーバー

  1. ファイアウォールとサーバーに連続して、つまり一度に1つずつ更新をインストールします。
  2. マニュアルページデータベースを更新します。
  3. 必要に応じて再起動します。
  4. 必要に応じて、最初のホストが再起動するのを待ってから、次のホストを開始します。

Play 3:ワークステーション

  1. サーバーが完了するまでワークステーションの更新を開始しないでください。
  2. 同時に並行して実行されている各コンピューターに更新プログラムをインストールします。
  3. マニュアルページデータベースを更新します。
  4. 必要に応じて再起動します。

はい、私はこれを行う他の方法があることを知っています。コントローラの再起動後にプレイブックを再起動する必要がないように、Ansibleコントローラを最後に実行することを考えました。しかし、私が行う方法は、最初にプライマリワークステーション(Ansibleコントロールノードでもある)で更新を行い、次に残りのシステムを更新する前にいくつかのテストを行うことです。したがって、この戦略はそのために完全に機能します。あなたのニーズはおそらく私のものとは異なるでしょう、それであなたはあなたにとって最もうまくいく方法を使うべきです。 Ansibleの特徴は、さまざまなニーズに対応できる柔軟性を備えていることです。

タスクの要件がわかったので、プレイブックを開始できます。

構文

Ansible Playbookは、標準のYAML構文とフォーマットに準拠している必要があります。私が遭遇した最も頻繁なエラーは、私自身のフォーマットの間違いです。これは通常、必要に応じて先頭のダッシュを使用したか使用しなかったか、間違ったインデントを使用したことが原因です。

プレイ名はプレイブックの1列目から始まり、後続の各タスクは正確に2つのスペースでインデントされます。 。正確に2つのスペースは、タスク内の各アクションをインデントし、サブタスクは、正確に2つのスペースによってさらにインデントされます。他の数のスペースまたはスペース以外の空白(タブなど)を使用すると、ランタイムエラーが発生します。行末の余分な空白もエラーを生成します。

フォーマットエラーが発生し、問題をすばやく確認できるようになります。プレイブックを実行する前にこれらのエラーを見つけるのに役立つツールがいくつかあり、長期的には時間を大幅に節約できます。

プレイブックの開始

それでは、これらのタスクを必要な順序で実行するプレイブックを始めましょう。プレイブックは、単にタスクのコレクションです。 ホストの望ましい状態を定義します。ホスト名またはインベントリグループは、プレイブックの先頭で指定され、Ansibleがプレイブックを実行するホストを定義します。

プレイブックには3つの演劇が含まれます 要件ステートメントで特定した各タイプのホストを処理します。各プレイのロジックは少し異なりますが、同じ結果が得られます。つまり、すべてのアップデートがインストールされた1つ以上のホストです。

私のプレイブックの名前はdoUpdates.yml /root/ansible/Updatesにあります このプロジェクト用に作成したディレクトリ。このプレイブックの演劇によってインストールされたBashプログラムは、/root/ansible/Updates/filesにあります。 ディレクトリ。

このプレイブックを一度に1セクションずつ見ていきましょう。

これをYAMLファイルとして定義する

私はすべてのコードを適切に構造化されたコメントで開始し、このプレイブックのファイル名と簡単な説明が将来自分自身または他のシステム管理者のために存在するようにします。プレイブックにはコメントを含めることができますが、これについて言及している記事や本はほとんど見たことがありません。

すべてを文書化することを信じているシステム管理者として、コメントは非常に役立つことがあります。これは、コメントでタスク名と同じことを言うことではなく、タスクのグループの目的を特定し、特定のことを特定の方法で行う理由を記録することです。注文。これは、後日、元の考えを忘れた可能性があるときに問題をデバッグするのに役立ちます。 Bashと同様に、コメントはで始まります 。

この最初のセクションの主な機能は、3つのダッシュ( --- )です。 )これをYAMLファイルとして定義するために使用されます。 yml ファイル名の拡張子はYAMLを表します。その意味をいくつか見てきましたが、YAMLは1つではないという主張をいくつか見たにもかかわらず、私の賭けは「YetAnotherMarkupLanguage」です。

########################################################################
#                             doUpdates.yml
#------------------------------------------------------------------
# This playbook installs all available RPM updates on the inventory hosts.
#
#    
#------------------------------------------------------------------
#
# Change History              
# Date        Name         Version   Description
# 2020/10/01  David Both   00.00     Started new code
# 2020/10/10  David Both   01.00     First release code finished
# 2020/10/18  David Both   01.01     Minor changes to sequence and
#                                    fix a couple minor problems.
#
########################################################################
---

最初のプレイ

この次のセクションでは、プレイブックの最初のプレイを定義します。プレイブックには1つ以上のプレイを含めることができ、1つはAnsibleが実行されているコントロールホスト用、1つはネットワーク上の2つのサーバー用、もう1つは残りのワークステーション用です。次に、最初のプレイを定義します。結局のところ、これはプレイブックです。

プレイは列0から始まり、プレイの残りの行が厳密にインデントされていることに注意してください。プレイの開始を定義するステートメントはありません。 Ansibleは、厳密なYAML構造を使用して、各プレイとタスクがどこから始まるかを決定します。

########################################################################
#######################################################################
# Play 1 - Do updates for host david
########################################################################
########################################################################
- name: Play 1 - Install updates on david - the Ansible controler
  hosts: david
  remote_user: root
  vars:
    run: false
    reboot: false

さまざまなキーワードに頻繁に遭遇するので、Ansibleを使い始めたときに私が望んでいたいくつかの説明があります。

名前 :この行はプレイの名前であり、プレイ名はSTDOUTデータストリームに表示されます。これにより、リダイレクトされたストリームを後で見たり表示したりするときに、追跡するために実行される各再生を簡単に識別できます。プレイとタスクごとにキーワードが必要ですが、テキストの内容はオプションです。

ホスト :これは、再生が実行されるホスト名を定義します。これには、スペースで区切られたホスト名のリストまたはホストのグループの名前を含めることができます。ホストグループとリストされているすべてのホストの名前がインベントリファイルに表示されている必要があります。デフォルトでは、これは/etc/ansible/hostsです。 ただし、-iを使用している限り、別のファイルにすることができます (--inventory )代替ファイルを指定するオプション。

remote_user :この行は必須ではありませんが、Ansibleがリモートホスト上で動作するユーザーを指定します。リモートホストのユーザーがローカルホストのユーザーと同じである場合、この行は必要ありません。デフォルトでは、AnsibleはリモートホストでAnsibleプレイブックを実行するユーザーと同じユーザーIDを使用します。ここでは、情報提供のみを目的として使用しています。ほとんどのプレイブックをローカルホストでrootとして実行しているため、Ansibleはrootとしてリモートホストにログインします。

変数 :このセクションは、任意のプログラミング言語と同様に使用できる1つ以上の変数を定義するために使用できます。この場合、プレイブックの後半にある条件付きの「when」ステートメントでそれらを使用して、実行パスを制御します。

変数のスコープは、変数が定義されているセクションに限定されます。この場合、それらはPlay 1で定義されているため、そのPlayに限定されます。後のプレイで使用したい場合は、必要なプレイごとに再設定する必要があります。変数がタスクに設定されている場合、それらはそのタスク内でのみ使用可能であり、そのプレイの残りの部分では使用できません。

-eを使用すると、コマンドラインで変数値を上書きできます。 (--extra_variables )別の値を指定するオプション。プレイブックを実行する時間になるとわかります。

タスク

これは、Play1のタスクセクションの始まりです。タスク :キーワードは正確に2つのスペースでインデントされます。各タスクには名前が必要です 名前のテキストがない場合でも、ステートメント。このテキストを使用すると、プレイブックロジックを簡単に追跡でき、実行中に画面に表示されて、進行状況をリアルタイムで追跡できるようになります。

tasks:
########################################################################
# Do some preliminary checking 
########################################################################
    - name: Install the latest version of the doUpdates script
      copy:
        src: /root/ansible/Updates/files/doUpdates
        dest: /usr/local/bin
        mode: 0774
        owner: root
        group: root



    - name: Check for currently available updates
      command: doUpdates -c
      register: check
    - debug: var=check.stdout_lines

この最初のセクションには、3つのタスクが含まれています。最初のタスクは、私が作成したBashプログラムをターゲットホストにコピーします。 2つ目は、インストールしたばかりのプログラムを実行し、 doUpdates からのSTDOUTデータストリームを割り当て(登録)します。 変数「check」にプログラムします。 3番目のタスクは、チェック変数のすべてのSTDOUT行を画面に出力します。

新しいキーワードをもう少し詳しく見てみましょう:

コピー :copyキーワードは、指定されたソースの場所( src )から1つ以上のファイルをコピーできるスタンザの先頭を定義します。 )指定されたターゲットの場所(宛先 )。このセクションのキーワードは、コピー操作のさまざまな側面とコピーされたファイルの最終状態を定義します。

src :これは、コピーするファイルの完全修飾パスと名前です。この場合、1つのファイルのみをコピーしますが、ディレクトリ内のすべてのファイル、またはファイルグロブパターンに一致するファイルのみをコピーするのは簡単です。ソースファイルは通常、Ansibleハブディレクトリツリー内の場所に保存されます。この場合、ソースファイルへの完全修飾パスは/root/ansible/Updates/files/doUpdatesにあります。 。

宛先 :これは、ソースファイルがコピーされるターゲットホスト上の宛先パスです。

モード :modeキーワードは、コピーされたファイルに適用されるファイルモードを定義します。ソースファイルのファイルモードに関係なく、Ansibleはファイルモードをこのステートメントで指定されたものに設定します。例: rwxr_xr __ または0754 。 8進形式を使用する場合は、必ず4バイトすべてを使用してください。

所有者 :これは、ファイルに適用される所有者アカウントです。

グループ :これは、ファイルに適用されるグループアカウントです。

コマンド :このキーワードでは、任意のLinuxシェルコマンド、シェルスクリプト、またはコマンドラインプログラムとオプションおよび引数を使用できます。インストールしたばかりのBashプログラムを使用して、dnfなどのAnsibleビルトインでは簡単に取得できない情報を取得しました。 。

登録 :このキーワードは、上記で指定されたコマンドのSTDOUTを「check」という名前の変数に設定します。 いつ: キーワードは、この変数の内容を照会できます。次に、それが一部であるタスクが実行されるかどうかを決定するための条件として使用されます。これについては次のセクションで説明します。

デバッグ :指定した変数の内容を画面に出力します。私はこれをデバッグツールとして頻繁に使用します。これはデバッグに役立ちます。ヒント、ヒント。

ここで、私の doUpdatesについて少し説明します。 Bashプログラム。

私はもともとこのBashプログラムを作成して、Ansibleで始めた更新を実際に実行しました。更新が利用可能かどうかを判断するコードが含まれています。また、kernel、systemd、またはglibcが更新されているかどうかも判別します。これらのいずれかを完全に有効にするには、再起動が必要です。私のプログラムは、ターゲットホストを再起動するかどうかを決定する条件としてAnsibleで使用できるSTDOUTに数行を出力します。これを次のセクションで使用します。このセクションでは実際の更新を行い、次のセクションではプライマリワークステーションの電源をオフにします。ご覧のとおり、同様のコードが他のすべてのホストで再起動を実行します。

-cで使用されるこのプログラムのSTDOUT アップデートが利用可能な場合、オプションは次のようになりますが、再起動は必要ありません。正規表現を使用して、このデータストリーム内の任意のテキストでキー文字列を検索できます。これは、いつで使用できます。 :特定のタスクが実行されるかどうかを決定するための条件付き。

TASK [debug] ******************************************************************************************************************************************
ok: [wally1] => {
    "check.stdout_lines": [
        "########## 48 updates ARE available for host wally1.both.org. ##########",
        "########## Including: ##########",
        "Last metadata expiration check: 1:47:12 ago on Tue 20 Oct 2020 01:50:07 PM EDT.",
        "Updates Information Summary: available",
        "    3 Security notice(s)",
        "        2 Moderate Security notice(s)",
        "    3 Bugfix notice(s)",
        "    2 Enhancement notice(s)",
        "    2 other notice(s)",
        "########## A reboot will NOT be required after these updates are installed. ##########",
        "Program terminated normally"
    ]
}

すぐ上のこの次のセクションでは、 when のすべての条件があれば、実際の更新を実行します。 :ステートメントは真です。このセクションでは、組み込みのAnsible dnfを使用します パッケージマネージャー。

########################################################################
# Do the updates.
########################################################################
# Install all available updates
    - name: Install all current updates
      dnf:
        name: "*"
        state: latest
      when: (check.stdout | regex_search('updates ARE available')) and run == "true"

dnf :DNFパッケージマネージャーとインターフェイスするAnsibleビルトインを呼び出します。機能には少し制限がありますが、パッケージのインストール、削除、および更新を行うことができます。 DNFモジュールの制限の1つは、check-updateがないことです。 働き。したがって、私は引き続きBashプログラムを使用して、更新するパッケージのリストを検出し、そこから再起動(または電源オフ)を実行する必要があるかどうかを判断します。 AnsibleにはYUMとAPTも組み込まれています。

名前 :操作するパッケージの名前を提供します。この場合、ファイルグロブ文字 * インストールされているすべてのパッケージを示します。

状態 :このキーワードの「latest」値は、インストールされているすべてのパッケージを最新バージョンにすることを示します。他の状態オプションのいくつかは、パッケージがインストールされているが必ずしも最新バージョンである必要はないことを意味する「存在」と、インストールされている場合にパッケージを削除することを意味する「不在」です。

いつ :この条件句は、このタスクを実行するために満たす必要のある条件を指定します。この場合、更新は、正規表現で定義されたテキストの文字列が以前に登録された変数「check」に存在し、「run」変数が「true」に設定されている場合にのみインストールされます。

更新が完了したので、再起動する必要があるかもしれません。それで、どのように対処できるか見てみましょう。次のタスクは私たちのためにそれを行います。

まず、コメントによるドキュメントが少しあります。これは、ハードウェアの潜在的な問題のために、このホストを再起動するのではなく、電源をオフにしたことを示しています。これは、この特定のプレイが必要な理由と、他のプレイとは異なる理由を説明しているため、コードとプレイブックにコメントを含める必要がある理由の完璧な例です。これは、あるホストを他のホストとは異なる方法で処理する方法の良い例でもあります。

########################################################################
# Now poweroff host david because of MB problems that won't let it
# do a reboot without manual intervention. Need to see if I
# can figure out this problem and fix it but it is a hardware issue
# and this is just a temporary circumvention. 
########################################################################
    - name: Poweroff this host if necessary and reboot extra variable is true
      command: poweroff
      when: (check.stdout | regex_search('reboot will be required')) and reboot == "true" and run == "true"

このタスクでは、poweroffを送信します コンピュータを再起動するという好ましいアクションの代わりにコマンド。コメントに記載されている理由でこれを行います。プライマリワークステーション(Ansibleハブでもある)のマザーボードが適切に再起動しないためです。これはおそらく、何らかのタイプの誤動作ではなく、私の側の設定ミスが原因です。すでに検索とBIOS構成の変更に費やした時間が許容範囲を超えており、作業を完了する必要があるため、その理由はまだわかりません。時々、私はもう少しそれに取り組んでいますが、それはもはや余分な時間の価値がありません。

プレイブックの実行は、電源がオフになると停止します(または、Ansibleハブデバイスが正しく再起動する場合は再起動します)。そのため、最終的に起動して再度実行された後で、プレイブックを再起動する必要があります。今回はアップデートがインストールされているため、電源オフやリブートは発生せず、次のプレイが実行されます。

これで最初のプレイは終了です。

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

まとめ

ここでは多くの情報を取り上げましたが、キーワードとタスクのしっかりとした説明がお役に立てば幸いです。コメントについての私の意見が何であるかも明らかです:それらは重要です。 Play 1は、Ansibleプレイブックを公開します。

この記事の第2部では、ファイアウォールとサーバーを管理するための2つの追加のプレイと、ネットワーク上の残りのホストでプレイブックを締めくくります。また、フォローアップの詳細と概念についても説明します。


Linux
  1. 追加の変数をAnsibleプレイブックに渡す方法

  2. Ansibleプレイブックを使用してソフトウェアパッケージをインストールする方法

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

  1. Ansibleでファイルを作成する方法

  2. Ansible Playbook:Playbookを作成および構成する方法

  3. リモートホストの OS バージョンを取得するために Ansible プレイブックを作成する方法

  1. Ansible Playbookでタグを使用する方法(例)

  2. AnsiblePlaybookで変数を使用する方法

  3. AnsiblePlaybookでループを使用する方法