AnsibleでAWS上にNginx・PHP・MariaDBを自動構築する実践手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Ansible > AnsibleでAWS上にNginx・PHP・MariaDBを自動構築する実践手順
「AWSのEC2に毎回手作業でNginxやPHPを入れている」「環境を再現しようとしたら設定が違っていた」
こういう悩みを抱えているLinuxエンジニアは少なくありません。

この記事では、AnsibleをつかってAWS EC2上にNginx・PHP・MariaDBを自動構築する実践的な手順を解説します。
Inventoryファイルの設計からRole分割、Playbookの実行・確認まで、現場で再現できるレベルで説明します。

この記事のポイント

・ansible-playbookコマンド1本でEC2にLEMP環境を自動構築できる
・RoleでNginx・PHP・MariaDBを分離すれば再利用性が大きく上がる
・Inventoryに接続情報を集約することで複数台管理も一元化できる
・AWSセキュリティグループのポート開放を事前に忘れると接続でつまずく


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

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" # }

「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サーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Linux無料マニュアルを受け取る >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。