こういう悩みを抱えているLinuxエンジニアは少なくありません。
この記事では、AnsibleをつかってAWS EC2上にNginx・PHP・MariaDBを自動構築する実践的な手順を解説します。
Inventoryファイルの設計からRole分割、Playbookの実行・確認まで、現場で再現できるレベルで説明します。
この記事のポイント
・ansible-playbookコマンド1本でEC2にLEMP環境を自動構築できる
・RoleでNginx・PHP・MariaDBを分離すれば再利用性が大きく上がる
・Inventoryに接続情報を集約することで複数台管理も一元化できる
・AWSセキュリティグループのポート開放を事前に忘れると接続でつまずく
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
Ansible × AWS 構築の概要と前提知識
AnsibleはSSH経由でリモートホストを操作する構成管理ツールです。エージェントレスで動作するため、管理対象のEC2にAnsible自体をインストールする必要はありません。
操作を実行するコントロールノード(手元のLinuxマシンやCloud Shell)にAnsibleを入れるだけで準備完了です。
今回の構成は以下のとおりです。
・コントロールノード: Amazon Linux 2023(EC2)またはローカルLinux環境
・管理対象ノード: Amazon Linux 2023(EC2 t3.micro)
・Ansible: 2.15以上
・構築対象ミドルウェア: Nginx 1.24系・PHP 8.2・MariaDB 10.11
動作確認済み環境: Amazon Linux 2023 / Ansible 2.15.9
AWS環境の事前準備(EC2・VPC・セキュリティグループ)
Ansibleを実行する前に、AWSのインフラ側の設定を整えておく必要があります。ここを省いて作業を進めると、後でSSH接続できない・Nginxに外部からアクセスできないといった問題でつまずきます。
1. EC2インスタンスを起動する
AWSマネジメントコンソールまたはAWS CLIでEC2を起動します。AMIは「Amazon Linux 2023」を選択してください。
# AWS CLIでEC2インスタンスを起動する例 aws ec2 run-instances \ --image-id ami-0123456789abcdef0 \ --instance-type t3.micro \ --key-name my-keypair \ --security-group-ids sg-xxxxxxxxxxxxxxxxx \ --subnet-id subnet-xxxxxxxxxxxxxxxxx \ --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=ansible-target}]'
2. セキュリティグループの設定
管理対象EC2のセキュリティグループには、以下の3つのインバウンドルールを設定します。| プロトコル | ポート | ソース | 用途 |
|---|---|---|---|
| TCP | 22 | コントロールノードのIP | Ansible SSH接続 |
| TCP | 80 | 0.0.0.0/0 | Nginxへのアクセス確認 |
| TCP | 443 | 0.0.0.0/0 | HTTPS(任意) |
3. SSH疎通確認
Ansibleを実行する前に、必ずSSH接続できることを確認します。# 秘密鍵のパーミッションを正しく設定する chmod 400 ~/.ssh/my-keypair.pem # SSH接続テスト ssh -i ~/.ssh/my-keypair.pem ec2-user@203.0.113.10 # 接続成功時の出力例(ホスト名・IPはマスク) # , #_ # ~\_ ####_ Amazon Linux 2023 # ~~ \_#####\ # ~~ \###| # ~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023 # ~~ V~' '-> # ~~~ / # ~~._. _/ # _/ _/ # _/m/' [ec2-user@ip-10-0-1-**]$
Inventoryファイルの設計と接続設定
AnsibleのInventoryファイルは、管理対象ホストの一覧と接続情報を定義するファイルです。今回はINI形式で作成します。
1. ディレクトリ構造
作業ディレクトリをあらかじめ作成しておきます。mkdir -p ~/ansible-aws/{inventory,roles,group_vars} cd ~/ansible-aws # ディレクトリ構成 ls -la # drwxr-xr-x 5 ec2-user ec2-user 85 6月 26 10:00 . # drwxr-xr-x 14 ec2-user ec2-user 4096 6月 26 10:00 .. # drwxr-xr-x 2 ec2-user ec2-user 6 6月 26 10:00 group_vars # drwxr-xr-x 2 ec2-user ec2-user 6 6月 26 10:00 inventory # drwxr-xr-x 2 ec2-user ec2-user 6 6月 26 10:00 roles
2. Inventoryファイルの作成
# ~/ansible-aws/inventory/hosts [webservers] 203.0.113.10 ansible_user=ec2-user ansible_ssh_private_key_file=~/.ssh/my-keypair.pem [webservers:vars] ansible_python_interpreter=/usr/bin/python3
3. Ansible設定ファイル(ansible.cfg)
# ~/ansible-aws/ansible.cfg [defaults] inventory = ./inventory/hosts remote_user = ec2-user private_key_file = ~/.ssh/my-keypair.pem host_key_checking = False retry_files_enabled = False
4. 接続確認(ping モジュール)
Playbookを実行する前に、Ansibleのpingモジュールで接続できることを確認します。ansible webservers -m ping # 成功時の出力例 # 203.0.113.10 | SUCCESS => { # "ansible_facts": { # "discovered_interpreter_python": "/usr/bin/python3" # }, # "changed": false, # "ping": "pong" # }
Ansibleの基礎からしっかり学びたい方へ
Ansibleを使いこなすには、Linux・SSH・YAMLの基礎を体系的に理解していることが大前提です。
現役エンジニアによるハンズオン形式のセミナーで、実務で使える構成管理スキルを身につけませんか。
>> Ansible実践セミナーの詳細はこちら
Role設計——Nginx・PHP・MariaDB を役割ごとに分離する
Ansibleには「Role」という機能があり、タスクをミドルウェア単位でモジュール化できます。Roleを使わずに1つのPlaybookに全部書く方法もありますが、Roleで分離しておくと再利用・テストが格段に楽になります。
1. Role用ディレクトリを作成する
cd ~/ansible-aws # 3つのRoleを作成 ansible-galaxy role init roles/nginx ansible-galaxy role init roles/php ansible-galaxy role init roles/mariadb # 作成後の構成 tree roles/ # roles/ # ├── mariadb # │ ├── defaults/main.yml # │ ├── handlers/main.yml # │ ├── tasks/main.yml # │ └── templates/ # ├── nginx # │ ├── defaults/main.yml # │ ├── handlers/main.yml # │ ├── tasks/main.yml # │ └── templates/ # └── php # ├── defaults/main.yml # ├── handlers/main.yml # ├── tasks/main.yml # └── templates/
2. Nginx Roleのタスク定義
# roles/nginx/tasks/main.yml --- - name: Nginxをインストールする ansible.builtin.dnf: name: nginx state: present - name: Nginxを起動・自動起動設定 ansible.builtin.systemd: name: nginx state: started enabled: true - name: Nginx設定ファイルを配置する ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf owner: root group: root mode: '0644' notify: Reload nginx
# roles/nginx/handlers/main.yml --- - name: Reload nginx ansible.builtin.systemd: name: nginx state: reloaded
3. PHP Role のタスク定義
# roles/php/tasks/main.yml --- - name: PHP 8.2 および関連パッケージをインストールする ansible.builtin.dnf: name: - php8.2 - php8.2-fpm - php8.2-mysqlnd - php8.2-mbstring - php8.2-xml state: present - name: PHP-FPMを起動・自動起動設定 ansible.builtin.systemd: name: php-fpm state: started enabled: true
4. MariaDB Role のタスク定義
# roles/mariadb/tasks/main.yml --- - name: MariaDBをインストールする ansible.builtin.dnf: name: - mariadb105-server - python3-PyMySQL state: present - name: MariaDBを起動・自動起動設定 ansible.builtin.systemd: name: mariadb state: started enabled: true - name: MariaDBのrootパスワードを設定する community.mysql.mysql_user: name: root password: "{{ mariadb_root_password }}" login_unix_socket: /var/lib/mysql/mysql.sock state: present no_log: true - name: アプリ用データベースを作成する community.mysql.mysql_db: name: "{{ mariadb_app_db }}" state: present login_user: root login_password: "{{ mariadb_root_password }}" - name: アプリ用ユーザーを作成する community.mysql.mysql_user: name: "{{ mariadb_app_user }}" password: "{{ mariadb_app_password }}" priv: "{{ mariadb_app_db }}.*:ALL" state: present login_user: root login_password: "{{ mariadb_root_password }}" no_log: true
5. group_vars で変数を一元管理する
パスワードなどの変数はPlaybook内にハードコードせず、group_varsに集約します。本番環境ではansible-vaultで暗号化してください。
# ~/ansible-aws/group_vars/webservers.yml --- mariadb_root_password: "Change_Me_Str0ng!" mariadb_app_db: "appdb" mariadb_app_user: "appuser" mariadb_app_password: "App_Passw0rd!"
Playbookの実行と動作確認
1. メインPlaybookを作成する
3つのRoleをまとめて呼び出すPlaybookを作成します。# ~/ansible-aws/site.yml --- - name: Nginx + PHP + MariaDB を EC2 に構築する hosts: webservers become: true roles: - nginx - php - mariadb
2. --check オプションでドライランを実施する
実際に変更を加える前に、`--check` オプションで変更内容を確認します。ansible-playbook site.yml --check # 実行例(一部抜粋) # PLAY [Nginx + PHP + MariaDB を EC2 に構築する] ********************** # # TASK [nginx : Nginxをインストールする] ********************************** # ok: [203.0.113.10] # # TASK [nginx : Nginxを起動・自動起動設定] ******************************* # changed: [203.0.113.10] # # PLAY RECAP ************************************************************ # 203.0.113.10 : ok=8 changed=5 unreachable=0 failed=0
3. Playbookを本番実行する
ansible-playbook site.yml # 成功時の最終出力例 # PLAY RECAP ************************************************************ # 203.0.113.10 : ok=14 changed=10 unreachable=0 failed=0 skipped=0
4. 動作確認
Playbookが正常に完了したら、ブラウザとSSHから動作を確認します。# SSH で管理対象EC2にログインして確認 ssh -i ~/.ssh/my-keypair.pem ec2-user@203.0.113.10 # Nginx 動作確認 systemctl status nginx # * nginx.service - The nginx HTTP and reverse proxy server # Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: disabled) # Active: active (running) since Thu 2026-06-26 10:15:33 UTC; 2min 48s ago # PHP-FPM 動作確認 php -v # PHP 8.2.18 (cli) (built: Apr 9 2026 12:00:00) (NTS) # Copyright (c) The PHP Group # MariaDB 動作確認 mysql -u root -p -e "SHOW DATABASES;" # +--------------------+ # | Database | # +--------------------+ # | appdb | # | information_schema | # | mysql | # | performance_schema | # | sys | # +--------------------+ # ブラウザ確認(コントロールノードからcurl) curl -I http://203.0.113.10 # HTTP/1.1 200 OK # Server: nginx/1.24.0 # Content-Type: text/html
5. トラブルシュート——よくあるエラーと対処法
| エラーメッセージ | 原因 | 対処 |
|---|---|---|
| UNREACHABLE! Connection timed out | セキュリティグループのSSH(22番)が未開放 | インバウンドルールにコントロールノードのIPを追加 |
| Permission denied (publickey) | 秘密鍵のパスが誤り、またはパーミッションが400以外 | chmod 400 ~/.ssh/my-keypair.pem を実行して再試行 |
| No package nginx available | dnfリポジトリが古い、またはamazon-linux-extraが未設定 | sudo dnf update -y を先に実行 |
| Access denied for user 'root'@'localhost' | MariaDB初回起動直後はunix_socket認証が有効 | タスクに login_unix_socket を明示して再実行 |
まとめ・次のステップ
この記事では、AnsibleをつかってAWS EC2上にNginx・PHP・MariaDBを自動構築する手順を解説しました。| やりたいこと | Ansibleの操作・設定 |
|---|---|
| 管理対象ホストを定義する | inventory/hosts にIPと接続情報を記述 |
| SSH接続を確認する | ansible webservers -m ping |
| Roleを作成する | ansible-galaxy role init roles/nginx |
| 変更内容を事前確認する | ansible-playbook site.yml --check |
| Playbookを本番実行する | ansible-playbook site.yml |
次のステップとして、以下のような応用を検討してみてください。
・ansible-vault: group_vars内のパスワードを暗号化して安全に管理する
・動的Inventory: AWS EC2プラグインでIPを自動取得し、ホストを手動管理しない構成に移行する
・CI/CDとの連携: GitHub ActionsからPlaybookを自動実行し、インフラ変更をコードレビューに乗せる
関連記事:
・Linux DNS 設定の基本(resolv.conf・nmcliの設定方法)
・Linux ポート確認の全コマンド(ss・lsof・netstat)
・Apache タイムアウト設定の詳細(Timeout・ProxyTimeout)
・mount コマンドの使い方(fstab・マウント手順)
・ntpd 時刻同期設定(chrony対応)
AnsibleでAWS構築を体系的に学びたい方へ
Playbookの書き方・Role設計・Vault暗号化・CI/CD連携まで、実機環境で手を動かしながら習得できます。
独学でつまずいている方は、現役エンジニアが指導するハンズオンセミナーで一気に理解を深めましょう。
>> Ansible実践セミナーの詳細・申込はこちら
Linux無料マニュアルを受け取る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 次のページへ:Ansibleのinventory・role・module設計|現場で崩れない構成管理の基礎
- 前のページへ:手作業のサーバー設定から卒業する|構成管理ツールAnsibleの入門ハンズオン
- この記事の属するカテゴリ:Ansibleへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます