序章

最新のアプリケーション環境は使い捨てであるため、サーバーの自動化はシステム管理において重要な役割を果たしています。 構成管理ツール( Ansible など)は通常、新しいサーバーの標準手順を確立することでサーバーセットアップを自動化するプロセスを合理化すると同時に、手動セットアップに関連する人的エラーを減らします。

Ansibleは、ノードに特別なソフトウェアをインストールする必要のないシンプルなアーキテクチャを提供します。 また、自動化スクリプトの作成を容易にする堅牢な機能セットと組み込みモジュールも提供します。

このガイドでは、Ansibleを使用して、Ubuntu20.04サーバー用の初期サーバーセットアップガイドに含まれる手順を自動化する方法について説明します。

前提条件

このガイドのプレイブックで提供されている自動セットアップを実行するには、次のものが必要です。

  • 1つのAnsibleコントロールノード:SSHキーを使用してAnsibleホストに接続するようにAnsibleがインストールおよび構成されたUbuntu20.04マシン。 サーバーの初期設定ガイドで説明されているように、コントロールノードにsudo権限とファイアウォールが有効になっている通常のユーザーがいることを確認してください。 Ansibleをセットアップするには、 Ubuntu20.04にAnsibleをインストールして構成する方法に関するガイドに従ってください。
  • Ubuntu 20.04のクリーンインストールを備えた1つのリモートサーバー:このサーバーでは事前のセットアップは必要ありませんが、上記のAnsibleコントロールノードからこのサーバーへのSSHアクセスが必要です。 このサーバーはAnsibleホストリモートサーバーになり、Ansibleコントロールノードによる自動プロビジョニングの対象になります。

このハンドブックは何をしますか?

このAnsibleプレイブックは、Ubuntu20.04初期サーバーセットアップガイドおよびUbuntu20.04でのSSHキーのセットアップに関するガイドで概説されている手順を手動で実行する代わりの方法を提供します。サーバ。 プレイブックを一度設定すると、その後はすべてのサーバーで使用できます。

このプレイブックを実行すると、Ansibleホストで次のアクションが実行されます。

  1. aptitudeをインストールします。これは、aptパッケージマネージャーの代わりにAnsibleで推奨されています。

  2. 新しいsudoユーザーを作成し、パスワードなしのsudoを設定します。

  3. ローカルSSH公開鍵をコピーし、リモートホストの新しい管理ユーザーのauthorized_keysファイルに含めます。

  4. rootユーザーのパスワードベースの認証を無効にします。

  5. システムパッケージをインストールします。

  6. SSH接続のみを許可し、他の要求を拒否するようにUFWファイアウォールを構成します。

プレイブックの実行が終了すると、サーバーへのログインに使用できる新しいユーザーが作成されます。

まず、Ansibleコントロールノードサーバーでsudoが有効なユーザーにログインします。

ステップ1—Ansibleコントロールノードを準備する

Ansibleコントロールノードサーバーで、AnsibleホストリモートサーバーのIPをAnsibleインベントリファイルに追加します。 お好みのテキストエディタを使用する:

  1. sudo nano /etc/ansible/hosts

これにより、Ansibleインベントリファイルが開きます。 AnsibleホストのリモートサーバーのIPを[servers]ブロックに追加します。

/ etc / ansible / hosts
[servers]
server1 ansible_host=your_remote_server_ip

. . .

次に、このAnsibleコントロールノードとAnsibleホストリモートサーバー間のSSH接続をテストして認証します。

  1. ssh [email protected]your_remote_server_ip

認証要求を受け入れ、プロンプトが表示されたらパスワードを入力します。 SSH接続を確認したら、CTRL+Dを押して接続を閉じ、コントロールノードに戻ります。

ステップ2—プレイブックの準備

playbook.ymlファイルには、すべてのタスクが定義されています。 タスクは、Ansibleプレイブックを使用して自動化できるアクションの最小単位です。 ただし、最初に、好みのテキストエディタを使用してプレイブックファイルを作成します。

  1. nano playbook.yml

これにより、空のYAMLファイルが開きます。 プレイブックにタスクを追加する前に、以下を追加することから始めます。

playbook.yml
---
- hosts: all
  become: true
  vars:
    created_username: sammy

ユーザー名を任意のユーザー名に自由に置き換えてください。

あなたが出くわすほとんどすべてのプレイブックは、これに似た宣言で始まります。 hostsは、Ansibleコントロールノードがこのプレイブックでターゲットとするサーバーを宣言します。 becomeは、すべてのコマンドがエスカレートされたroot特権で実行されるかどうかを示します。

varsを使用すると、データを変数に格納できます。 将来このユーザー名を変更する場合は、ファイル内のこの1行を編集するだけで済みます。

注:プレイブックファイルを最終的な完成状態で表示する場合は、ステップ8にジャンプします。 YAMLファイルはインデント構造に特化している可能性があるため、すべてのタスクを追加したら、プレイブックを再確認することをお勧めします。

ステップ3—PlaybookにAptitudeインストールタスクを追加する

デフォルトでは、タスクはプレイブックの上から下に順番にAnsibleによって同期的に実行されます。 これは、タスクの順序が重要であることを意味し、次のタスクが開始する前に1つのタスクの実行が終了すると安全に想定できます。

このプレイブックのすべてのタスクはスタンドアロンで、他のプレイブックで再利用できます。

Linuxパッケージマネージャーとインターフェイスするためのツールであるaptitudeをインストールする最初のタスクを追加します。

playbook.yml
  tasks:
    - name: Install aptitude
      apt:
        name: aptitude
        state: latest
        update_cache: true

ここでは、apt Ansibleの組み込みモジュールを使用して、Ansibleにaptitudeをインストールするように指示しています。 Ansibleのモジュールは、生のbashコマンドとして実行する必要がある操作を実行するためのショートカットです。 aptitudeが利用できない場合、Ansibleはパッケージをインストールするためにaptに安全にフォールバックします。 したがって、この手順は技術的にはオプションですが、Ansibleは歴史的にaptitudeを優先してきました。

ステップ4—PlaybookにSudoユーザーセットアップタスクを追加する

rootユーザーの広範な使用を避けることをお勧めします。 次を追加することにより、sudo特権が付与されたユーザーの作成を自動化できます。

playbook.yml
    - name: Setup passwordless sudo
      lineinfile:
        path: /etc/sudoers
        state: present
        regexp: '^%sudo'
        line: '%sudo ALL=(ALL) NOPASSWD: ALL'
        validate: '/usr/sbin/visudo -cf %s' 

    - name: Create a new regular user with sudo privileges
      user:
        name: "{{ created_username }}"
        state: present
        groups: sudo
        append: true
        create_home: true

lineinfile Ansibleモジュールを使用して、ファイル内の特定の行をターゲットにして置き換えています。 この場合、正規表現を使用してsudoersファイルの特定の行をターゲットにし、それを変更してsudoをパスワードなしで使用できるようにします。 また、visudoを使用して変更を検証し、何かが壊れないようにします。

これを利用するために、userモジュールを使用して新しいユーザーを追加します。 Ansibleは、このユーザーがまだ存在しない場合は作成され、ユーザーがsudoグループに属し、他のグループから削除されていないことを確認し、ホームディレクトリが作成されます。

注:変数を示す中括弧の前後に引用符を含めるようにしてください。 これらの引用符の省略は、非常に一般的なAnsible構文エラーです。

ステップ5—SSHキーセットアップの追加とルートパスワードタスクの無効化をPlaybookに追加する

Ansibleは、SSHキーを使用していることを前提に動作します。 SSHキーの使用とrootパスワード認証の無効化を組み合わせることを強くお勧めします。 これを自動化するには、以下を追加します。

playbook.yml
    - name: Set authorized key for remote user
      ansible.posix.authorized_key:
        user: "{{ created_username }}"
        state: present
        key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"

    - name: Disable password authentication for root
      lineinfile:
        path: /etc/ssh/sshd_config
        state: present
        regexp: '^#?PermitRootLogin'
        line: 'PermitRootLogin prohibit-password'

authorized_keyモジュールは、ユーザー名とキーの場所を指定すると使用できます。 ここで、キーへのパスは、Ansibleのlookup関数を使用して作成されます。

lineinfileモジュールは、 root のパスワード認証を無効にして、セキュリティを強化するための特権へのアクセスを制限するために、sshd_configの行を検索および置換するために使用されます。

ステップ6—Playbookへのパッケージインストールタスクの追加

Ansibleは、特定のパッケージが常にサーバーにインストールされていることを確認できます。 個々のパッケージでapt installを呼び出したり、複数のタスクに分割したりするのではなく、必要なすべてのパッケージを一覧表示できます。

playbook.yml
    - name: Update apt and install required system packages
      apt:
        pkg:
          - curl
          - vim
          - git
          - ufw
        state: latest
        update_cache: true

好みに応じてパッケージを追加または削除できます。 これにより、すべてのパッケージが存在するだけでなく、最新バージョンでも存在し、aptによる更新が呼び出された後に実行されます。

ステップ7—ファイアウォールセットアップタスクをプレイブックに追加する

インターネットに面しているサーバーにはファイアウォールが不可欠です。 次を追加することで、AnsibleにUFW(Uncomplicated Firewall)が適切に構成されていることを確認できます。

playbook.yml
    - name: UFW - Allow SSH connections
      community.general.ufw:
        rule: allow
        name: OpenSSH

    - name: UFW - Enable and deny by default
      community.general.ufw:
        state: enabled
        default: deny

ufwモジュールは、最初にSSHアクセスが許可されていることを確認します。 次に、このモジュールは、サーバーへの他のすべてのトラフィックをデフォルトで拒否しながら、ファイアウォールを有効にします。

ステップ8—完全なプレイブックを確認する

プレイブックはおおよそ次のようになりますが、カスタマイズによって若干の違いがあります。

playbook.yml
---
- hosts: all
  become: true
  vars:
    created_username: sammy

  tasks:
    - name: Install aptitude
      apt:
        name: aptitude
        state: latest
        update_cache: true

    - name: Setup passwordless sudo
      lineinfile:
        path: /etc/sudoers
        state: present
        regexp: '^%sudo'
        line: '%sudo ALL=(ALL) NOPASSWD: ALL'
        validate: '/usr/sbin/visudo -cf %s'

    - name: Create a new regular user with sudo privileges
      user:
        name: "{{ created_username }}"
        state: present
        groups: sudo
        append: true
        create_home: true

    - name: Set authorized key for remote user
      ansible.posix.authorized_key:
        user: "{{ created_username }}"
        state: present
        key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"

    - name: Disable password authentication for root
      lineinfile:
        path: /etc/ssh/sshd_config
        state: present
        regexp: '^#?PermitRootLogin'
        line: 'PermitRootLogin prohibit-password'

    - name: Update apt and install required system packages
      apt:
        pkg:
          - curl
          - vim
          - git
          - ufw
        state: latest
        update_cache: true

    - name: UFW - Allow SSH connections
      community.general.ufw:
        rule: allow
        name: OpenSSH

    - name: UFW - Enable and deny by default
      community.general.ufw:
        state: enabled
        default: deny

注:これは、くぼみに注意するための穏やかなリマインダーです。 エラーが発生した場合は、これが原因である可能性が非常に高くなります。 YAMLは、この例で行われたように、インデントとして2つのスペースを使用することを提案します。

プレイブックに満足したら、テキストエディタを終了して保存できます。

ステップ9—Playbookを初めて実行する

これで、このプレイブックを1つ以上のサーバーで実行する準備が整いました。 ほとんどのプレイブックは、デフォルトでインベントリ内のすべてのサーバーで実行されるように構成されていますが、今回はサーバーを指定します。

server1でのみプレイブックを実行し、rootとして接続するには、次のコマンドを使用できます。

  1. ansible-playbook playbook.yml -l server1 -u root -k

-lフラグはサーバーを指定し、-uフラグはリモートサーバーにログインするユーザーを指定します。 リモートサーバーをまだセットアップしていないため、rootが唯一のオプションです。 -kフラグは、SSHパスワードを入力できるため、最初のプレイブックの実行時に非常に重要です。

次のような出力が得られます。

Output
. . . TASK [UFW - Allow SSH connections] *************************************************************************************************************************************************************************************************************************** changed: [server1] TASK [UFW - Enable and deny by default] ********************************************************************************************************************************************************************************************************************** changed: [server1] PLAY RECAP *************************************************************************************************************************************************************************************************************************************************** server1 : ok=9 changed=8 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

これは、サーバーのセットアップが完了したことを示しています。 出力は完全に同じである必要はありませんが、障害がゼロであることが重要です。

プレイブックの最初のセットアップが完了したので、後続のすべてのansible呼び出しは、ユーザーsammyを使用して、-kフラグなしで実行できます。

  1. ansible-playbook playbook.yml -l server1 -u sammy

次の方法でサーバーにログインすることもできます。

  1. ssh sammy@your_remote_server_ip

sammycreated_username変数で定義されたユーザーに置き換え、server_host_or_IPをサーバーのホスト名またはIPアドレスに置き換えることを忘れないでください。

サーバーにログインした後、UFWファイアウォールのアクティブなルールをチェックして、正しく構成されていることを確認できます。

  1. sudo ufw status

次のような出力が得られるはずです。

Output
Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6)

これは、UFWファイアウォールが正常に有効になったことを意味します。 これがプレイブックの最後のタスクであったため、このサーバーでプレイブックが完全に実行されたことを確認します。

結論

サーバーの初期設定を自動化することで時間を節約できると同時に、サーバーがニーズに合わせて改善およびカスタマイズできる標準構成に従うようにすることができます。 最新のアプリケーションは分散しているため、さまざまなステージング環境間で一貫性を保つ必要があるため、このような自動化が必要になります。

このガイドでは、Ansibleを使用して、sudoアクセス権を持つ非rootユーザーの作成、UFWの有効化、UFWの有効化など、新しいサーバーで実行する必要のある初期タスクを自動化する方法を示しました。リモートパスワードベースのrootログインを無効にします。

Ansibleプレイブックの実行方法の詳細については、Ansibleチートシートガイドをご覧ください。

このプレイブックに新しいタスクを含めて、サーバーの初期設定をさらにカスタマイズする場合は、Ansibleの紹介ガイド構成管理101:Ansibleプレイブックの作成を参照してください。 Ansibleロールを使用してインフラストラクチャ環境を抽象化する方法に関するガイドも確認できます。