AWS CLIツール管理法

AWS CLIツールの管理方法についてまとめてみた。

はじめに

複数の作業環境でAWS用のツールをメンテナンスし続けるのは結構大変ですよね。
また複数のAWSアカウントやIAMなどを使うために、複数のCredentialを使い分けることがあります。
皆さんそれぞれのやり方があると思うのですが、今回は僕の管理方法をご紹介します。

前提条件

AWSCLIツールを一括管理するために、gitを使っています。
Windows(Cygwin)/Mac OS X/Linuxで共通のレポジトリとなっています。
残念ながら一部ツールはCygwinで動作しないため、Windows上で動作しないものもあります。
ツールによっては、別途rubypythonなどを要求するものがありますので、適宜インストールしておく必要があります。

ディレクトリ構成

効率よくパスを通すために、以下のような構成になっています(~/aws以下にサービス名のsymlinkを作り、実体はtoolsの下に納めてある)。
こうする事で、バージョンの切り替えなどを簡単に出来るようにしています(Symlink操作のみ)。

~/aws
├── env
├── AS -> tools/AutoScaling-1.0.33.1
├── CF -> tools/AWSCloudFormation-1.0.6/
├── CW -> tools/CloudWatch-1.0.9.5
├── EC2 -> tools/ec2-api-tools-1.4.0.2
├── ELB -> tools/ElasticLoadBalancing-1.0.10.0
├── EMR -> tools/elastic-mapreduce-client-2010-11-11
├── IAM -> tools/IAMCli-1.1.0/
├── RDS -> tools/RDSCli-1.2.006
├── S3 -> tools/s3cmd-0.9.9.91/
├── keys-foo
├── keys-bar
├── sdk
│└── aws-php-sdk-1.2.0
└── tools
    ├── AWSCloudFormation-1.0.6
    ├── AWSIdentityManagementCLI
    ├── AutoScaling-1.0.33.1
    ├── CloudWatch-1.0.9.5
    ├── ElasticLoadBalancing-1.0.10.0
    ├── IAMCli-1.1.0
    ├── RDSCli-1.2.006
    ├── ec2-ami-tools-1.3-57676
    ├── ec2-api-tools-1.4.0.2
    ├── elastic_mapreduce_client-2010-11-11
    └── s3cmd-0.9.9.91

また、こうしておくことで、パスを通しやすくなります。
~/aws/env というファイルで各種環境設定をしています。

(該当箇所だけ抜粋)
# for JAVA
if [ "$JAVA_HOME" = "" ]
then
	for x in /usr/local/java /usr/java/default /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home /cygdrive/c/java/
	do
		if [ -d $x ]
		then
			export JAVA_HOME=$x
			export PATH=$JAVA_HOME/bin:$PATH
			break
		fi
	done
fi

# for AWS tool HOMEs
if [ "$AWSENV" = "" ] # do not add path more than once
then
	export EC2_HOME=~/aws/EC2
	export AWS_ELB_HOME=~/aws/ELB
	export AWS_AUTO_SCALING_HOME=~/aws/AS
	export AWS_CLOUDWATCH_HOME=~/aws/CW
	export AWS_RDS_HOME=~/aws/RDS
	export AWS_IAM_HOME=~/aws/IAM

	for x in ~/aws/*/bin
	do
		export PATH=$x:$PATH
	done
fi

認証情報の管理について

AWS用の認証情報には、アクセスキー、X.509証明書、キーペアがあります。
キーペアは自分で作ってインポートしたりssh-agentを利用して管理しています。
アクセスキー、X.509証明書をアカウント毎に簡単に切り替える方法を色々模索して、現在は以下のようなやり方で管理しています。

~/aws/keys-foo
├── env
├── credential
├── cert.pem // X.509証明書
└── pk.pem // X.509秘密鍵

---keys-foo/env
export EC2_PRIVATE_KEY=~/aws/keys-foo/pk.pem
export EC2_CERT=~/aws/keys-foo/cert.pem
export AWS_CREDENTIAL_FILE=~/aws/keys-foo/credential
. $AWS_CREDENTIAL_FILE
export AWS_ACCESS_KEY_ID=$AWSAccessKeyId
export AWS_SECRET_ACCESS_KEY=$AWSSecretKey

---keys-foo/credential
AWSAccessKeyId=<Write your AWS access ID>
AWSSecretKey=<Write your AWS secret key>

そして、~/aws/env内に以下のようなシェル関数を用意してあります

function key
{
        keydir=~/aws/keys-$1/
        source $keydir/env && echo using keys-$1
}

こうすることで、key foo とか key bar で切り替えすることができます。

リージョンの切り替え

操作対象のリージョンを切り替えるための関数も~/aws/env内に用意してあります

function region
{
        target=$1
        if [ "$target" = "" ]
        then
                if [ "$EC2_REGION" = "" ]
                then
                        echo "currently region is not set (us-east-1 will be used by default)"
                else
                        echo currently region is set to $EC2_REGION
                fi
                echo "usage: region <region>"
                echo available regions are:
                ec2-describe-regions | awk '{print "region "$2}'
        else
                export EC2_REGION=$target
                export EC2_URL=https://ec2.$target.amazonaws.com
                echo EC2 API endpoint changed to $EC2_URL
        fi
}
alias use="region us-east-1"
alias usw="region us-west-1"
alias euw="region eu-west-1"
alias aps="region ap-southeast-1"
alias apn="region ap-northeast-1"

使い方

  • region と打つと現在のリージョンの表示と、使用可能なリージョンの一覧が得られます(API呼び出すので少し時間がかかります)
  • region (上のコマンドの結果からコピペできます)とするとリージョンを指定できます
  • use/usw/euw/aps/apn のaliasを使うとタイプ数が少なくなりますね

シェル起動時に自動読み込み

.bashrcに以下のように書いてます。

. ~/aws/env
key foo
region ap-northeast-1

おまけ

1つのアカウントを複数人数でシェアする共同作業環境では、どれが誰のインスタンスだかパッと見で分かりにくいときがあります。僕らのチームではまだタグがない時に、keypairやsecurity groupなどの中に必ず自分のアカウント名を入れる(適当な名前のインスタンスは落とされても文句を言えない)という鉄の掟が作られました。
そういう環境で使える myinst という関数を作りました。作業マシンのログインアカウント(もしくは引数)で指定したユーザ名でec2-describe-instancesの結果をフィルタし、Terminatedでないインスタンスの情報をコンパクトに表示するものです(連続したタブをスペース1つに変換)。本当はタグ対応にしたいんですけど。

function myinst
{
	target=$1
	if [ "$target" = "" ]
	then
		target=$USER
	fi
	ec2-describe-instances | grep ^INSTANCE | grep $target | grep -v terminated | perl -pe 's/\t+/\ /g'
}
$ myinst
INSTANCE i-xxxxxxxx ami-440fa445 ec2-175-xx-xx-xx.ap-northeast-1.compute.amazonaws.com ip-10-xx-xx-xx.ap-northeast-1.compute.internal running j3tm0t0 0  t1.micro 2011-03-02T12:20:19+0000 ap-northeast-1a aki-d209a2d3   monitoring-disabled 175.xx.xx.xx.xx 10.xx.xx.xx.xx ebs paravirtual xen 

おわりに

質問とかもっとこうしたらいいんじゃない?とかあれば、コメントかtwitter @j3tm0t0 までお願いします。