黒い画面は怖くない、AWS CLI入門

記事タイトルとURLをコピーする

AWS認定 DevOps Engineer Professional になりました、みっちゃんです。(この自己紹介が一度やりたかった!)

さて、AWSを使い込んでいる方ならご存知の方も多いとは思いますが、今回は改めてAWS CLIについて紹介したいと思います。文字通りですが、これを上手に使いこなせばAWSのあらゆるサービスをCLI(コマンドラインインターフェース)経由で制御することができます。私は実際にお客様にデリバリーする環境の構築だったり、ドキュメンテーションなどに活用しています。いずれシチュエーションごとの小ネタも投下したいと思いますが、本項ではまずはその前段として概要をおさらいします。

前提知識

AWS CLIはBoto Coreライブラリで書かれたPython製のツールです。
本項執筆時点の最新バージョンは1.7.32です。

$ aws --version
aws-cli/1.7.32 Python/2.7.6 Darwin/14.3.0

AWSはあらゆる操作をREST API経由で実行しています。ブラウザからアクセスできるManagement Consoleも、GUIで選択・入力した内容をREST APIに引き渡し、その戻り値を可視化しています。AWS CLIはそのAPIに対して、シェルから直接アクセスしてパラメータを引き渡すようなものだと理解してもらえると良いのではないかと思います。

歴史的経緯っぽいところをざっくり

少し前まで、EC2 API ToolsAuto Scaling Command Line Tool のように各サービス毎に専用のCLIツール群が個別にパッケージングされたものがメジャーに用いられていました。
これらもまだメンテナンスされており現役ですが、複数サービス用のツール群を個別にインストール管理する必要があったりして、ツールを上手に運用するためにもちょっとした手間が必要になってきます。
その点、AWS CLIでは各種サービスのツールを1つのパッケージで管理することができます。また、サブコマンドの使い分けで各種サービスに対応することができるので、新しく触り始めるなら「とりあえずAWS CLIから」で間違いないと思います。

使ってみる

何が便利かというような話は、使いながら理解して頂くのがてっとり早いと思います。まずはインストールから。今回はMac OS X Yosemiteでやってみます。

$ sudo easy_install pip
$ sudo pip install awscli

ちなみにWindowsでもPowerShellからAWS CLIを利用することができます。
AWS CLIのページから環境にあったパッケージをダウンロードしてインストールしましょう。

インストールが完了したら初期設定です。
AWS CLIはアクセスキー/シークレットキーのペアを用いて各API操作の認証を行います。もちろんIAMにも完全対応しています。むしろルートアカウントや本番環境と同じアカウントで触るのは事故の元なので、まずは権限を限定したIAMユーザで試してみるのが安全でしょう。

$ aws configure

プロンプトの指示に従って "AWS Access Key ID" と "AWS Secret Access Key" を入力します。
"Default Region name" は、任意のリージョン名を入力します。例えば東京なら "ap-northeast-1" です。これはオプションですが、入力しておくとコマンド実行時にリージョンを指定する手間が省けます。

設定が正しいことを確認するために、とりあえず利用可能なリージョンの一覧を取得する describe-regions を実行してみます。

$ aws ec2 describe-regions

認証が正しくできていれば、以下のようなレスポンスが返ってきます。

{
    "Regions": [
        {
            "Endpoint": "ec2.eu-central-1.amazonaws.com",
            "RegionName": "eu-central-1"
        },
        {
            "Endpoint": "ec2.sa-east-1.amazonaws.com",
            "RegionName": "sa-east-1"
        },
        {
            "Endpoint": "ec2.ap-northeast-1.amazonaws.com",
            "RegionName": "ap-northeast-1"
        },
        {
            "Endpoint": "ec2.eu-west-1.amazonaws.com",
            "RegionName": "eu-west-1"
        },
        {
            "Endpoint": "ec2.us-east-1.amazonaws.com",
            "RegionName": "us-east-1"
        },
        {
            "Endpoint": "ec2.us-west-1.amazonaws.com",
            "RegionName": "us-west-1"
        },
        {
            "Endpoint": "ec2.us-west-2.amazonaws.com",
            "RegionName": "us-west-2"
        },
        {
            "Endpoint": "ec2.ap-southeast-2.amazonaws.com",
            "RegionName": "ap-southeast-2"
        },
        {
            "Endpoint": "ec2.ap-southeast-1.amazonaws.com",
            "RegionName": "ap-southeast-1"
        }
    ]
}

AWS CLIコマンドの基本

AWS CLIのコマンドは以下のような書式になっています。

aws ec2 describe-instance --instance-id i-1a2b3c4d
aws + コマンド + サブコマンド + [パラメータ]

といった形になっています。
サービス名を表すコマンドがあり、サブコマンドで具体的に何をするかを指定します。サブコマンドによっては、操作対象をパラメータで指定します。だいたい"サービス名=コマンド"ですが、中にはs3とs3apiのように、1つのサービスで複数コマンドに分かれているものもあります。

このAWS CLI、APIとの相性がものすごく良いので、サブコマンドの一覧を見ると「そのサービスに対してユーザがどんな操作が出来るのか」をほぼ一覧することができます。また、特に構築系のサブコマンドに関しては、投入可能なパラメータの一覧を見ると、そのリソースにどんな設定を渡すことができるかが一目瞭然となります。極端な話ですが、黒い画面に抵抗のない人であれば、入門書を読むよりも、CLIのオプションを見た方が「AWSの各サービスでどんなことができるのか」を理解する近道になるかもしれません。

補完について

上述のサブコマンドやパラメータ、一覧できると便利なのは事実なんですが、如何せん数が多いのでタブで補完できると便利です。補完用のスクリプトも用意されているので、以下のようにサクッと有効にしましょう。.bashrcへの追記も忘れずに。

bashの場合

$ type aws_completer
aws_completer is /usr/local/bin/aws_completer
$ complete -C '/usr/local/bin/aws_completer' aws
 
zshの場合

zshの場合はスクリプトが用意されているので、sourceコマンドで読ませるだけでOKです。こちらも.zshrcに書き足しておくと幸せになれます。

$ type aws_zsh_completer.sh
aws_zsh_completer.sh is /usr/local/bin/aws_zsh_completer.sh
 

profileオプション

AWS CLIにはプロファイルという概念があり、設定ファイルにちょろっと書き足してあげることで複数アカウントを切り替えて使うこともできます。例えば、本番環境のアカウントと検証環境のアカウントを分けている場合などに便利です。

例として、普通にコマンドを叩くと開発環境のアカウントに対して実行されるようにして、本番環境のアカウントでの操作は明示的にパラメータを渡さなければいけないようにしてみます。

AWS CLIの設定は ~/.aws/config に保存されています。

$ vim ~/.aws/config

このファイルを見てみると、[default] 行に続けて、先ほどの aws configure コマンドで入力した内容が反映されています。profileオプションを使わずにコマンドを実行した場合、このdefaultプロファイルに指定されたアカウントで操作が実行されます。

[default]
aws_access_key_id = AKIAXXXXXXXXXXXXXXXXX
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxx
region = ap-northeast-1

この設定ファイルに以下のように追記します。

[profile production]
aws_access_key_id = AKIAXXXXXXXXXXXXXXXXX
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxx
region = ap-northeast-1

このproductionプロファイルを利用してAWS CLIを利用する場合には、
実行時のパラメータに、--profile production と追記します。

filterオプション

AWS CLIの真髄その1、--filterオプションです。「条件に一致した情報だけを表示する」、いわゆるフィルタリングを行うことができます。このオプションを使わない場合には、例えばインスタンスIDなどリソース個別のIDを指定する必要があります。

--filterオプションを使うと、「特定のタグがついているリソースの情報を表示する」といった、一見複雑な操作が簡単に実行できます。'--filter "Name=キー,Values=値" ' といった書式で使い、複数のフィルタを同時に書くことができます。

例えば、以下はRDSのスナップショット一覧を表示するコマンドです。

$ aws rds describe-db-snapshots

上記のコマンドでは、リージョン内にある全てのRDSスナップショットの情報がずらずらっと表示されます。この表示結果から、"workload-type"タグの値が"development"であるスナップショットだけを表示させたい場合には以下のようにフィルタリングします。

$ aws rds describe-db-snapshots 
--filters "Name=tag-key,Values=workload-type Name=tag-value,Values=development"

もちろん実際には、タグだけでなく幅広い値をフィルタに使うことができます。
各サブコマンド毎に利用可能なフィルタオプションはAWS CLI documentationに記載されています。

queryオプション

AWS CLIの真髄その2、--queryオプションです。実行結果のJSONをパースして必要な情報だけをクエリすることができます。クエリはJMESPathという記法で記述します。

上記のRDSスナップショットの表示では特に出力する情報を絞り込んでいなかったので、以下のように情報がずらっと出てきます。
 

{
    "DBSnapshots": [
        {
            "Engine": "mysql",
            "SnapshotCreateTime": "2015-06-08T13:35:24.514Z",
            "AvailabilityZone": "ap-northeast-1a",
            "PercentProgress": 100,
            "MasterUsername": "mitsui",
            "Encrypted": false,
            "LicenseModel": "general-public-license",
            "StorageType": "gp2",
            "Status": "available",
            "VpcId": "vpc-ae5086cb",
            "DBSnapshotIdentifier": "rds:mitsui-testrds-2015-06-08-13-35",
            "InstanceCreateTime": "2015-04-06T12:24:54.811Z",
            "OptionGroupName": "default:mysql-5-6",
            "AllocatedStorage": 5,
            "EngineVersion": "5.6.22",
            "SnapshotType": "automated",
            "Port": 3306,
            "DBInstanceIdentifier": "mitsuo-testrds"
        }
    ]
}

例えばここから、「スナップショット名、スナップショット作成日時だけを抜き出したい」といった場合には以下のようなコマンドを実行します。
 

$ aws rds describe-db-snapshots 
--filters "Name=tag-key,Value=workload-type Name=tag-value,Values=development" 
--query "DBSnapshots[].[DBSnapshotIdentifier,SnapshotCreateTime]"

 

[
    [
        "rds:mitsui-testrds-2015-06-08-13-35",
        "2015-06-08T13:35:24.514Z"
    ]
]

だいぶシンプルな表示結果になりました。

outputオプション

比較的地味だけど個人的にAWS CLIの真髄その3です。
--outputオプションを指定することで、出力結果の表示方法を json, table, text の3種類から選ぶことができます。デフォルトはJSONなので何も指定しない場合は先の例のように、JSON形式で出力されます。

--output table

インタラクティブな感じの表示結果になります。

$ aws rds describe-db-snapshots 
--filters "Name=tag-key,Value=workload-type Name=tag-value,Values=development" 
--query "DBSnapshots[].[DBSnapshotIdentifier,SnapshotCreateTime]" 
--output table

出力結果

---------------------------------------------------------------------
|                        DescribeDBSnapshots                        |
+--------------------------------------+----------------------------+
|  rds:mitsui-testrds-2015-06-08-13-35 |  2015-06-08T13:35:24.514Z  |
|  rds:mitsui-testrds-2015-06-09-13-35 |  2015-06-09T13:35:30.523Z  |
+--------------------------------------+----------------------------+

--output text

個人的に一番のお気に入り。プレーンなタブ区切りのテキストで表示されます。次のコマンドにちょろっとパイプで渡して加工したい時なんかに便利です。

$ aws rds describe-db-snapshots 
--filters "Name=tag-key,Value=workload-type Name=tag-value,Values=development" 
--query "DBSnapshots[].[DBSnapshotIdentifier,SnapshotCreateTime]" 
--output text

出力結果

rds:mitsui-testrds-2015-06-08-13-35    2015-06-08T13:35:24.514Z
rds:mitsui-testrds-2015-06-09-13-35    2015-06-09T13:35:30.523Z

最後に

AWS CLIではただ情報を取得するだけでなく、適切にフィルタ、クエリすることで効果的に必要な情報だけを抜き出すことができる、というところまでご紹介しました。
あとはパイプで繋いでもファイルに書き出してもよし、どこまで長いワンライナーを書けるかを競うのもまた一興ですね。どんな道具もそうですが、使う人次第で使い道はどこまでも広がります。

サーバーワークスでは、シェル芸を切磋琢磨できる熱い仲間を募集しています!

クラウドを操りSIの世界を変えたいエンジニアをWanted!