Ubuntu 18.04でAnsibleを使用してサーバーのセットアップを自動化する方法

前書き

新しいUbuntu 18.04サーバーを初めて作成するとき、基本的なセットアップの一部として早期に実行する必要があるいくつかの構成手順があります。 これにより、サーバーのセキュリティと使いやすさが向上し、その後のアクションの強固な基盤として機能します。

これらの手順を手動で完了できますが、プロセスを自動化することで時間を節約し、人的エラーを減らすことができます。 コンテナ化されたアプリケーションとマイクロサービスの普及により、サーバー自動化はシステム管理において重要な役割を果たしています。 また、新しいサーバーの標準手順を確立する方法でもあります。

このガイドでは、Ansibleを使用して、Initial Server Setup Guideに含まれるステップを自動化する方法について説明します。 Ansibleは、リモートシステムのプロビジョニングと構成の自動化に使用できる最新の構成管理ツールです。

飛行前チェック

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

  • Ansibleは、ローカルマシンまたはAnsible Control Nodeとして設定したリモートサーバーのいずれかにインストールされます。 チュートリアルHow to Install and Configure Ansible on Ubuntu 18.04のステップ1に従って、これを設定できます。

  • Ansibleによって管理される1つ以上のUbuntu 18.04サーバーへのルートアクセス。

プレイブックを実行する前に、AnsibleがSSH経由でサーバーに接続し、Pythonを使用してAnsible modulesを実行できることを確認することが重要です。 次の2つのセクションでは、Ansibleインベントリを設定してサーバーを含める方法と、アドホックAnsibleコマンドを実行して接続と有効な資格情報をテストする方法について説明します。

インベントリファイル

inventory fileには、Ansibleで管理するホストに関する情報が含まれています。 インベントリファイルには1〜数百のサーバーを含めることができ、ホストはグループとサブグループに編成できます。 インベントリファイルは、プレイブックおよびテンプレート内で使用するために、特定のホストおよびグループにのみ有効な変数を設定するためにもよく使用されます。 すぐに表示されるansible_python_interpreter変数のように、一部の変数はプレイブックの実行方法にも影響を与える可能性があります。

デフォルトのAnsibleインベントリの内容を調べるには、ローカルマシンまたはAnsibleコントロールノードで、選択したコマンドラインエディターを使用して/etc/ansible/hostsファイルを開きます。

sudo nano /etc/ansible/hosts

[.note]#Note:一部のAnsibleインストールでは、デフォルトのインベントリファイルが作成されません。 ファイルがシステムに存在しない場合は、/etc/ansible/hostsに新しいファイルを作成するか、コマンドとプレイブックを実行するときに-iパラメーターを使用してカスタムインベントリパスを指定できます。

Ansibleインストールで提供されるデフォルトのインベントリファイルには、インベントリをセットアップするためのリファレンスとして使用できるいくつかの例が含まれています。 次の例では、serversという名前のグループを定義し、その中に3つの異なるサーバーがあり、それぞれがカスタムエイリアスで識別されます:server1server2、およびserver3

/etc/ansible/hosts

[servers]
server1 ansible_host=203.0.113.111
server2 ansible_host=203.0.113.112
server3 ansible_host=203.0.113.113

[servers:vars]
ansible_python_interpreter=/usr/bin/python3

server:varsサブグループは、serversグループに含まれるすべてのホストに有効なansible_python_interpreterホストパラメーターを設定します。 このパラメーターは、リモートサーバーが/usr/bin/python(Python 2.7)の代わりに/usr/bin/python3 Python 3実行可能ファイルを使用するようにします。これは最近のUbuntuバージョンにはありません。

インベントリファイルのセットアップを完了するには、強調表示されたIPをサーバーのIPアドレスに置き換えます。 終了したら、CTRL+Xyの順に押して変更を確認し、次にENTERを押して、ファイルを保存して閉じます。

インベントリファイルの準備ができたので、ノードへの接続をテストします

接続性のテスト

サーバーを含めるようにインベントリファイルを設定したら、Ansibleがこれらのサーバーに接続してSSH経由でコマンドを実行できるかどうかを確認します。 このガイドでは、Ubunturootアカウントを使用します。これは、通常、新しく作成されたサーバーでデフォルトで使用できる唯一のアカウントであるためです。 このハンドブックは、リモートサーバーとのその後の対話で使用する必要があるsudo特権を持つ新しい非rootユーザーを作成します。

ローカルマシンまたはAnsible Control Nodeから、次を実行します。

ansible -m ping all -u root

このコマンドは、組み込みのpingAnsible moduleを使用して、デフォルトのインベントリからすべてのノードで接続テストを実行し、rootとして接続します。 pingモジュールは次のことをテストします:ホストがアクセス可能かどうか
、有効なSSH資格情報がある場合は
、ホストがPythonを使用してAnsibleモジュールを実行できる場合は

キーベースの認証の代わりにpassword-based authenticationを使用してリモートサーバーに接続する場合は、Ansibleコマンドに追加のパラメーター-kを指定して、接続のパスワードの入力を求めるメッセージを表示する必要があります。ユーザー。

ansible -m ping all -u root -k

[.note]#Note:一部のサーバーでは、rootユーザーとしてのパスワードベースの認証に対して追加のセキュリティ対策が講じられている場合があり、場合によってはサーバーに手動でログインする必要がある場合があります。初期ルートパスワードを変更します。

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

Outputserver1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
server2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
server3 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

SSH経由でこれらのサーバーに初めて接続する場合は、Ansible経由で接続しているホストの信頼性を確認するよう求められます。 プロンプトが表示されたら、yesと入力し、Enterを押して確認します。

ホストから「ピンポン」応答が返ってきたら、そのサーバーでAnsibleコマンドとプレイブックを実行する準備ができていることを意味します。

このPlaybookの機能

このAnsibleプレイブックは、Ubuntu 18.04 initial server setup guideおよびsetting up SSH keys on Ubuntu 18.04のガイドで概説されている手順を手動で実行する代わりの方法を提供します。

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

  1. 管理グループwheelsが作成され、passwordless sudo用に構成されます。

  2. create_user変数で指定された名前を使用して、そのグループ内に新しい管理ユーザーが作成されます。

  3. 公開SSHキーは、変数copy_local_keyで定義された場所からコピーされ、前の手順で作成したユーザーのauthorized_keysファイルに追加されます。

  4. rootユーザーのパスワードベースの認証は無効になっています。

  5. ローカルaptパッケージインデックスが更新され、変数sys_packagesで定義された基本パッケージがインストールされます。

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

このプレイブックに含まれている各ステップの詳細については、Ubuntu 18.04 initial server setup guideを参照してください。

プレイブックの実行が終了すると、新しく作成されたsudoアカウントを使用してサーバーにログインできるようになります。

このプレイブックの使用方法

開始するには、playbookのコンテンツをAnsibleコントロールノードにダウンロードします。 これは、ローカルマシン、またはAnsibleをインストールしてインベントリをセットアップしたリモートサーバーのいずれかです。

[.note]#便宜上、プレイブックの内容もfurther section of this guide
に含まれています#

このプレイブックをコマンドラインからダウンロードするには、curlを使用できます。

curl -L https://raw.githubusercontent.com/do-community/ansible-playbooks/master/initial_server_setup/ubuntu1804.yml -o initial_server_setup.yml

これにより、プレイブックの内容が現在のローカルパス上のinitial_server_setup.ymlという名前のファイルにダウンロードされます。 選択したコマンドラインエディタでファイルを開くと、プレイブックの内容を調べることができます。

nano initial_server_setup.yml

プレイブックファイルを開くと、注意が必要な3つの異なる変数を持つvarsという名前のセクションに気付くはずです。

  • create_user:作成してsudo権限を付与するroot以外のユーザーアカウントの名前。 この例ではsammyを使用していますが、任意のユーザー名を使用できます。

  • copy_local_key:新しい非ルートsudoアカウントの承認済みキーとして設定する有効なSSH公開キーへのローカルパス。 デフォルト値は、~/.ssh/id_rsa.pubにある現在のローカルユーザーの公開鍵を指します。

  • sys_packages:パッケージマネージャーツールaptを使用してインストールされる基本的なシステムパッケージのリスト。

initial_server_setup.yml内の変数の更新が完了したら、ファイルを保存して閉じます。

これで、1つ以上のサーバーでこのプレイブックを実行する準備が整いました。 ほとんどのプレイブックは、デフォルトでインベントリからallサーバーで実行されるように構成されています。 -lフラグを使用して、サーバーのサブセットまたは単一のサーバーのみがプレイブックの影響を受けるようにすることができます。 server1でのみプレイブックを実行するには、次のコマンドを使用できます。

ansible-playbook initial_server_setup.yml  -l server1

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

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

TASK [Make sure we have a 'wheel' group] *********************************************************************************************************
changed: [server1]

TASK [Allow 'wheel' group to have passwordless sudo] *********************************************************************************************
changed: [server1]

TASK [Create a new regular user with sudo privileges] ********************************************************************************************
changed: [server1]

TASK [Set authorized key for remote user] ********************************************************************************************************
changed: [server1]

TASK [Disable password authentication for root] **************************************************************************************************
changed: [server1]

TASK [Update apt] ********************************************************************************************************************************
changed: [server1]

TASK [Install required system packages] **********************************************************************************************************
ok: [server1]

TASK [UFW - Allow SSH connections] ***************************************************************************************************************
changed: [server1]

TASK [UFW - Deny all other incoming traffic by default] ******************************************************************************************
changed: [server1]

PLAY RECAP ***************************************************************************************************************************************
server1                    : ok=9    changed=8    unreachable=0    failed=0

プレイブックの実行が完了すると、次の方法でサーバーにログインできるようになります。

ssh sammy@server_domain_or_IP

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

copy_local_key変数を使用してカスタム公開鍵を設定した場合は、対応する秘密鍵の場所を指定する追加のパラメーターを指定する必要があります。

ssh sammy@server_domain_or_IP -i ~/.ssh/ansible_controller_key

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

sudo ufw status

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

OutputStatus: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)

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

プレイブックの内容

初期サーバーセットアッププレイブックは、DigitalOceanCommunity GitHub organizationansible-playbooks repositoryにあります。 スクリプトの内容を直接コピーまたはダウンロードするには、スクリプトの上部にあるRawボタンまたはclick here to view the raw contents directlyをクリックします。

便宜上、完全な内容もここに含まれています。

initial_server_setup.yml

---
- hosts: all
  remote_user: root
  gather_facts: false
  vars:
    create_user: sammy
    copy_local_key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
    sys_packages: [ 'curl', 'vim', 'git', 'ufw' ]

  tasks:
    - name: Make sure we have a 'wheel' group
      group:
        name: wheel
        state: present

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

    - name: Create a new regular user with sudo privileges
      user:
        name: "{{ create_user }}"
        state: present
        groups: wheel
        append: true
        create_home: true
        shell: /bin/bash

    - name: Set authorized key for remote user
      authorized_key:
        user: "{{ create_user }}"
        state: present
        key: "{{ copy_local_key }}"

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

    - name: Update apt
      apt: update_cache=yes

    - name: Install required system packages
      apt: name={{ sys_packages }} state=latest

    - name: UFW - Allow SSH connections
      ufw:
        rule: allow
        name: OpenSSH

    - name: UFW - Deny all other incoming traffic by default
      ufw:
        state: enabled
        policy: deny
        direction: incoming

このプレイブックを自由に修正したり、独自のワークフロー内の個々のニーズに最適な新しいタスクを含めたりしてください。

結論

サーバーの初期セットアップを自動化することで時間を節約できます。また、サーバーが標準構成に従っていることを確認し、必要に応じて改善およびカスタマイズできます。 最新のアプリケーションの分散された性質と、異なるステージング環境間での一貫性の必要性により、このような自動化が必要になります。

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

このプレイブックに新しいタスクを含めてサーバーの初期設定をさらにカスタマイズする場合は、Ansibleの紹介ガイドConfiguration Management 101: Writing Ansible Playbooksを参照してください。