「VPCとEC2を別々のPlaybookに分けたが、どちらを先に流せばいいのか毎回迷う」
このエラーが出た時点で、設計に根本的な問題があります。EC2インスタンスはVPCの中に置くリソースです。VPCがなければサブネットも存在せず、EC2に渡すsubnet_idを得ることができません。
この記事では、AnsibleでAWS環境を構築する際の「リソース作成の順序設計」を解説します。VPCから始めてサブネット・IGW・セキュリティグループを用意してからEC2を起動するまでの流れを、Playbookの依存関係とregister変数の使い方を軸に説明します。
動作確認環境: Ansible 9.x / amazon.aws collection 8.x / Python 3.11 / RHEL 9.4
この記事のポイント
・VPC→サブネット→IGW→SG→EC2の順序を守らないとPlaybookは動かない
・register変数でVPC作成結果のIDをEC2タスクへ引き渡す
・role分割でVPCネットワーク層とEC2起動層の依存を明示的に管理する
・subnet_id/vpc_idが見つからないエラーは順序と変数名のミスが原因の9割
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
VPCを先に用意しないとEC2のPlaybookは成立しない
AWSのリソースには親子関係があります。EC2インスタンスはサブネットの中に作るため、サブネットが先に存在していなければEC2タスクは実行できません。サブネットはVPCの中に作るため、VPCが先に存在していなければサブネットタスクは実行できません。この依存チェーンを図にすると次のようになります。
VPC(アドレス空間の定義) └─ サブネット(AZへの分散配置) └─ ルートテーブル(外への出口の設定) └─ インターネットゲートウェイ(パブリック接続) セキュリティグループ(ポートのホワイトリスト) └─ EC2インスタンス(起動先サブネットとSGを指定して初めて作れる)
前提:amazon.awsコレクションの準備とAWS認証
1. amazon.awsコレクションのインストール
AWSリソースを操作するためのAnsibleモジュールはamazon.awsコレクションに含まれています。標準のansible.builtinには含まれていないため、別途インストールが必要です。# コレクションのインストール ansible-galaxy collection install amazon.aws # バージョン確認 ansible-galaxy collection list amazon.aws
# /home/ansible/.ansible/collections/ansible_collections Collection Version ------------- ------- amazon.aws 8.2.1
2. AWS認証情報の設定
Playbookの実行前にAWS認証情報を環境変数に設定します。IAMユーザーのアクセスキーを使う場合は以下の形式です。export AWS_ACCESS_KEY_ID=AKIA...(取得したキーIDを設定) export AWS_SECRET_ACCESS_KEY=wJal...(取得したシークレットを設定) export AWS_REGION=ap-northeast-1
VPCとネットワーク層を先に作るPlaybook設計
1. VPCの作成(network/vpc.yml)
ネットワーク層のPlaybookファイルを作成します。最初にVPCそのものを定義し、CIDRブロックで全体のアドレス空間を確保します。--- - name: VPCとネットワーク層を構築 hosts: localhost connection: local gather_facts: false vars: region: ap-northeast-1 vpc_cidr: "10.0.0.0/16" public_subnet_cidr: "10.0.1.0/24" private_subnet_cidr: "10.0.2.0/24" az: "ap-northeast-1a" tasks: - name: VPCを作成する amazon.aws.ec2_vpc_net: name: "production-vpc" cidr_block: "{{ vpc_cidr }}" region: "{{ region }}" tags: Environment: production register: vpc_result - name: VPC IDを表示して確認 ansible.builtin.debug: msg: "VPC ID: {{ vpc_result.vpc.id }}"
2. サブネットの作成(パブリック・プライベートの2層)
VPCのIDを受け取ってサブネットを2つ作成します。パブリックサブネットにはEC2(Webサーバー等)を、プライベートサブネットにはDBやバックエンドを置く設計です。- name: パブリックサブネットを作成する amazon.aws.ec2_vpc_subnet: vpc_id: "{{ vpc_result.vpc.id }}" cidr: "{{ public_subnet_cidr }}" az: "{{ az }}" map_public: true region: "{{ region }}" tags: Name: "public-subnet-1a" Tier: public register: public_subnet_result - name: プライベートサブネットを作成する amazon.aws.ec2_vpc_subnet: vpc_id: "{{ vpc_result.vpc.id }}" cidr: "{{ private_subnet_cidr }}" az: "{{ az }}" region: "{{ region }}" tags: Name: "private-subnet-1a" Tier: private register: private_subnet_result
3. インターネットゲートウェイとルートテーブルの設定
パブリックサブネットからインターネットへ出るためのゲートウェイを作成し、ルートテーブルで0.0.0.0/0宛トラフィックをIGW経由に設定します。- name: インターネットゲートウェイを作成する amazon.aws.ec2_vpc_igw: vpc_id: "{{ vpc_result.vpc.id }}" region: "{{ region }}" tags: Name: "production-igw" register: igw_result - name: パブリックサブネット用のルートテーブルを作成する amazon.aws.ec2_vpc_route_table: vpc_id: "{{ vpc_result.vpc.id }}" region: "{{ region }}" subnets: - "{{ public_subnet_result.subnet.id }}" routes: - dest: "0.0.0.0/0" gateway_id: "{{ igw_result.gateway_id }}" tags: Name: "public-rtb"
4. セキュリティグループの定義
EC2を起動する前に、どのポートを開けるかをセキュリティグループで定義します。- name: Webサーバー用のセキュリティグループを作成する amazon.aws.ec2_security_group: name: "web-sg" description: "Web server security group" vpc_id: "{{ vpc_result.vpc.id }}" region: "{{ region }}" rules: - proto: tcp from_port: 80 to_port: 80 cidr_ip: "0.0.0.0/0" - proto: tcp from_port: 443 to_port: 443 cidr_ip: "0.0.0.0/0" - proto: tcp from_port: 22 to_port: 22 cidr_ip: "10.0.0.0/8" tags: Name: "web-sg" register: sg_result
VPCリソースのIDをEC2 Playbookへ渡す設計
1. ネットワーク層の変数をファイルに書き出す
VPC構築PlaybookとEC2起動Playbookを別ファイルに分けると、register変数はPlaybook間で共有されません。IDを引き渡すには一度ファイルに書き出す方法が確実です。- name: ネットワーク層のIDをホスト変数として保存する ansible.builtin.copy: dest: ./network_ids.yml content: | vpc_id: "{{ vpc_result.vpc.id }}" public_subnet_id: "{{ public_subnet_result.subnet.id }}" private_subnet_id: "{{ private_subnet_result.subnet.id }}" web_sg_id: "{{ sg_result.group_id }}"
2. EC2インスタンスの起動タスク(ec2/launch.yml)
--- - name: EC2インスタンスを起動する hosts: localhost connection: local gather_facts: false vars_files: - ../network/network_ids.yml vars: region: ap-northeast-1 # Amazon Linux 2023 AMI(ap-northeast-1) ami_id: ami-0599b6e53ca798bb2 instance_type: t3.small tasks: - name: EC2インスタンスを起動する amazon.aws.ec2_instance: name: "web-server-01" image_id: "{{ ami_id }}" instance_type: "{{ instance_type }}" subnet_id: "{{ public_subnet_id }}" security_groups: - "{{ web_sg_id }}" region: "{{ region }}" network: assign_public_ip: true tags: Role: web Environment: production wait: true register: ec2_result - name: 起動したEC2のパブリックIPを確認する ansible.builtin.debug: msg: "Public IP: {{ ec2_result.instances[0].public_ip_address }}"
roleで依存関係をディレクトリ構造として表現する
タスク数が増えると、playbook単体で管理するのが煩雑になります。VPCネットワーク層とEC2起動層をroleに分けると、依存関係がディレクトリ構造として見えるようになります。roles/ ├── vpc_network/ │ └── tasks/ │ └── main.yml ← VPC・サブネット・IGW・SGを作成 └── ec2_launch/ └── tasks/ └── main.yml ← vpc_networkのregister変数を受け取ってEC2を起動 site.yml ← roleの実行順を明示
--- - name: AWS環境を構築する(ネットワーク→EC2の順序) hosts: localhost connection: local gather_facts: false roles: - vpc_network # 必ず先に実行 - ec2_launch # vpc_networkの完了後に実行
トラブルシュート|よくあるエラーと対処法
エラー1: subnet_id が見つからないfatal: [localhost]: FAILED! => {"msg": "The subnet ID 'subnet-xxxxxxxx' does not exist"}
エラー2: VPCのCIDRが重複している
An error occurred (InvalidVpc.Conflict) when calling the CreateVpc operation: The CIDR '10.0.0.0/16' conflicts with another vpc
エラー3: register変数のキーが変わった
amazon.awsコレクションのバージョンアップで、registerに格納されるキー名が変わることがあります。`ansible.builtin.debug: var: vpc_result` でregister変数の中身を出力して、正しいキーパスを確認してください。
# 変数の中身を確認するデバッグタスク - name: vpc_resultの構造を確認する ansible.builtin.debug: var: vpc_result
本記事のまとめ
| 作成するリソース | 使用するモジュール | 依存する先行リソース |
|---|---|---|
| VPC | amazon.aws.ec2_vpc_net |
なし(最初に作る) |
| サブネット | amazon.aws.ec2_vpc_subnet |
VPC ID |
| インターネットゲートウェイ | amazon.aws.ec2_vpc_igw |
VPC ID |
| ルートテーブル | amazon.aws.ec2_vpc_route_table |
VPC ID・サブネットID・IGW ID |
| セキュリティグループ | amazon.aws.ec2_security_group |
VPC ID |
| EC2インスタンス | amazon.aws.ec2_instance |
サブネットID・セキュリティグループID |
ネットワーク層とEC2層をroleに分けてsite.ymlで順序を明示することで、誰がPlaybookを読んでも実行順序が一目でわかる設計になります。チームでAWSを運用する現場ほど、この可読性が後の保守コストを下げます。
AnsibleによるAWS自動化をさらに深く学びたい方は、VPC設計からPlaybook設計・role構成まで体系的に解説した専門講座(Ansible講座 — LinuxMaster.JP)も参考にしてください。
Linux無料マニュアルを受け取る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:既存Playbookのtaskをroleへ移すAnsibleの移行手順|ファイル配置と参照パスの付け替え
- この記事の属するカテゴリ:Ansibleへ戻る

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