ちょっと話題の記事

AWS Command Line Tool Python版

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

軽量コマンドラインツールが出た!

awscli-000

全国うん万人?のAWSデベロッパーの皆さん、ニュースです。AWSから提供されていたコマンドラインツールがPython版になって登場です。すでに12のサービスに対応しています。ただ単にJavaからPythonになったというレベルではありません。超軽量になったのです。今までのコマンドラインツールは、バックグラウンドでJVM(Java VM)が立ち上がっていました。コマンドが呼ばれる度にVMが初期起動するのでCPU使用率が非常に高く、サーバー運用時の定期呼び出しには大きな問題となっていました。仕方なく、RubyやPythonのSDKを使ってスクリプトを書くという毎日でした。Java好きな私ですので多少擁護しますと、Java版はRI(Reference Implementation)として、AWSの全てのAPIにアクセスするためのお手本として、今後も最初にSDKが提供されると思います。Python版は裏でBotoライブラリが動いているようです。12のサービスがコマンドで呼び出せますので、具体的な使い方としてはBash等のシェルの中で呼び出して使います。また、戻り値がJSONやテキストで取得することができます。定時実行、分岐、繰り返し、判定などの処理と組み合わせたり、様々なツールとの連携をして、AWSを管理・操作することが容易になったのです。さっそく使い勝手をチェックしてみましょう。

対応しているAWSサービス

2013年1月5日現在の最新版は、0.4.5です。あれ?VPC追加された?

awscli-001

  • Amazon Elastic Compute Cloud (Amazon EC2) including VPC
  • Elastic Load Balancing
  • Auto Scaling
  • AWS CloudFormation
  • AWS Elastic Beanstalk
  • Amazon Simple Notification Service (Amazon SNS)
  • Amazon Simple Queue Service (Amazon SQS)
  • Amazon Relational Database Service (Amazon RDS)
  • AWS Identity and Access Management (IAM)
  • AWS Security Token Service (STS)
  • Amazon CloudWatch
  • Amazon Simple Email Service (Amazon SES)

インストール

Amazon Linuxを例にインストールです。サクッと完了です。

$ sudo easy_install pip

$ sudo pip install awscli

既にインストールしている方は最新版に上げましょう

$ sudo pip install awscli --upgrade

コマンド入力補間

Java版ではヘルプを見ながらコマンドや引数を指定していましたが、Python版では入力補間を行うことができます。以下のコマンドを打ってみて下さい。

$ complete -C aws_completer aws

初回起動時に入力補間の初期設定してくれるように、また、リージョン指定を自動的に行うように、.bash_profileに追記します。

$ echo "complete -C aws_completer aws" >> ~/.bash_profile 
$ echo "export AWS_CONFIG_FILE=/home/ec2-user/aws.config" >> ~/.bash_profile

これで入力補間設定ができました。早速、いくつかキーを叩いてみましょう。

$ aws (タブを打つ)                                              
autoscaling       directconnect     elb               rds               sqs               
cloudformation    ec2               emr               ses               sts               
cloudwatch        elasticbeanstalk  iam               sns

次にec2を選択してからさらにタブを打ってみます。

$ aws ec2 describe- (タブ)
describe-addresses                     describe-key-pairs                     describe-snapshots
describe-availability-zones            describe-licenses                      describe-spot-datafeed-subscription
describe-bundle-tasks                  describe-network-acls                  describe-spot-instance-requests
describe-conversion-tasks              describe-network-interface-attribute   describe-spot-price-history
describe-customer-gateways             describe-network-interfaces            describe-subnets
describe-dhcp-options                  describe-placement-groups              describe-tags
describe-export-tasks                  describe-regions                       describe-volume-attribute
describe-image-attribute               describe-reserved-instances            describe-volumes
describe-images                        describe-reserved-instances-listings   describe-volume-status
describe-instance-attribute            describe-reserved-instances-offerings  describe-vpcs
describe-instances                     describe-route-tables                  describe-vpn-connections
describe-instance-status               describe-security-groups               describe-vpn-gateways
describe-internet-gateways             describe-snapshot-attribute     
       
$ aws ec2 describe-vpcs (タブ)
--debug         --filters       --profile       --version       
--endpoint-url  --output        --region        --vpc-ids    
         
$ aws ec2 describe-vpcs --region (タブ)
ap-northeast-1  ap-southeast-2  sa-east-1       us-gov-west-1   us-west-2       
ap-southeast-1  eu-west-1       us-east-1       us-west-1 
      
$ aws ec2 describe-vpcs --region ap- (タブ)
ap-northeast-1  ap-southeast-1  ap-southeast-2  

$ aws ec2 describe-vpcs --region ap-northeast-1 (エンター)
{
    "vpcSet": [
        {
            "instanceTenancy": "default", 
            "state": "available", 
            "vpcId": "vpc-26c18XXX", 
            "cidrBlock": "10.1.0.0/16", 
            "dhcpOptionsId": "dopt-075dcXXX"
        }, 
        {
            "instanceTenancy": "default", 
            "state": "available", 
            "vpcId": "vpc-035dcXXX", 
            "cidrBlock": "10.0.0.0/16", 
            "dhcpOptionsId": "dopt-075dcXXX"
        }
    ], 
    "requestId": "4b2786b1-4af9-422c-b464-2c1dca3fbXXX"
}

すばらしいカジュアルさですね。

カギ情報の設定

このコマンドラインツールは、AWS APIへアクセスするためにカギ情報の設定を行う必要がありまして、3つの方法が提供されています。

  • 環境変数の指定
  • コンフィグファイルの指定
  • IAMRoleの指定

環境変数の指定

最も基本的な方法が環境変数の指定です。名前がJava版と微妙に異なりますw

$ export AWS_ACCESS_KEY_ID=<access_key>
$ export AWS_SECRET_ACCESS_KEY=<secret_key>

コンフィグファイルの指定

コンフィグファイルを使うと複数の設定を切り替えることができます。

[default]
aws_access_key_id=<default access key>
aws_secret_access_key=<default secret key>

[development]
aws_access_key_id=<testing access key>
aws_secret_access_key=<testing secret key>

[production]
aws_access_key_id=<testing access key>
aws_secret_access_key=<testing secret key>
region=ap-northeast-1

これを環境変数に設定します。

$ export AWS_CONFIG_FILE=/path/to/config_file

使うときはこんな感じです

$ aws ec2 describe-vpcs --profile production

IAMRoleの指定

最後にご紹介するのがIAMRoleです。環境変数の設定では、各インスタンスに個別の認証情報を書き込んでしまっています。これをDI(Dependency Injection)する形で後から設定できます。Python版のコマンドラインツールが優れているのは、Java版と同様にIAMRoleに対応していることが挙げられます。オレオレツールのAPIアクセスSDKは、IAMRoleに対応していないことが多く使えないのですが、公式コマンドラインツールはIAMRoleにしっかり対応してくれています。環境変数の設定は不要です。

awscli-004

その他の環境変数

その他の環境変数の設定として、各種デフォルト値を指定することができます。

デフォルトのリージョン指定です。

$ export AWS_DEFAULT_REGION=ap-northeast-1

デフォルトリージョンを手書きするのは面倒ですよね。自分がどこのリージョンで起動しているか判別して勝手に設定しましょう。以下は、リージョンとAZ(アベイラビリティゾーン)を取得するサンプルです。メタデータを取得して加工しています。

#!/bin/bash

aws_region=$(wget -q -O- http://169.254.169.254/latest/meta-data/hostname | cut -d. -f2)

echo $aws_region

az_name=$(wget -q -O- http://169.254.169.254/latest/meta-data/placement/availability-zone)

echo $az_name

az_char=$(echo $az_name | cut -c-1)

echo $az_char

実行結果はこんな感じです

ap-northeast-1
ap-northeast-1a
a

このサンプルを流用して以下のようにデフォルトリージョンの設定をしました。

#!/bin/bash

aws_region=$(wget -q -O- http://169.254.169.254/latest/meta-data/hostname | cut -d. -f2)

echo $aws_region

export AWS_DEFAULT_REGION=$aws_region

これも.bash_profileあたりに追加しておきましょう。

次は、デフォルトのプロファイル指定です。指定が無い場合には、defaultが指定されます。リージョンをプロファイルで設定できますが別リージョンで起動する際には変更するのが面倒なので私はあえて記載しません。ポータビリティ重視で、IAMRoleとデフォルト自動設定がいいかなぁと。

$ export AWS_DEFAULT_PROFILE=development

複雑な入力指定

コマンドラインツールと聞くと、簡単な情報参照のみできるのかなと思いますが、実際のところはかなり細かい記述を行うことが出来ます。例えば、セキュリティグループに設定を追加してみましょう。

$ aws ec2 authorize-security-group-ingress --group-id sg-0ac26XXX \
    --ip-protocol tcp --from-port 22 --to-port 22 --cidr-ip 0.0.0.0/0
{
    "return": "true", 
    "requestId": "ff2cda9f-3e75-43d3-b95b-a06d498e6XXX"
}

内容を確認してみましょう。たしかに22番ポートが追加されています。

$ aws ec2 describe-security-groups --group-ids sg-0ac26XXX
{
    "securityGroupInfo": [
        {
            "ipPermissionsEgress": [], 
            "groupId": "sg-0ac26XXX", 
            "ipPermissions": [
                {
                    "toPort": 22, 
                    "ipProtocol": "tcp", 
                    "ipRanges": [
                        {
                            "cidrIp": "0.0.0.0/0"
                        }
                    ], 
                    "groups": [], 
                    "fromPort": 22
                }, 
                {
                    "toPort": 80, 
                    "ipProtocol": "tcp", 
                    "ipRanges": [
                        {
                            "cidrIp": "0.0.0.0/0"
                        }
                    ], 
                    "groups": [], 
                    "fromPort": 80
                }
            ], 
            "groupName": "XXXXXXXX", 
            "ownerId": "XXXXXXXXXXXX", 
            "groupDescription": "(no description)"
        }
    ], 
    "requestId": "737d0a8a-b6fb-4c62-81f2-b2b98a99fXXX"
}

jqを使ってJSONを操作する

awscli-002

Python版コマンドラインツールを使ってJSONが取得できることは分かりました。しかしこのままでは扱いづらいので、JSON操作をするjqというツールを使ってみましょう。以下はインストールの手順です。

$ sudo yum install git gcc make flex bison rake -y
$ sudo git clone https://github.com/stedolan/jq.git
$ cd jq
$ make
$ sudo make install

コマンドラインツールとjqをパイプで連結して操作します。インタンス一覧から起動中のIDとIPアドレスを表示したいと思います。

まずは、基本形です。パイプで全体を表示しています。jqを用いるとハイライト表示してくれるので見やすいですね。

$ aws ec2 describe-instances | jq '.'

awscli-003

続けてJSONを掘って行きます。

$ aws ec2 describe-instances | jq '.reservationSet | .[]'
{
  "instancesSet": [
    {
      "rootDeviceName": "/dev/sda1",
      "rootDeviceType": "ebs",
      "hypervisor": "xen",
      "architecture": "x86_64",
      "launchTime": "2012-09-03T17:15:47.000Z",
      "ebsOptimized": false,
      "networkInterfaceSet": [
        {
          "privateIpAddress": "10.0.0.100",
          "privateIpAddressesSet": {
            "item": {
              "privateIpAddress": "10.0.0.100",
              "primary": "true"
            }
          },
          "ownerId": "771293814336",
---

さらにパイプで掘ります。selectを使うとある条件のJSONのみ抽出できます。以下の例は起動中のインスタンスステータスを指定しています。

$ aws ec2 describe-instances | jq '.reservationSet | .[]' \
    | jq '.instancesSet | select(.[].instanceState.code == 16)'
[
  {
    "tagSet": [
      {
        "value": "Dev",
        "key": "Name"
      }
    ],
    "reason": "",
    "privateDnsName": "ip-10-146-7-205.ap-northeast-1.compute.internal",
    "virtualizationType": "paravirtual",
    "privateIpAddress": "10.146.7.205",
    "kernelId": "aki-44992845",
    "dnsName": "ec2-54-248-221-248.ap-northeast-1.compute.amazonaws.com",
    "monitoring": {
      "state": "disabled"
    },
---

やっと欲しい情報が見えてきました。ここで、インスタンスIDとIPアドレスを取得してみたいと思います。

$ aws ec2 describe-instances | jq '.reservationSet | .[]' \
    | jq '.instancesSet | select(.[].instanceState.code == 16)' \
    | jq '.[] | .instanceId , .ipAddress'
"i-ac3d4XXX"
"12.248.221.247"
"i-ac3d4YYY"
"23.248.221.248"
"i-ac3d4ZZZ"
"34.248.221.249"

ダブルコーテーションを削りたければcutします。

$ aws ec2 describe-instances | jq '.reservationSet | .[]' 
    | jq '.instancesSet | select(.[].instanceState.code == 16)' \
    | jq '.[] | .instanceId , .ipAddress' \
    | sed -e 's/\"//g'
i-ac3d4XXX
12.248.221.247
i-ac3d4YYY
23.248.221.248
i-ac3d4ZZZ
34.248.221.249

な、長いwww。でも、シェルだけで必要な情報を取得できるのは嬉しいですね!

まとめ

今回は、AWSコマンドラインツールPython版をご紹介しました。AWSをフル活用するためには、各種情報を取得しながらサービス間の連携を行うことが必要です。このツールを使いこなすことで、より一層AWS各種サービスの管理が容易になり、もう一歩踏み込んだ自律的な動作を実現することができます。巳年はヘビ(Python)を使いこなしましょう。あ、ちなみにこのツールは内部でbotocoreを呼んでいますので、botocoreのgithubを見ていると今後の機能追加を追えるかもしれません〜。

参照情報

awscli 0.4.5 - Universal Command Line Environment for AWS.

botocore - A low-level interface to a growing number of Amazon Web Services.

jq - jq is a lightweight and flexible command-line JSON processor.