2021/08/26

Ansibleを利用したAWS VPC自動構築について

 
  

Ansibleの自動構築について


Ansibleを使用して、自動的にAWSのVPC構築する方法を記載します。

VPC構築は、同じような構成になることが多く、自動化する方が効率良くなります。一つのAWSアカウントに対して、VPCが一つの場合もありますが、マイクロサービス化が主流となっている今日では、AWSアカウントに複数のVPCが存在するケースが多くなってきました。

同じようなVPC構成が多いため、Ansibleを利用して各VPCの設定を簡単に構築できるようにします。

基本となるVPC構成を考えよう

システムのVPC構成は、役割ごとにSubnetを組み、セキュリティを考慮してSubnet間でポートの開放を設定します。

会社によっては、全てパブリックなサブネットに所属している場合もあります。セキュリティを考慮して、Webサーバ以外はパブリックなサブネットに所属(インターネットゲートウェイをルーティングに追加)せず、プライベートサブネットに配置して、インターネット上の接続は、NATゲートウェイ経由で接続するようにします。

AnsibleのPlaybookを作る前に必要なこと


Ansibleは、Pythonで組まれているため、AWSモジュールを利用するときにboto3が必要になります。

pip コマンドを利用して、以下のモジュールをインストールします。

pip install boto3https://docs.ansible.com/ansible/latest/scenario_guides/g…

Ansible で profile パラメータを利用するためには

awscliが入っていると、プロフィール設定で接続先を切り替えられるので、複数のAWS環境で実行する時に便利です。

Ansibleの変数にアクセスキーとシークレットキーを設定し、Ansible Voltで暗号化して保持させても良いですし、環境変数を利用しても構いません。

この記事には記載しませんが、profile パラメータを使用した切り替えも可能になっています。

インストールしておくと、今後のデバック作業も簡潔になるため、以下のコマンドでawscliをインストールします。

pip install awsclihttps://pypi.org/project/awscli/

Ansible で AWS を構築するを利用するときには、ansible-galaxy を利用しよう

Ansible 2.10以上になると、ansible-galaxyのCommunity AWS Collectionを利用できます。

Ansible 2.9 以下は、Ansibleのドキュメント内に含まれるCloud Moduleを利用します。Ansibleのバージョンを2.10以上にできない場合は、適したAnsibleのバージョンを指定して、ドキュメントに沿って作成して下さい。

ansible-galaxyが使えないため、AWSの自動構築ができないことはありません。AWS関連モジュールのTaskが異なるだけで、設定値は同じです。

Ansible 2.10以上を利用する場合は、以下のコマンドでCommunity AWS Collectionを追加します。

ansible-galaxy collection install amazon.awshttps://galaxy.ansible.com/amazon/aws

Ansible を利用して、AWS VPC を作成しよう

Examplesを参考に、AWS認証情報を付与すると以下のようになります。

# Ansible 2.10以上
- name: create VPC
  amazon.aws.ec2_vpc_net:
    name: sample_vpc
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    cidr_block: 10.1.0.0/16
    region: ap-northeast-1
    tags:
      module: ec2_vpc_net
      this: works
    register: vpc_id
# Ansible 2.9以下
- name: create a VPC with dedicated tenancy and a couple of tags
  ec2_vpc_net:
    name: test_vpc
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    cidr_block: 10.1.0.0/16
    region: ap-northeast-1
    tags:
      module: ec2_vpc_net
      this: works
    register: vpc_id

ExamplesのNoteに記載があるように、サンプルにはAWSの認証情報は含まれていません。記載したサンプルには、AWS認証情報と実行結果を取得するパラメータを追加しています。

認証情報は、AWSコンソールのIAMから取得したアクセスキーとシークレットキーをAnsible変数に設定していることを前提とします。

サンプルから追加したパラメータは、以下の一覧になります。

パラメータ名 パラメータ設定値
aws_access_key IAMの認証アクセスキー
aws_secret_key IAMの認証シークレットキー
register 実行結果を保存する変数名

region パラメータについて

AWSコンソールの上のメニューに地域名が記載されている部分がリージョンになります。
今回のサンプルでは、東京リージョンとしています。
設置するリージョンが東京リージョンでない場合は、該当するリージョン名を指定して下さい。

リージョンの一覧は、region パラメータの説明部分にリンクがあります。

実行結果を格納した変数の中身を理解しよう

AWS VPCの作成が成功すると、作成されたデータ構造がPythonの連想配列で設定されます。今後の作業で、作成されたVPCのidが必要になるため、registerの登録されたパラメータを利用していきます。

Task処理がエラーになった場合は、Ansibleの動作が停止します。エラー発生時に、異なるTaskを実行するのであれば、エラーを無視するパラメータが必要になります。

今回は、エラーが発生した場合は何もしないため、エラー発生時はAnsibleの動作が停止することになります。

作成した AWS VPC に、subent を追加しよう


役割ごとにSubnet を追加します。

プライベートサブネットは、サービスの規模にもよりますが、多く作成されるものとなりますので、今回はひとつだけプライベートサブネットを設けることにし、もう一つのサブネットは、パブリックなサブネットとします。

サブネットを作成するタスクは、Ansible2.10以上とAnsible2.9以下でTaskが異なるため、バージョンに沿ったTaskを利用します。

# Ansible 2.10以上
- name: Create Private subnets
  amazon.aws.ec2_vpc_subnet:
    state: present
    vpc_id: "{{ vpc_id.vpc.id }}"
    cidr: 10.1.1.0/24
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    region: ap-northeast-1
    register: sub_private
    tags:
      Name: private
- name: Create Public subnets
  amazon.aws.ec2_vpc_subnet:
    state: present
    vpc_id: "{{ vpc_id.vpc.id }}"
    cidr: 10.1.2.0/24
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    region: ap-northeast-1
    register: sub_public
    tags:
      Name: public
# Ansible 2.9以下
- name: Create subnets
  ec2_vpc_subnet:
    state: present
    vpc_id: "{{ vpc_id.vpc.id }}"
    cidr: 10.1.1.0/24
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    region: ap-northeast-1
    register: sub_private
    tags:
      Name: private
- name: Create subnets
  ec2_vpc_subnet:
    state: present
    vpc_id: "{{ vpc_id.vpc.id }}"
    cidr: 10.1.2.0/24
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    region: ap-northeast-1
    register: sub_public
    tags:
      Name: public

サンプルコードを利用して、publicとprivateのサブネットを追加しました。追加されたサブネットの情報は、register パラメータの変数に格納されます。

冗長的な記載の場合は、with_items を利用しよう

with_items パラメータを利用すると、publicとprivateを同時に登録できます。

今回はわかりやすくするため、publicとprivateを個別に登録する記載にしています。利用方法は、Ansibleドキュメントで検索してください。

AWS VPC の subnet にセキュリティを追加しよう


subnetに接続可能なポートを開放します。

AWS VPC 内のsubnetに対するセキュリティ追加は、パラメータのgroup_idを利用します。

今回の例では、パブリックなサブネットに、tcp ポートのHTTP(80)とHTTPS(443)の2種類を追加することにし、プライベートなサブネットに、tcp ポートのMySQL(3306)を追加することにします。

作成済みのpublicとprivateのセキュリティを追加するサンプルは、以下になります。

# Ansible 2.10 以上
- name: public subnet group
  amazon.aws.ec2_group:
    name: web
    description: web security group
    vpc_id: "{{ vpc_id.vpc.id }}"
    region: ap-north-east-1
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    rules:
      - proto: tcp
        from_port: 80
        to_port: 80
        cidr_ip: 0.0.0.0/0
        group_id: "{{ sub_public.subnet.id }}"
      - proto: tcp
        from_port: 443
        to_port: 443
        cidr_ip: 0.0.0.0/0
        group_id: "{{ sub_public.subnet.id }}"
- name: private subnet group
  amazon.aws.ec2_group:
    name: mysql
    description: mysql security group
    vpc_id: "{{ vpc_id.vpc.id }}"
    region: ap-north-east-1
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    rules:
      - proto: tcp
        from_port: 3306
        to_port: 3306
        cidr_ip: 10.0.0.0/8
        group_id: "{{ sub_private.subnet.id }}"
# Ansible 2.9 以下
- name: public subnet group
  ec2_group:
    name: web
    description: web security group
    vpc_id: "{{ vpc_id.vpc.id }}"
    region: ap-northeast-1
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    rules:
      - proto: tcp
        from_port: 80
        to_port: 80
        cidr_ip: 0.0.0.0/0
        group_id: "{{ sub_public.subnet.id }}"
      - proto: tcp
        from_port: 443
        to_port: 443
        cidr_ip: 0.0.0.0/0
        group_id: "{{ sub_public.subnet.id }}"
- name: private subnet group
  ec2_group:
    name: mysql
    description: mysql security group
    vpc_id: "{{ vpc_id.vpc.id }}"
    region: ap-northeast-1
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    rules:
      - proto: tcp
        from_port: 3306
        to_port: 3306
        cidr_ip: 10.0.0.0/8
        group_id: "{{ sub_private.subnet.id }}"

AWS VPC に インターネットゲーウェイを追加しよう


外部接続ができるように、インターネットゲートウェイをAWS VPCに追加します。

パブリックなサブネットと表現していてもインターネット接続されていなければ、外部からの接続ができません。

Ansible 2.10以上の場合、異なるコレクションにタスクが含まれているため、以下のコマンドでコレクションを追加します。

ansible-galaxy collection install community.awshttps://docs.ansible.com/ansible/latest/collections/commu…

インターネットゲートウェイを作成しよう

インターネットゲーウェイの作成は、Ansibleのバージョンに沿ったタスクを利用して作成します。

作成するサンプルは、以下のようになります。

# Ansible 2.10 以上
- name: create internet gateway
  community.aws.ec2_vpc_igw:
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    region: ap-northeast-1
    vpc_id: "{{ vpc_id.vpc.id }}"
    state: present
    tags:
      Name: internet gateway
    register: igw
# Ansible 2.9 以下
- name: create internet gateway
  ec2_vpc_igw:
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    region: ap-northeast-1
    vpc_id: "{{ vpc_id.vpc.id }}"
    state: present
    tags:
      Name: internet gateway
  register: igw

AWS VPC のルーティングを設定しよう


パブリックなサブネットが外部インターネットと通信するために必要になるため、作成したインターネットゲートウェイをパブリックなサブネットとルーティングさせます。

Ansibleのバージョンによってタスクが異なるため、利用しているバージョンに沿ってタスクを使用します。

サンプルは、以下になります。

# Ansible 2.10 以上
- name: Set up public subnet route table
  community.aws.ec2_vpc_route_table:
    vpc_id: "{{ vpc_id.vpc.id }}"
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    region: ap-northeast-1
    tags:
      Name: Public
    subnets:
      - "{{ sub_public.subnet.id }}"
    routes:
      - dest: 0.0.0.0/0
        gateway_id: "{{ igw.gateway_id }}"
# Ansible 2.9 以下
- name: Set up public subnet route table
  ec2_vpc_route_table:
    vpc_id: "{{ vpc_id.vpc.id }}"
    aws_access_key: "{{ AWS_ACCESS_KEY }}"
    aws_secret_key: "{{ AWS_SECRET_KEY }}"
    region: ap-northeast-1
    tags:
      Name: Public
    subnets:
      - "{{ sub_public.subnet.id }}"
    routes:
      - dest: 0.0.0.0/0
        gateway_id: "{{ igw.gateway_id }}"

Ansibleを使って、基本ネットワーク構造を自動構築しよう!

今回の自動化設定を利用することで、AWSインフラを作成するときは、設定値を変更するだけで同様のVPC設定を作成できます。

今回の例では、MySQLとWebサーバを対象としたため、NATゲートウェイには触れていません。インターネットゲートウェイと同様に、NATゲートウェイを作成し、プライベートなサブネットのルーティングに追加することによって、インターネットと接続できるようになります。

NATゲートウェイを利用して通信する場合は、また別の記事を参考にしてください。

冗長的な記載になりますが、Ansibleのテンプレート(Jinja2)と、Ansibleの変数を利用するともっとスマートに記載できます。

ITエンジニアへのキャリアチェンジならキャリアチェンジアカデミー

この記事の監修者・著者

株式会社オープンアップITエンジニア
株式会社オープンアップITエンジニア
未経験からITエンジニアへのキャリアチェンジを支援するサイト「キャリアチェンジアカデミー」を運営。これまで4500人以上のITエンジニアを未経験から育成・排出してきました。
・AWS、salesforce、LPICの合計認定資格取得件数:2100以上(2023年6月時点)
・AWS Japan Certification Award 2020 ライジングスター of the Year 受賞

おすすめの動画

  • 【未経験からIT業界へ転職するなら】相談窓口とスキルの獲得はここで解決!IT転職が一気に有利に!【キャリアチェンジアカデミー】

  • 【費用一切不要】未経験からIT業界へ転職するならまずはここへ相談!【キャリアチェンジアカデミー】

  • 【何のエンジニアになれるのか?】未経験からITエンジニアを目指すとこんな道がある【キャリアチェンジアカデミー】