AWSもAnsibleもよく分からない状態から、AIと一緒に「動くところ」まで作ってみた
この記事は、筆者と対話AI「カレン」との共同作業です。
「AIに全部やらせた記録」ではなく、分からないことを実際に手を動かしながら学び、AIに先生・伴走者として説明してもらい、一緒に構築した記録として書いています。筆者は開始時点で、Git・AWS・Ansibleの各コマンドや役割を十分には理解していませんでした。
そのためこの記事では、完成品を誇るというより、分からないまま一度やってみて、あとから構造を理解していく学習方法そのものも含めて残します。
はじめに
AWS、Git、SSH、Ansible。
名前は知っていても、
- Gitは何をしているのか
- VPCとSubnetは何が違うのか
- Security GroupはLinuxのFirewallとどう違うのか
- AnsibleはSSHと何が違うのか
- Playbookとは何なのか
と聞かれると、かなり曖昧でした。
そこで今回は、最初から全部理解しようとするのをやめて、
- まず実際に構築する
- 動作を確認する
- ログを残す
- そのログを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が、
- SSHで接続
- 対象側でPythonを使う
- Ansibleモジュールを実行
-
pongを返す
ところまで確認しています。
ApacheをPlaybookで構築する
今回作ったPlaybookの目的は、
web01に
・Apacheがインストール済み
・Apacheが起動中
・OS起動時にも自動起動
・指定したHTMLが配置済み
・localhostへHTTPアクセスすると200が返る
という状態にすることです。
利用した主なAnsibleモジュールは、
dnfservicecopyuri
です。
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:~$