LoginSignup
7
6

More than 5 years have passed since last update.

Ansible で CloudFormation のスタック作成・削除

Posted at

Ansible を使って AWS の CloudFormation のスタックを作成および削除する方法のメモです。シンプルなスタックの管理は aws コマンドをシェルスクリプトでラップすれば良いのですが、テンプレートへの入力パラメータの管理と出力内容の再利用性を高めるために Ansible を使います。

Ansible の cloudformation モジュールのドキュメントはこちら。

作成するスタックは AWS の Quick Start にある VPC と Bastion を使います。

Bastion スタックには DependsOn を利用して新規に VPC スタックを構成するマスターテンプレートもありますが、ここではスタックの出力を Ansible の変数として受け渡すことを示すため、個別にテンプレートを呼び出します。

準備

まずは Ansible をインストールし、AWS の API を実行できるように Boto を追加します。

Ansible のインストールは Ubuntu だと以下のような作業になりますが、他のディストリビューションおよび macOS でもだいたい一緒です。利用環境に合わせて調整してください。

Ansibleのインストール
$ sudo apt-get install -y python-pip
$ sudo pip install -U pip
$ sudo pip install ansible==2.4.0

続いて Boto をインストールし、アクセスキーの情報を設定ファイル (~/.boto) に記載します。

boto3のインストール
$ sudo pip install boto3

アクセスキーの情報は利用するアカウントに合わせてください。CloudFormation の作成や削除の権限以外に、スタックの中で管理するリソースに関する権限が必要になります。Bastion スタックでは IAM の Role 関係の権限が必要です。

~/.boto
[Credentials]
aws_access_key_id = xxxxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxx

Ansible の変数ファイルを group_vars/all.yml として用意します。踏み台ホスト (bastion) へのアクセスを許可する IP アドレスを remote_global_ip_addr と定義していますが、実行環境のネットワークに応じて値を変更してください。また、リージョンやAZ、キーペア、スタック名なども調整してください。

group_vars/all.yml
---

remote_global_ip_addr: "aaa.bbb.ccc.ddd/32"

aws_region: ap-northeast-1
aws_ec2_keypair_bastion:
  name: bastion
  private_key_file: ~/.ssh/keys/aws_bastion.pem

aws_cfn_stack_name: "Example"
aws_cfn_vpc_stack_name: "{{ aws_cfn_stack_name }}VPC"
aws_cfn_vpc_availability_zones: "ap-northeast-1b,ap-northeast-1c"
aws_cfn_vpc_qs_template_url: "https://s3.amazonaws.com/quickstart-reference/aws/vpc/latest/templates/aws-vpc.template"
aws_cfn_vpc_qs_keypair: "{{ aws_ec2_keypair_bastion.name }}"
aws_cfn_bastion_stack_name: "{{ aws_cfn_stack_name }}Bastion"
aws_cfn_bastion_qs_template_url: "https://s3.amazonaws.com/quickstart-reference/linux/bastion/latest/templates/linux-bastion.template"

例示のために all.yml としていますが、インベントリごとに読み込みを変えたい場合はファイル配置とプレイブックを適宜調整してください。インベントリファイルの配置については Ansible のドキュメントを参照してください。

スタックの作成

site.yml としてプレイブックを用意します。

site.yml
---

- name: Create VPC and Bastion stack
  hosts: localhost
  connection: local
  gather_facts: no
  tasks:
    - name: Launch VPC network with NAT gateway
      cloudformation:
        region: "{{ aws_region }}"
        stack_name: "{{ aws_cfn_vpc_stack_name }}"
        state: "present"
        template_url: "{{ aws_cfn_vpc_qs_template_url }}"
        template_parameters:
          AvailabilityZones: "{{ aws_cfn_vpc_availability_zones }}"
          KeyPairName: "{{ aws_cfn_vpc_qs_keypair }}"
      register: _vpc
    - name: Launch bastion stack
      cloudformation:
        region: "{{ aws_region }}"
        stack_name: "{{ aws_cfn_bastion_stack_name }}"
        state: "present"
        template_url: "{{ aws_cfn_bastion_qs_template_url }}"
        template_parameters:
          VPCID: "{{ _vpc.stack_outputs.VPCID }}"
          PublicSubnet1ID: "{{ _vpc.stack_outputs.PublicSubnet1ID }}"
          PublicSubnet2ID: "{{ _vpc.stack_outputs.PublicSubnet2ID }}"
          RemoteAccessCIDR: "{{ remote_global_ip_addr }}"
          EnableTCPForwarding: "true"
          KeyPairName: "{{ aws_ec2_keypair_bastion.name }}"
      register: _bastion
    - name: Show bastion EIP
      local_action: shell echo {{ _bastion.stack_outputs.EIP1 }} > bastion

プレイブックを実行します。正常に処理が終了すると bastion ファイルに踏み台ホストの IP アドレスが出力されます。

プレイブックの実行
$ ansible-playbook site.yml

スタックの削除

halt.yml としてプレイブックを用意します。

halt.yml
---

- name: Delete all stacks
  hosts: localhost
  connection: local
  gather_facts: no
  tasks:
    - name: Delete bastion stack
      cloudformation:
        region: "{{ aws_region }}"
        stack_name: "{{ aws_cfn_bastion_stack_name }}"
        state: "absent"
    - name: Delete VPC stack
      cloudformation:
        region: "{{ aws_region }}"
        stack_name: "{{ aws_cfn_vpc_stack_name }}"
        state: "absent"

プレイブックを実行します。

プレイブックの実行
$ ansible-playbook halt.yml

まとめ

Ansible を使って AWS の CloudFormation のスタックを作成および削除しました。入力パラメータを Ansible のインベントリに沿って管理でき、スタックの出力結果をプレイブックの中で変数として利用できますので、その他にもいくつかの処理が必要な場合には便利です。例えば、踏み台ホストの EIP を ~/.ssh/config に追記することが考えられます。

シェルスクリプトだと書き方が人によってばらつきがあったり、条件による変数の使い分けが難しいことがありますので、Ansible のような構成管理ツールにまとめておくと便利な場面はあることでしょう。

環境補足

Vagrant を使って Ansible および Boto をインストールする場合は以下のようになります。

Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-16.04"

  config.vm.provision "shell", inline: <<-SHELL
    apt-get update
    apt-get install -y python-pip
    pip install -U pip
    pip install ansible==2.4.0
    pip install boto3
  SHELL
end

プレイブックの実行には Ansible Local を使っても良いでしょう。

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6