📌

ローカルPCにAnsible環境を構築&AWSのEC2にデプロイしてみた

2024/02/11に公開

Agenda

ここでは、以下の方を対象としています。

  • Ansibleを利用する初めの一歩が踏み出せない
  • Ansible使いたいけど、何からやればいいかわからない
  • 難しいことは分からんが、とりあえずAnsible使ってみたい

Ansibleというツールを知った時、なんて便利なツールなんだと思いましたが、
実際にどうやって使えばいいのか、ぶっちゃけ分からないと私は思っていました。

なので、ここでの目標は

  • Ansibleの導入方法
  • Ansibleを使ったリモートサーバーへのデプロイ方法

を理解できるようにしていきましょう。

Ansibleとは?

aws-with-ansible-001

他の動画や記事でも分かりやすく説明されているので、ここではざっくりと説明します。

Ansibleというのは、Red Hatという会社が提供しているシステム構成管理ツールです。
Red Hatは、Linuxディストリビューションを提供しているので有名ですかね。

AnsibleはPythonで作られたOSS(オープンソースソフトウェア)です。
YAML形式でコードを記述し、サーバーやNW機器、クラウドリソースを構築、管理、運用などを行えます。
いわゆる、Infrastrucrture as Code (IaC)です。

構成管理ツールには、ChefやPuppetというものもありますが、Ansibleはエージェントレスで、
PythonとSSHが使えればすぐに利用できるのが特徴です。

また、自動化に役立つモジュールが幅広く用意されいてるので、一から作成する必要もないです。

Ansibleのアーキテクチャ

aws-with-ansible-002

ざっくりとした概要はこんな感じですが、
もう一つおさえておきたいのが、Ansibleのアーキテクチャについてです。

他のサイトでもAnsibleの使い方について、解説されている記事がありますが、
古めの記事とかだとAnsibleのバージョンが2.9以前のものを使っていたりします。
既にサーバーに導入されているAnsibleとかを使っている場合とかは2.9になっているかもしれません。

2.9は既に開発が終了しており、メンテナンス対象外となっているため、アップデートが推奨されています。
Ansible2.9を使う場合は新しいバージョン3系を利用することを推奨します。

ansible2.10以降はansibleパッケージの構成が大幅に変わりました。
少し歴史的な話をすると、ansible2.9までは、ansibleは1つのパッケージで全てのモジュールを管理していました。
そして、その時点でモジュールは約3000程あり、モジュールに新規機能を追加するたびにパッケージも更新させる必要があり、
リリースサイクルが遅いという課題があったそうです。

そこで2.10では、よく使われるプラグインとモジュールをコアパッケージ、
その他の用途別に使うモジュールやプラグインをコレクションという管理方法で分ける構成となりました。

このようにコアパッケージとコレクションという2構成にすることで、リリースサイクルの早いコレクションのモジュールは
適宜リリースして、必要に応じてコレクション経由でモジュールをダウンロードすることができるようになりました。

このコアパッケージは、2.10ではansible-base、2.11以降ではansible-coreという名前で提供されています。

そして、今現在で普及しているパッケージがAnsible Community Packageであり、これはansible-core
コミュニティが選択したコレクションをセットにしたパッケージとなります。

今回は、このパッケージを利用していきます。
バージョンはansible-core 2.15を提供するAnsible Community Package 8.x系を利用していきます。

バージョンに関する情報は、公式のリリース情報を確認しましょう
Releases and maintenance

ハンズオン概要

aws-with-ansible-003

それでは今回のハンズオンの概要についてです。
今回は、ローカルPC上に実際にAnsibleをインストールし、
AWS上のEC2インスタンスに対してデプロイが行える状況まで持っていきます。

  1. PC上にAnsibleのインストール、セットアップを行い
  2. AWS上のEC2インスタンスに、Ansible実行ユーザーを作成し
  3. 実際にEC2に対してping疎通確認を行うためのPlaybookを実行していきます

ハンズオンの手順は具体的には以下のとおり

  1. ローカルPC
  • Ansibleインストール
  • Ansible環境構築
  1. AWS
    • CloudFormationでテスト環境構築
    • EC2サーバーセットアップ
  2. テスト
    • Ansibleプロジェクトフォルダ作成
    • Playbook実行

aws-with-ansible-004

今回は以下のような環境でハンズオンを行います
OS : MacOS (Ventura)
Python : 3.10
Ansible : 8.5.x (ansible-core 2.15)

また、前提条件は以下のとおり

  • AWSアカウントは作成済みであること
  • Python3が既にローカルPCにインストールされていること
    • 未インストールの方は事前にインストールをしておいてください。
  • EC2インスタンス、VPC環境構築の知識は既に持っていること
    (今回はCloudFormationで実装していく)
  • ハンズオン環境はMacを利用します
    • Windows利用の方は、手順に差分が出てくるかもなのでご了承
    • 要望があればWindows版も作成するかも

それでは実際にハンズオンを行っていきましょう。

手順

Python仮想環境(venv)構築

公式では、Pythonのパッケージマネージャー(pip)を使用することが推奨されているので、これで構築します。
pipを使うことで、Pythonの仮想環境virtualenv(venv)を構築でき、python本体の環境を汚さずにAnsibleを使えるようになります。
また、pipはAnsibleで依存するPythonライブラリも自動的に取得してくれるので実装が楽になります。

  1. pipインストール確認
`python3 -m pip -V`
  1. (option)以下のように出る場合はpipインストールが必要なのでインストールする
$ python3 -m pip install
/usr/bin/python3: No module named pip
  1. (option)pipインストール
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py --user
  1. venv作成
python3 -m venv ansible-venv
  1. 仮想環境にアクティベート
source ansible-venv/bin/activate
  1. (option)仮想環境を抜ける(ディアクティベート)
deactivate

Ansibleのインストール

仮想環境に入ったら、Ansibleを実際にインストール

  1. Ansibleをインストール
pip install ansible
  1. インストール確認
# バージョン確認
ansible --version

# インストール確認
pip list
pip freeze

Ansible実行用のSSHキーペア作成

そしたらAnsibleではデプロイ先のサーバー(Managed Node)にSSH経由で接続をするため、
接続用のキーペアを作成していきます。
ローカルPCで実行していきます。

※ここではAWSの仕様に合わせ、OpenSSHに標準搭載されているssh-keygenを使用していきます。
OpenSSHをPC上にインストールされていない場合は、事前にインストールをお願いします。

  1. ansible実行用SSHキー作成
    ここではEDCSA形式で作成(RSA形式でもok)
ssh-keygen -t ecdsa -b 521
キーペア名: `~/.ssh/ansible`  # デフォルトの.sshフォルダ配下に配置(場所は任意でok)
キーフレーズ: 入力しない            # キーフレーズは空にする

AWS環境構築

次に、AWS側の環境を構築していきましょう。

まずは、EC2環境を作っていきますが、事前に用意したCloudFormationの
テンプレートを使って作成していきましょう。
テンプレートは以下URLのGitHubテンプレート上に記載していますのでそちらから確認してください。

006_deploy-ec2-with-ansible

※ AWSにログインし、リージョンが東京リージョン(ap-northeast-1)が選択されている状態から始めます。

  1. CloudFormationのStacks画面から[Create stack] - [With new resources(standard)]をクリック
    ansible-handson01

  2. 事前に用意したansible-cfnファイルをアップロードしてNextをクリック
    ansible-handson02

  3. Stack nameを入力してNext(Parameterは変更不要)
    ansible-handson03

  4. Review画面まで遷移し、Capabilitiesの項目にチェックを入れて[Submit]をクリック
    ansible-handson04

  5. StackのStatusがCompleteになったら環境構築完了
    ansible-handson05

  6. 今回のテスト用サーバーが2台作成されているはず
    ansible-handson06

Manage Node(EC2インスタンス)セットアップ

EC2サーバーにAnsible実行のためのユーザーを設定していきます。

EC2インスタンスに接続

ここではEC2インスタンスにSession Managerで接続していきます。
SSHで接続したい人は、別途秘密鍵を取得して接続をしてください。

  1. EC2のInstances画面からsv01の方のインスタンスを選択し[Connect]を選択
    ansible-handson07

  2. Session Managerタブを選択し、[Connect]を選択
    ansible-handson08

  3. コンソール画面が開くのでコマンドを実行していく
    ansible-handson09

Ansible実行ユーザー作成

  1. rootに昇格
sudo su -
  1. ansible実行ユーザー作成
useradd -m ansible
  1. wheelグループに追加
gpasswd -a ansible wheel
  1. ansibleユーザーにパスワード設定
passwd ansible

公開鍵設定

ユーザー作成が完了したら、SSH接続に必要な公開鍵情報を登録していきます。

  1. ansibleユーザーに遷移し、認証ファイル作成
# Ansible実行ユーザーにスイッチ
su - ansible

# Ansibleユーザーで認証ファイル格納フォルダを作成
mkdir .ssh
touch .ssh/authorized_keys

# 作成したフォルダと認証ファイルの権限レベルを変更
chmod 700 .ssh
chmod 600 .ssh/authorized_keys
  1. ローカル上で作成したSSH公開鍵情報をauthorized_keysファイルにコピペ
# 以下で公開鍵の情報をコピペ
vi .ssh/authorized_keys

# コントロールノードにSSH接続ができることを確認
ssh ansible@${接続先IP}

ssh-copy-idコマンドでマネージドノードに公開鍵を登録してもok
その場合はマネージドノード側のSSH設定でパスワード認証を有効化する必要があるので注意。

ssh-copy-id -i .ssh/{秘密鍵} {ansible}@{host}

以下の記事とかが分かりやすかった
https://maku.blog/p/2mzbmw8/

  1. ローカルからEC2にSSH接続ができることを確認
ssh -i ~/.ssh/ansible ansible@[パブリックIP]

接続できない場合は、.sshフォルダや秘密鍵の権限が違っていたり、
SSH設定が問題になっているかもしれないので見直してみましょう。

プロジェクトフォルダ作成

プロジェクトフォルダを作成していきます。
ここではGitHub上に事前に用意していたサンプルフォルダを使っていきます。

概要欄に記載のリンクからsample_projectフォルダをダウンロードしてローカル環境に配置してください。

sample_projectフォルダの構成は以下の通り

sample_project        # プロジェクトルート
├── ansible.cfg       # ansible設定ファイル
├── group_vars
│   └── all.yml       # 全体共通の変数定義ファイル
├── host_vars
│   ├── dev-sv01.yml  # dev-sv01用変数定義ファイル
│   └── dev-sv02.yml  # dev-sv02用変数定義ファイル
├── hosts             # inventoryファイル
├── playbooks
│   └── ping.yml      # ping実行用playbook
└── roles
    └── ping          # ping実行用role
        └── tasks
            └── main.yml

パブリックIP情報を設定

そしたら、dev-sv01.ymldev-sv02.ymlに、パブリックIP情報を
設定してください。

---
ansible_host: xx.xx.xx.xx # replace Public IP

ansible設定ファイルの確認

ansible.cfgはプロジェクト固有のAnsibleの動作を設定できるファイルです。

[defaults]
# リモートホストへの SSH 接続時の秘密鍵の場所
private_key_file = ~/.ssh/ansible

# ロールのデフォルトの場所
roles_path = ./roles

# デフォルトで色を有効化
ansible_color = auto

# リモートコマンドの実行時に警告を非表示にする
ansible_ssh_common_args = -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no

# SSH接続時に公開鍵のフィンガープリントをチェック
host_key_checking=False

[privilege_escalation]
# 特権昇格 (sudo) の設定
become = yes

private_key_fileで、秘密鍵の場所を設定しています。
また、playbookは基本的にsudoで行うものが多いと思うので
becomeプロパティを有効にし、常にsudoでplaybookを実行させています。

動作テスト

プロジェクトルートに遷移し、以下コマンドを実行

ansible-playbook -i hosts playbooks/ping-test.yml

問題なければ、以下のようにTASK実行結果がOKで返ってくるはず

% ansible-playbook -i hosts playbooks/ping-test.yml
PLAY [dev] ***************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************
ok: [dev-sv01]
ok: [dev-sv02]

TASK [ping : Try to connect to host using an Ansible Playbook] ***********************************************************************************
ok: [dev-sv02]
ok: [dev-sv01]

PLAY RECAP ***************************************************************************************************************************************
dev-sv01                   : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
dev-sv02                   : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

以上で、Ansible実行に必要な最低限の環境が整いました。

後片付け

CloudFormationで作成したスタックは削除しておきましょう。

ansible-handson10

継続利用する場合は、課金にご注意ください。

終わりに

今回はAnsibleをインストールし、AWSのEC2インスタンスへのデプロイ環境を構築しました。
Ansibleの魅力は、SSH接続が行えれば、新規サーバーへのデプロイもすぐに行えるという点です。

Ansibleの使い方としては、主にサーバー内部の設定などで使うのが良いかなと思うので、
AWS環境はCloudFormattion、サーバー環境はAnsibleで実装することで、
より快適なIaC運用ができるのではと思っています。

興味がある人は、ぜひAnsibleを勉強してみてください。

今回使用したリポジトリ

以下です

006_deploy-ec2-with-ansible

Discussion