pythonでAWSのリソース情報を取得してyamlファイルを編集してみた


はじめに

仕事で特定のyamlファイルをコピーして、EC2のIPアドレスなどの特定の箇所を編集してplaybookを実行することがあり、手作業だとミスが起きると思いプログラムでAWSのリソースを取得して、その値でyamlファイルを書き換えられないか試してみた。

実施したこと

引数として

  • 編集したいyamlのファイル名
  • EC2のタグ(Name)の値
  • AWSのプロファイル

を渡してあげて、AWSのプロファイルの設定で、EC2タグの値に紐づくECインスタンスを取得して
yamlファイルを編集する。

yamlファイルのイメージ

- hosts: target_test
  tasks:
  - name: install git
    yum: name=git state=latest
  instance:
    private_ip: 0.0.0.0
    public_ip: 0.0.0.0
    ip: 0.0.0.0

↑のprivate_ipと、public_ipを編集する。

作成したソース

#!/usr/bin/python
# -*- coding: utf-8 -*-

import ruamel
import ruamel.yaml
import sys
import boto3
from boto3.session import Session

yaml = ruamel.yaml.YAML()

args = sys.argv
file_name = args[1]
tag_value = args[2]
profile = args[3]
# プロファイルの内容でAWSのリソースにアクセスするように設定
session = Session(profile_name=profile)

def read_file(file_name):
    """
    ファイル読み込み
    引数
    file_name: ファイル名

    返り値
    loadしたyamlデータ
    """
    with open(file_name, 'r') as file:
        data = yaml.load(file)

    return data

def fetch_ec2_instance(tag_value):
    """
    ec2インスタンス取得
    引数
    tag_value: ファイル名

    返り値
    Name=tag_valueのインスタンス
    """
    ec2 = session.client("ec2")

    # Nameタグでフィルター
    instances = ec2.describe_instances(
            Filters=[
                {'Name': 'tag-key', 'Values': ['Name']},
                {'Name': 'tag-value', 'Values': [tag_value]}
            ]
        )['Reservations']

    if len(instances) == 0:
        raise Exception("インスタンスが存在しません。 Name:{}".format(tag_value))

    return instances[0]

def edit_data(data, instance):
    """
    パブリックIP、プライベートIPの修正
    引数
    data: yamlデータ
    instance: ec2インスタンス
    """
    data[0]["instance"]["private_ip"] = instance['Instances'][0]['PrivateIpAddress']
    data[0]["instance"]["public_ip"] = instance['Instances'][0]['PublicIpAddress']

def write_data(file_name, data):
    """
    yamlデータ書き込み
    file_name: 書き込むファイル名
    data: yamlデータ
    """

    with open(file_name, 'w') as file:
        yaml.dump(data, stream=file)

data = read_file(file_name)
instance = fetch_ec2_instance(tag_value)
edit_data(data, instance)
write_data(file_name, data)

ruamelを使用して、yamlファイルの編集をしてます。
PyYamlもあるのですが、その場合yamlファイルの順序が保障されてないためruamelを使用してます。

以下コマンドで実行

python {pythonのソースファイル名} {編集ファイル名}  {Nameタグの値} {プロファイル}

参考

ruamelについて
https://dev.classmethod.jp/articles/getting-started-with-pyyaml-and-ruamel-yaml/

デフォルトのプロファイル以外を使用する
https://qiita.com/inouet/items/f9723d7ae7d8d134280b