1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWSもAnsibleもよく分からない状態から、AIと一緒にWebサーバを構築して冪等性まで確認した

1
Posted at

AWSもAnsibleもよく分からない状態から、AIと一緒に「動くところ」まで作ってみた

この記事は、筆者と対話AI「カレン」との共同作業です。
「AIに全部やらせた記録」ではなく、分からないことを実際に手を動かしながら学び、AIに先生・伴走者として説明してもらい、一緒に構築した記録として書いています。

筆者は開始時点で、Git・AWS・Ansibleの各コマンドや役割を十分には理解していませんでした。
そのためこの記事では、完成品を誇るというより、分からないまま一度やってみて、あとから構造を理解していく学習方法そのものも含めて残します。


はじめに

AWS、Git、SSH、Ansible。

名前は知っていても、

  • Gitは何をしているのか
  • VPCとSubnetは何が違うのか
  • Security GroupはLinuxのFirewallとどう違うのか
  • AnsibleはSSHと何が違うのか
  • Playbookとは何なのか

と聞かれると、かなり曖昧でした。

そこで今回は、最初から全部理解しようとするのをやめて、

  1. まず実際に構築する
  2. 動作を確認する
  3. ログを残す
  4. そのログをAIと一緒に見直して理解する

という順番で学習しました。

結果として、AWS上に2台のEC2を立て、Ansible ControllerからWebサーバへApacheを構築し、再実行時に changed=0 となるところまで確認できました。


今回作ったもの

全体像は以下です。

自分のPC
└─ WSL2 / Ubuntu
      |
      | SSH
      v
AWS VPC
└─ Public Subnet
      |
      +-- ansible-controller
      |      |
      |      | SSH / Ansible
      |      v
      +-- web01
             |
             └─ Apache httpd

今回の役割分担はこうです。

  • WSL2 / Ubuntu
    • Git、AWS CLI、SSHなどを実行する作業環境
  • AWS
    • VPC、Subnet、Security Group、EC2などを作るクラウド環境
  • ansible-controller
    • Ansibleを実行する管理側EC2
  • web01
    • Ansibleで設定される管理対象EC2
  • Apache
    • web01上で動作するWebサーバ
  • Git / GitHub
    • READMEやPlaybookなどの成果物を履歴管理する

まずGitの作業場所を作る

最初にGitHub上の既存リポジトリをcloneしました。

mkdir -p ~/work
cd ~/work
git clone https://github.com/yellow-777/learning.git
cd learning

その後、学習用ブランチを作成しました。

git switch -c study/aws-ansible-20260910

この時点ではGitの理解もかなり曖昧でしたが、あとから整理すると、

ファイルを編集
    ↓
git add
    ↓
次のcommitに入れる変更を選ぶ
    ↓
git commit
    ↓
ローカルの履歴として確定
    ↓
git push
    ↓
GitHubへ送る

という流れです。

.gitignore も作る

AWSやSSHでは秘密情報を扱うため、以下のようなものをGit管理対象から除外しました。

*.pem
*.ppk
.env
.env.*
*.log

.aws/
credentials

*.retry

「GitHubに載せない方がいいものを先に除外する」という考え方は、今回かなり重要だと感じました。


AWS CLIでネットワークを作る

AWSでは、以下の要素を作成しました。

  • VPC
  • Subnet
  • Internet Gateway
  • Route Table
  • Security Group
  • EC2

VPC

今回のVPCは以下のアドレス範囲です。

10.10.0.0/16

VPCは、AWS上に作る自分専用の仮想ネットワーク全体、と理解しています。

Subnet

VPCの中に以下のSubnetを作りました。

10.10.1.0/24

イメージとしては、

VPC 10.10.0.0/16
└─ Subnet 10.10.1.0/24

です。

Internet GatewayとRoute Table

Route Tableには、以下のような経路を持たせました。

10.10.0.0/16 → local
0.0.0.0/0    → Internet Gateway

ここは復習してやっと理解できました。

  • 10.10.0.0/16 → local
    • VPC内部宛の通信はVPC内部へ
  • 0.0.0.0/0 → Internet Gateway
    • それ以外のIPv4通信はインターネット側へ

つまり、Route Tableは「通信をどこへ送るか」を決めるものです。


Security Group

Security Groupは、AWS側でEC2への通信を制御する仕組みです。

今回、Controller用とWeb用で分けました。

Controller側

SSHのTCP/22を、検証元のPublic IPからのみ許可。

web01側

  • SSH / TCP 22
    • Ansible ControllerのSecurity Groupから許可
  • HTTP / TCP 80
    • 検証元Public IPから許可

ここはLinuxのFirewallとの違いが分かりづらかった部分です。

現在の理解では、

Internet / VPC
     ↓
Security Group   ← AWS側
     ↓
EC2
     ↓
Linux Firewall   ← OS側
     ↓
Apache / sshd

という違いです。

Security Groupは、Linuxへ届く前のAWS側で通信を制御します。


EC2を2台作る

EC2は2台用意しました。

ansible-controller
web01

Private IPは以下でした。

ansible-controller: 10.10.1.157
web01:              10.10.1.8

同じSubnet内にいるため、Controllerからweb01への通信にはPrivate IPを利用します。


SSHで接続する

まず、自分のWSLからControllerへSSHしました。

WSL
 ↓ SSH
ansible-controller

次に、Controllerからweb01へ接続できるようにしました。

最終的にはController側にAnsible用のSSH鍵を作成し、

Controller
 ↓ SSH
web01

という形で接続できるようにしました。

確認時には、

SSH OK

が返り、web01のPrivate IPが 10.10.1.8/24 であることも確認できました。


Ansibleを入れる

ControllerへAnsible Coreをインストールしました。

確認したバージョンは、

ansible core 2.14.18
Python 3.9.25

でした。


Inventoryを作る

Ansibleでは、まず「どのサーバを管理するのか」をInventoryに書きます。

今回の例です。

[web]
web01 ansible_host=10.10.1.8 ansible_user=ec2-user ansible_ssh_private_key_file=/home/ec2-user/.ssh/ansible_web01

これは、

webグループ
└─ web01
   ├─ IP: 10.10.1.8
   ├─ User: ec2-user
   └─ SSH Key: ansible_web01

という意味です。


Ansibleのpingで確認

次にAnsibleからweb01へ接続確認しました。

ansible -i inventory.ini web -m ping

結果は、

web01 | SUCCESS
ping: pong
changed: false

でした。

ここで最初に勘違いしていたのですが、Ansibleの ping は普通のICMP pingとは違います。

Ansibleが、

  1. SSHで接続
  2. 対象側でPythonを使う
  3. Ansibleモジュールを実行
  4. pong を返す

ところまで確認しています。


ApacheをPlaybookで構築する

今回作ったPlaybookの目的は、

web01に
・Apacheがインストール済み
・Apacheが起動中
・OS起動時にも自動起動
・指定したHTMLが配置済み
・localhostへHTTPアクセスすると200が返る

という状態にすることです。

利用した主なAnsibleモジュールは、

  • dnf
  • service
  • copy
  • uri

です。

Playbookのイメージは以下です。

---
- name: Configure Apache web server
  hosts: web
  become: true

  tasks:
    - name: Install Apache
      ansible.builtin.dnf:
        name: httpd
        state: present

    - name: Enable and start Apache
      ansible.builtin.service:
        name: httpd
        state: started
        enabled: true

    - name: Deploy test page
      ansible.builtin.copy:
        dest: /var/www/html/index.html
        content: |
          <h1>AWS Ansible Lab</h1>

    - name: Verify Apache locally
      ansible.builtin.uri:
        url: http://127.0.0.1/
        status_code: 200

初回実行

Playbookを実行すると、

ok=5
changed=3
unreachable=0
failed=0

となりました。

changed=3 は、Ansibleが実際に対象サーバの状態を変更した、という意味です。


2回目の実行で changed=0

同じPlaybookをもう一度実行しました。

結果は、

ok=5
changed=0
unreachable=0
failed=0

でした。

ここが今回、一番「Ansibleらしい」と感じた部分です。

すでに目的の状態になっているため、Ansibleは不要な変更を行いません。

望む状態
    ↓
現在状態を確認
    ↓
すでに一致
    ↓
何もしない

これが 冪等性(idempotency) です。


外部からApacheへアクセス

web01自身からのHTTP確認だけでなく、WSLからweb01のPublic IPv4へアクセスしてHTTP 200も確認しました。

WSL
 ↓ HTTP
Internet
 ↓
AWS
 ↓
web01
 ↓
Apache

返ってきたHTMLには、

<h1>AWS Ansible Lab</h1>
<p>Apache deployed by Ansible.</p>

が含まれていました。

Ansibleで配置したHTMLが、実際に外部から見えるところまで確認できました。


失敗もかなりあった

今回のログは、成功した操作だけではありません。

例えば、

  • GitのAuthor情報が設定されておらずcommitできなかった
  • 一度仮のメールアドレスでcommitした
  • Ansibleの成功出力をそのままシェルへ貼ってしまった
  • SSH鍵を作り直した
  • コマンドの出力を次のコマンドだと誤認した
  • pagerやheredocの挙動が分からず混乱した

といったこともありました。

個人的には、ここを消さずに残しておくことにしました。

成功例だけを見ても、「なぜそのコマンドが必要なのか」が分からないからです。


GitHubへ成果物を残す

最終的に、以下をGitで管理する形にしました。

infrastructure/aws-ansible-lab/
├── README.md
└── ansible/
    ├── apache.yml
    └── inventory.example.ini

実環境用の inventory.ini はGit管理対象から除外し、公開用に inventory.example.ini を用意しました。

変更内容を確認してから、

git add ...
git diff --cached
git commit -m "Add Ansible Apache lab implementation and verification"
git push

という流れでGitHubへ反映しました。


今回やってみて分かったこと

今回の学習前は、

AWS
Git
SSH
Ansible
Apache

が、ほぼ別々の単語に見えていました。

実際に一度構築したことで、ようやく、

Git
= 作ったものと変更履歴を残す

AWS
= ネットワークと仮想サーバを用意する

SSH
= サーバへ安全に接続する

Ansible
= SSHなどを使ってサーバを目的の状態にする

Apache
= 実際にWebページを返す

という役割分担が見えてきました。

まだコマンドを何も見ずに書ける段階ではありません。

むしろ、今回の構築が終わってからログを見返して初めて、

「VPCってそういう意味だったのか」
「Inventoryは接続先一覧なのか」
「changed=0ってこういうことか」

と理解し始めています。


AIとの共同作業について

今回の構築では、対話AI「カレン」にかなり先生役をしてもらいました。

ただし、自分の中では、

人間が指示してAIに完成品を作らせる

という関係ではなく、

自分:
実際に操作する
分からないことを言語化する
結果を返す
疑問を出す

カレン:
次の操作を提案する
ログを読む
失敗原因を整理する
概念を説明する
理解できていない点を分解する

という共同作業として捉えています。

特に今回は、

まずやってみないと、何が分からないのかすら分からない

という状態から始めました。

AIから答えだけを受け取るのではなく、実際の操作ログを材料に何度も振り返ることで、ようやく「コマンド」と「概念」がつながってきました。

今後も、AIを単なる自動化ツールとしてではなく、先生・共同研究者・レビュー相手として使いながら、実際に手を動かして理解を深めていくつもりです。


まとめ

今回やったことを一文でまとめると、

Gitで学習成果を履歴管理しながら、AWS上にネットワークと2台のEC2を構築し、SSHで接続し、Ansibleでweb01へApacheを自動構築して、冪等性まで確認した。

です。

まだ「AWSやAnsibleを理解した」と言える段階ではありません。

でも、

分からない
↓
実際にやる
↓
ログを残す
↓
AIと一緒に振り返る
↓
構造を理解する

という学び方は、自分にはかなり合っていると感じました。

次は、今回触ったものを、

  • Git
  • AWSネットワーク
  • SSH
  • Ansible
  • Linux Shell

のようにレイヤーごとに分けて、もう一段細かく復習していく予定です。

red@Debian13:~$

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?