[AWS]AnsibleのDynamic Inventoryを使って実行対象のEC2をタグ等で柔軟に指定する

ANSIBLE

コンニチハ、千葉です。

AWS + Ansible環境を利用する場合、InventoryをIPで管理するのがつらくなる場合があります。柔軟にインスタンスができたり、消えたりする世界でプライベートIPが変更なったタイミングで、Inventoryをメンテナンスするのは涙が出ますね。ということで、Dynamic Inventoryを触ってみました。

【Ansible】EC2 External Inventory Scriptを使った動的ホスト一覧生成

こちらの記事で紹介がありますが、今回はEC2 External Inventory Scriptを使ってどんな指定ができるか調べてみました。まずやりたいのはEC2タグでの指定。それ以外にも柔軟な指定ができそうなので調べてみました。

対象

では、どんな指定方法があるのでしょうか。

ec2.iniより

# configure which groups should be created.
group_by_instance_id = True
group_by_region = True
group_by_availability_zone = True
group_by_aws_account = False
group_by_ami_id = True
group_by_instance_type = True
group_by_instance_state = False
group_by_key_pair = True
group_by_vpc_id = True
group_by_security_group = True
group_by_tag_keys = True
group_by_tag_none = True
group_by_route53_names = True
group_by_rds_engine = True
group_by_rds_parameter_group = True
group_by_elasticache_engine = True
group_by_elasticache_cluster = True
group_by_elasticache_parameter_group = True
group_by_elasticache_replication_group = True

アカウント、VPC、インスタンスタイプ、インスタンスID、ami-id、等などで指定ができそうです。 また、rdsやelasticacheも対象にできるようですね。

下準備

Dynamic Inventoryを利用するためのインストールや設定を行います。 今回私は、Docker for Mac + Amazon Linuxを使って検証しました。

$ docker --version
Docker version 17.06.0-ce-rc2, build 402dd4a
$ cat /etc/system-release
Amazon Linux AMI release 2017.03
$ python --version
Python 2.7.12

以下はDocker + Amazon Linux利用時のみ行ってください。

$ yum install -y wget gcc python27-devel openssl-devel vi

下準備として、Ansibleとbotoをインストールをインストールしましょう。

$ wget https://bootstrap.pypa.io/get-pip.py
$ python get-pip.py
$ pip install ansible
$ ansible --version
ansible 2.3.1.0
  config file =
  configured module search path = Default w/o overrides
  python version = 2.7.12 (default, Sep  1 2016, 22:14:00) [GCC 4.8.3 20140911 (Red Hat 4.8.3-9)]
$ pip install -U boto boto3

次にEC2 External Inventory Scriptをダウンロードします。

$ wget https://raw.github.com/ansible/ansible/devel/contrib/inventory/ec2.py
$ wget https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.ini
$ chmod +x ec2.py

アクセスキーの設定を行います。対象のリージョンとアクセスキーを設定します。

$ vi ec2.ini
## 以下を修正
regions = ap-northeast-1
# regions_exclude = us-gov-west-1, cn-north-1 # この行をコメントアウト
aws_access_key_id = xxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxx

動作確認です。以下のようにEC2の情報が取得できていればokです。

$ ./ec2.py --list
{
  "_meta": {
    "hostvars": {
      "xx.xx.xx.xx": {
        "ansible_ssh_host": "xx.xx.xx.xx",
        "ec2__in_monitoring_element": false,
        "ec2_account_id": "xxxxxxxxxxxxx",
        "ec2_ami_launch_index": "0",
        "ec2_architecture": "x86_64",
・・・・

EC2の情報を取得できました。これで準備okです。

やってみた

どんなグループが自動で作成されるかを確認

まず、初めにグループ名を確認します。

$ ./ec2.py --refresh-cache

このコマンドを実行すると、取得した情報が表示されます。そして、一番下の方に表示される「ami_6154bb00」などがグループ名になります。ansible実行時にはこのグループ名を指定します。

  "ami_6154bb00": [
    "13.115.254.160"
  ],
  "ami_923d12f5": [
    "54.250.238.152"
  ],
  "ap-northeast-1": [
    "54.250.238.152",
    "13.115.254.160"
  ],
  "ap-northeast-1a": [
    "54.250.238.152",
    "13.115.254.160"
  ],
  "ec2": [
    "54.250.238.152",
    "13.115.254.160"
  ],
  "i-02fef9a1a8118af90": [
    "54.250.238.152"
  ],

タグ指定

ansible -i ec2.py tag_env_dev -m ping

タグは以下のように指定しています

  • key:env
  • value:dev

リージョン指定

ansible -i ec2.py ap-northeast-1 -m ping

AZ指定

ansible -i ec2.py ap-northeast-1a -m ping

AMI-ID指定

ansible -i ec2.py ami_6154bb00 -m ping

VPC指定

ansible -i ec2.py vpc_id_vpc_xxxxxxxx -m ping

インスタンスタイプで指定

ansible -i ec2.py type_t2_nano -m ping

ec2.init設定Tips

重要そうな設定箇所を見てみます。

リージョン指定

設定例です。除外設定や、複数指定ができます。

regions = ap-northeast-1
regions_exclude = us-gov-west-1, cn-north-1
regions = us-east-1,us-west-1,us-west-2

プライベートからアクセス? or グローバルからアクセス?

インターネット経由でアクセスする場合は、以下を指定することでグローバルIPが指定されます。

destination_variable = public_dns_name
vpc_destination_variable = ip_address

プライベート環境の場合は、以下を指定しプライベートIPでの接続を行います。

destination_variable = private_dns_name
vpc_destination_variable = private_ip_address

最後に

AWSではEC2インスタンスを柔軟に作成・削除することができます。対象が変わった場合に、対象のIPアドレスを都度メンテナンスのはつらすぎますね。Dynamic Inventoryを利用することで、管理を楽にできそうです。それでは、また。

参考

http://docs.ansible.com/ansible/intro_dynamic_inventory.html http://dev.classmethod.jp/cloud/aws/ansible-dynamic-inventory-intro/