近いうちに AWS CLIコマンドで生成されるファイルは ~/.aws/config から ~/.aws/credentials に統合されるというお話

Route53 を DSL で管理する Roadworker は便利だからよく使っていたのですが、 AWS CLI 生成した ~/.aws/config を読み込んでくれなくてちょっと不便だなって思っていたのですが、 Roadworker で ~/.aws/config 読み込まないのはなんで?って質問したら

Want to read from AWS credentials from awscli generated config file · Issue #6 · winebarrel/roadworker

どうやら AWS SDK では ~/.aws/credentials を読み込むのが最近のトレンドのようだったのです。

A New and Standardized Way to Manage Credentials in the AWS SDKs – AWS Security Blog

確かに aws cli のドキュメント調べたらまずはじめに ~/.aws/credentials がないか調べますって書いてあって、だがしかし、 aws configure コマンドは ~/.aws/config ファイルを生成して、なんでかなあって不思議に思ってたんですよね。

Configuring the AWS Command Line Interface – AWS Command Line Interface

親切にも指定したクレデンシャルファイルを読み込むオプションをつけて実装してくださいました。
フィードバック速い!

で、肝心の AWS CLI に質問したら即効で答え返ってきました。
もうその議論はなされていてレビュー通ったらマージされて、リリースされるよって教えてくれました。
僕のすごいへたくそな英語にも親切に答えてくれる。
それなりに通じてるんだろうか・・・。あなたがチュキだからーみたいな感じになってないといいな。

aws configure may have to generate ~/.aws/credentials instead ~/.aws/config · Issue #918 · aws/aws-cli

楽しみだなあ。
issue を登録するだけで contribution graph に色が塗られるのは気持ちいいけど、コード的なコミットもしたいなあ。

いかにも貢献していますって感じでかっこいいじゃないですか。

ちなみに今の AWS CLI のバージョンは 1.4.4 です。
リリースされたらアップグレードしましょう。

pip install --upgrade awscli

あと、Roadworker はとってもオススメです。もっと Star ついてもいいと思う。
僕の尊敬している伊藤直也さんも使ってるので最高です。
いつか直也さんみたいなすごいエンジニアになりたい。

以上、半分以上僕の日記帳でした。

Mac OS X Mavericksでawscliをインストールする

家で余ってたMBAのセットアップ。
ついでに jq もインストールする。
以前は環境変数の設定周りがごちゃごちゃしてた気がするんだよな・・・。

前提条件

  • デフォルトのpythonは無視したい(homebrewで入れる)
  • zsh
  • /etc/paths を少しいじってる(/usr/local/bin/python が使われるようにして
    る)

インストール

意外とあっさり入った。

brew install python
pip install awscli
brew install jq

デフォルトで入っているpythonとのバージョン比較(3014/07/29現在)

[noguchiwataru@noguchiwataru-no-MacBook-Air] ~
% python --version
Python 2.7.8
[noguchiwataru@noguchiwataru-no-MacBook-Air] ~
% /usr/bin/python --version
Python 2.7.5

設定

アクセストークンはIAMから発行すること。
間違ってもAWSアカウント直で発行しないこと。死ぬ。
また、出力フォーマットはjqで整形できるのでJSONが望ましい。

% aws configure
AWS Access Key ID [None]: your_access_key_id
AWS Secret Access Key [None]: your_secret_access_key
Default region name [None]: ap-northeast-1
Default output format [None]: json

以下のようにすると設定ファイルが作成されていることがわかる。

% ls -F ~/.aws/
config

中身はこんな感じ。

[default]
output = json
region = ap-northeast-1
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key

動作確認

次のコマンドが動作すればOK。

% aws ec2 describe-instances | jq '.'

補完機能を有効にする

zsh

一番最後の行に以下の1行を入れる。
一番最後じゃないと動かなかった気がする。
たぶんデフォルトでパスが通っている場所においてあると思う。

# ~/.zshrc
# (snip)
source aws_zsh_completer.sh

source ~/.zshrc

bash

~/.bashrc じゃだめなので注意。

# ~/.bash_profile
complete -C aws_completer aws

source ~/.bash_profile

References

  1. Configuring the AWS Command Line Interface
  2. Macのzshでawscliの補完を有効化する – 戦場のプログラマー

awscliでec2インスタンスを操作する

よく忘れるので基本的な操作方法のまとめ。

インスタンスの操作

インスタンスを作成

  • AMI IDを調べてメモる
  • 立ち上げたいインスタンス
  • インスタンスタイプ: 現状t2.microが最小(2014/7/8現在)
  • 使用するキーペア
  • 適用するセキュリティグループ
% aws ec2 run-instances --image-id ami-29dc9228 --count 1 --instance-type t2.micro --key-name default --security-groups hoge | jq '.'

AZを指定する

--placement AvailabilityZone=ap-northeast-1a をつけてやればいい。

aws ec2 run-instances --image-id ami-29dc9228 --count 1 --instance-type t2.micro --key-name default --security-groups web --placement AvailabilityZone=ap-northeast-1a | jq '.'

DeleteOnTerminationを避ける

今ではほとんどEBSから起動されるEC2インスタンスがほとんどだが、このままでは DeleteOnTermination=true となってしまっているので、インスタンスをterminateするとインスタンスに紐付けられているボリューム自体も削除されてしまう。

これを避けたいなら

% aws ec2 run-instances --image-id ami-29dc9228 --count 1 --instance-type t2.micro --key-name default --security-groups hoge \
--block-device-mappings "[{\"DeviceName\": \"/dev/xvda\",\"Ebs\":{\"DeleteOnTermination\": \"false\"}}]" | jq '.'

としなければならない。面倒だが。

既に作成されたインスタンスについて DeleteOnTermination=true としたい場合は

% aws ec2 modify-instance-attribute --instance-id i-dfff36d1 --block-device-mappings "[{\"DeviceName\": \"/dev/xvda\",\"Ebs\":{\"DeleteOnTermination\": \"false\"}}]" | jq '.'

とすればいい。

インスタンスを起動

% aws ec2 start-instances --instance-ids i-xxxxxxxx | jq '.'

インスタンスを停止

% aws ec2 stop-instances --instance-ids i-xxxxxxxx | jq '.'          

停まったかどうか確認。

% aws ec2 describe-instances --instance-ids i-xxxxxxxx | jq -r '.Reservations [] .Instances [] .State .Name'
stopped

インスタンスを削除(terminate)

% aws ec2 terminate-instances --instance-ids i-xxxxxxxx | jq '.'

jqで欲しい値をとってくる

インスタンスID

% aws ec2 describe-instances | jq -r '.Reservations [] .Instances [] .InstanceId'
i-xxxxxxxx

グローバルIPアドレス

% aws ec2 describe-instances | jq -r '.Reservations [] .Instances [] .PublicIpAddress'
xxx.xxx.xxx.xxx

PublicDNS名

% aws ec2 describe-instances | jq -r '.Reservations [] .Instances [] .PublicDnsName'
ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com

SSHで接続するとき

単なる覚え書き。

ssh ec2-user@xxx.xxx.xxx.xxx -i ~/.ssh/foobar.pem

References

  1. run-instances — AWS CLI 1.3.21 documentation
  2. start-instances — AWS CLI 1.3.21 documentation
  3. stop-instances — AWS CLI 1.3.21 documentation
  4. terminate-instances — AWS CLI 1.3.21 documentation
  5. describe-instances — AWS CLI 1.3.21 documentation

awscliでt1.microインスタンスをたちあげようとしたら怒られたでござる

t1.microインスタンスawscliから立ち上げようとAMI ID調べて立ち上げようとしたら失敗した。

% aws ec2 run-instances --image-id ami-29dc9228 --count 1 --instance-type t1.micro --key-name default --security-groups hoge | jq '.'
A client error (InvalidParameterCombination) occurred: Non-Windows instances with a virtualization type of 'hvm' are currently not supported for this instance type.

このインスタンスタイプはサポートしてないぞゴルァ!と怒られてしまいました。
しかたなくManagement Consoleからどんなタイプが選べるのか確認してみると t2.micro というインスタンスタイプが・・・。
「無料枠に最適!」って書いてあったのでこれで立ち上げてみました。

% aws ec2 run-instances --image-id ami-29dc9228 --count 1 --instance-type t2.micro --key-name default --security-groups hoge | jq '.'
{
"Instances": [
{
(snip)
}
],
"Groups": [],
"ReservationId": "r-ffffaaaa",
"OwnerId": "ffffffffffff"
}

うーん、今度からはt1.microインスタンスじゃなくてt2.microインスタンスっていう新しい最小のインスタンスタイプが追加された?変更された?みたいだ。
発表は2014/7/1とタイムリー。
T2インスタンスにはCPUクレジットという概念が追加されたみたい。
バーストするけど、クレジット消費してしまっても極端には性能は落ちませんよってことかな?

References

  1. dogmap.jp を t1.micro から t2.micro に変更してみました | dogmap.jp
  2. Amazon Web Services ブログ: 【AWS発表】バースト可能な性能を持つ新しい低コストEC2インスタンス

awscliでセキュリティグループを定義する

このへんは手でやったほうが早い気がしないでもない。
CloudFormationとかだといろいろよろしくやってくれるんだろうか。
まだその辺の境地にも達してないけど・・・。

セキュリティグループの作成

% aws ec2 create-security-group --group-name web --description "Web server role security group."
{
"return": "true",
"GroupId": "sg-ffffffff"
}

Inbound方向の規則を定義する

ping(ICMP)応答

aws ec2 authorize-security-group-ingress --group-name web --protocol icmp --port -1 --cidr "0.0.0.0/0" | jq '.'
{
"return": "true"
}

SSH

% aws ec2 authorize-security-group-ingress --group-name web --protocol tcp --port 22 --cidr "0.0.0.0/0" | jq '.'
{
"return": "true"
}

HTTP

% aws ec2 authorize-security-group-ingress --group-name web --protocol tcp --port 80 --cidr "0.0.0.0/0" | jq '.'
{
"return": "true"
}

Outbound方向

Outbound(authorize-security-group-egress)方向はデフォルトで全通過。

まとめると

aws ec2 create-security-group --group-name web --description "Web server role security group." | jq '.'
aws ec2 authorize-security-group-ingress --group-name web --protocol icmp --port -1 --cidr "0.0.0.0/0" | jq '.'
aws ec2 authorize-security-group-ingress --group-name web --protocol tcp --port 22 --cidr "0.0.0.0/0" | jq '.'
aws ec2 authorize-security-group-ingress --group-name web --protocol tcp --port 80 --cidr "0.0.0.0/0" | jq '.'

逆の操作

セキュリティグループに対して以下の様な操作を行うと22番ポートが封じられるのでSSH不能になる。
CIDRまできちんと記述しないといけないので注意。

aws ec2 revoke-security-group-ingress --group-name web --protocol tcp --port 22 --cidr "0.0.0.0/0" | jq '.'

ただし、ICMP規則を削除するときは

aws ec2 revoke-security-group-ingress --group-name web --protocol icmp --port -1 --cidr "0.0.0.0/0" | jq '.'

に関してはいったんpingを止めないとpingをずっと受け入れ続けてしまうみたいなので、いったん Ctrl+C でとめてからもう一回pingを打ってみると通らなくなることが確認できる。

References

  1. authorize-security-group-ingress — AWS CLI 1.3.21 documentation
  2. authorize-security-group-egress — AWS CLI 1.3.21 documentation

awscliでキーペア(鍵ペア)を生成する

意外と簡単。あとは jq で見せ方を工夫すればOK。
ここではVagrantのinsecure private keyをダミーとして使用。

% aws ec2 create-key-pair --key-name default | jq -r '.KeyMaterial' | tee ~/.ssh/aws-ec2-default.pem && chmod 600 ~/.ssh/aws-ec2-default.pem
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI
w+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoP
kcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2
hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NO
Td0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcW
yLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKd
ELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1
Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzf
TK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnK
iqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4A
sClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf
4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iP
cXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7Rk
EjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pN
CAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX
3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZG
YEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj
3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+
dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz
6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWC
P9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDF
llYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJ
kda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH
+vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQ
NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s=
-----END RSA PRIVATE KEY-----

ダブルクォーテーションを消すのには jq の -r オプションを使ってます。
teeコマンドは標準出力にもちゃんとできたこと見せたいから。

References

  1. create-key-pair — AWS CLI 1.3.21 documentation
  2. jqに痺れた … AWS CLIで演習など – OpenGroove
  3. teeコマンドの使い方 – Qiita
  4. vagrant/keys/vagrant at master · mitchellh/vagrant

awscliでキーペア(鍵ペア)を一括削除する

概要

AWSAPIの練習とシェルスクリプトの練習も兼ねてる。

AWS APIを叩く練習をしていてキーペアをいっぱい作っちゃいました。
こんな感じ。

% aws ec2 describe-key-pairs| jq -r '.KeyPairs [] .KeyName'
default
default2
default3
default4
default5
default6
default7
default8

ちなみにjqの -r オプションはダブルクォーテーションを消してくれるオプション。

これらのキーペアを消したい。

find+xargsを使う(失敗)

find+xargsの組合せに慣れてるから以下の様な感じにしたくなる。

aws ec2 describe-key-pairs | jq -r '.KeyPairs [] .KeyName' | xargs aws ec2 delete-key-pair --key-name
Unknown options: default3, default4, default5, default6, default7, default8, default2

でもエラー。xargsのmanページをよく見てみる。

Man page of XARGS

xargs は標準入力から読み込んだ一連の項目をその後ろに 追加していく (訳注: 作成されたコマンドラインが、
コマンドライン長の上限を 越える場合や、オプションによる特別な指定がある場合は、入力を適宜分割して、
command を複数回実行することになる)。標準入力における空行は無視する。

そういえば

find | xargs rm

find | xargs grep hoge

は引数に複数のエントリをもたせられた気がする・・・。

1個ずつ削除したいのでこれは使えない。

while+readを組み合わせる(成功)

aws ec2 describe-key-pairs | jq -r '.KeyPairs [] .KeyName' | while read key; do
aws ec2 delete-key-pair --key-name $key
done

これならどうだ。

% aws ec2 describe-key-pairs | jq -r '.KeyPairs [] .KeyName' | while read key; do
pipe pipe while> aws ec2 delete-key-pair --key-name $key
pipe pipe while> done
{
"return": "true"
}
{
"return": "true"
}
{
"return": "true"
}
{
"return": "true"
}
{
"return": "true"
}
{
"return": "true"
}
{
"return": "true"
}
{
"return": "true"
}

あっ、うまくいった。
やったきもちいいいいい。

References

  1. jq
  2. jqに痺れた … AWS CLIで演習など – OpenGroove
  3. jqコマンドを使ってみた – mknkisk report
  4. Bash – パイプ出力を現在のシェル上のwhileに喰わせる上手いやり方 – Qiita

awscliからEC2インスタンスを作成する(Amazon Linux + EBS + Elastic IP)

  • jqコマンドがあるととても便利です。
  • 事前にセキュリティグループとキーペア、Elastic IPは作成・割り当て済みとします。

インスタンスの作成

aws ec2 run-instances --image-id ami-0d13700c --count 1 --instance-type t1.micro --key-name default --security-groups webserver | jq '.'

インスタンスIDを調べる

さっき起動したインスタンスインスタンスIDを調べます。

aws ec2 describe-instances | jq '.Reservations [] .Instances [] .InstanceId'

Elastic IPの一覧を調べる

aws ec2 describe-addresses| jq '.'

インスタンスにElastic IPを割り当て

aws ec2 associate-address --instance-id i-12345678 --public-ip 111.111.111.111

インスタンスのAZ(Availability Zone)を調べる

EBSを作成するときにインスタンスのAZが違うとアタッチできないようです。

% aws ec2 describe-instances --instance-ids i-12345678 | jq '.Reservations [] .Instances [] .Placement .AvailabilityZone'
"ap-northeast-1a"

EBSボリューム作成

2GBのボリュームをap-northeast-1aに作成します。

aws ec2 create-volume --size 2 --availability-zone ap-northeast-1a

作成されたボリュームのIDを調べる

2番目(1)のボリュームIDを参照します。

aws ec2 describe-volumes | jq '.Volumes [1] .VolumeId'
"vol-b5d722ab"

EBSボリュームのアタッチ

aws ec2 attach-volume --volume-id vol-b5d722ab --instance-id i-12345678 --device xvdf

EC2インスタンスSSH接続してボリュームをフォーマットしてext4ファイルシステムを作成します。

パーティション作成。

fdisk /dev/xvdf
n
p
1
Enter
Enter
w

ext4ファイルシステムを作成。

mkfs.ext4 /dev/xvdf1

マウント先を /data にします。

mkdir /data

fstab編集。

vi /etc/fstab
/dev/xvdf1  /data       ext4    defaults,noatime  1   1

マウント実行。

mount -a

マウントされたか確認します。

[root@ip-172-31-5-123 ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1      7.9G  1.2G  6.7G  16% /
tmpfs           298M     0  298M   0% /dev/shm
/dev/xvdf1      2.0G   35M  1.9G   2% /data

おわりに

大体終わりました。
ここではswapを作成していないのが問題です。

インスタンスを停止する

aws ec2 stop-instances --instance-ids i-12345678 | jq '.'

インスタンスを起動する

aws ec2 start-instances --instance-ids i-12345678 | jq '.'

awscliでAvailability Zoneの一覧を調べる

  • jqコマンドを使っています。
% aws ec2 describe-availability-zones --region ap-northeast-1 | jq '.'
{
"AvailabilityZones": [
{
"ZoneName": "ap-northeast-1a",
"Messages": [],
"RegionName": "ap-northeast-1",
"State": "available"
},
{
"ZoneName": "ap-northeast-1c",
"Messages": [],
"RegionName": "ap-northeast-1",
"State": "available"
}
]
}

Macのzshでawscliの補完を有効化する

最近、ローカルのラップトップマシンは順次、zshに乗り換え始めたんだけど、
Bashと同じノリでawscliの補完を有効化しようとして

complete -C aws_completer aws

としてsourceしたらエラーになってしまった。

/Users/noguchiwataru/.zshrc:13: command not found: complete

zshに関しては aws_zsh_completer.sh というのを読み込むらしいので、
findで探してみたらパスが通っているところにあった

% find / -name aws_zsh_completer.sh 2>/dev/null
/usr/local/bin/aws_zsh_completer.sh

なので

# ~/.zshrc
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_DEFAULT_REGION=ap-northeast-1
aws_zsh_completer.sh

.zshrc に書いてsourceすればOKかな?

[noguchiwataru@Macintosh] ~
% source ~/.zshrc
/usr/local/bin/aws_zsh_completer.sh: line 18: autoload: command not found
/usr/local/bin/aws_zsh_completer.sh: line 19: compinit: command not found
/usr/local/bin/aws_zsh_completer.sh: line 20: bashcompinit: command not found

だめだった。。。
よくよく考えたらzshシェルスクリプト内で別シェルとしてさらにスクリプト実行したら意味が無いので、
ここでは aws_zsh_completer.sh をsourceするのが正しいですよね。

# ~/.zshrc
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_DEFAULT_REGION=ap-northeast-1
source aws_zsh_completer.sh

今度はエラーでなかったけど、あれ、補完効かないぞ。。。ぼくの幻覚なのかな。。。
でもみんなこの書き方で動いているっぽいし、なんでだろう。

で、よく調べてみたら始めの方に記述していたのがいけなかった。
.zshrc の一番最後の方に書いたらうまく動くようになった。

# ~/.zshrc
# (snip)
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_DEFAULT_REGION=ap-northeast-1
source /usr/local/bin/aws_zsh_completer.sh
complete -C aws_completer aws
# [EOF]

参考文献