全力で怠けたい

怠けるために全力を尽くしたいブログ。

EC2 インスタンスのメタデータを取得する ec2-metadatafs コマンドが便利すぎた。

AWS の EC2 インスタンスメタデータを取得する ec2-metadatafs を使ってみたら便利すぎたのでメモ。

ec2-metadatafs ってなに?

ec2-metadatafs は AWS の EC2 インスタンスメタデータを取得できるコマンド。

ec2-metadatafs の特徴は EC2 インスタンスメタデータファイルシステム上にマウントすることによって ls とか cat とか grep とかの CLI ツールと一緒に使うことが容易になること。 また、メタデータファイルシステム上に配置するのでシェルの補完機能を最大限に活用することができるのがとても便利。

さっそく使ってみる。

$ mkdir metadata

$ ec2-metadatafs --tags metadata/
2019/08/12 05:38:35 [INFO] forked child with PID 3459
2019/08/12 05:38:35 [INFO] child process successfully mounted

$ tree metadata/
metadata/
├── dynamic
│   └── instance-identity
│       ├── document
│       ├── pkcs7
│       ├── rsa2048
│       └── signature
├── meta-data
│   ├── ami-id
│   ├── ami-launch-index
│   ├── ami-manifest-path
│   ├── block-device-mapping
│   │   ├── ami
│   │   └── root
│   ├── events
│   ├── hostname
│   ├── iam
│   │   ├── info
│   │   └── security-credentials
│   │       └── ec2-describetag-role
│   ├── identity-credentials
│   ├── instance-action
│   ├── instance-id
│   ├── instance-type
│   ├── local-hostname
│   ├── local-ipv4
│   ├── mac
│   ├── metrics
│   ├── network
│   │   └── interfaces
│   │       └── macs
│   │           └── 06:e5:0c:b8:f7:3e
│   │               ├── device-number
│   │               ├── interface-id
│   │               ├── ipv4-associations
│   │               ├── local-hostname
│   │               ├── local-ipv4s
│   │               ├── mac
│   │               ├── owner-id
│   │               ├── public-hostname
│   │               ├── public-ipv4s
│   │               ├── security-group-ids
│   │               ├── security-groups
│   │               ├── subnet-id
│   │               ├── subnet-ipv4-cidr-block
│   │               ├── vpc-id
│   │               ├── vpc-ipv4-cidr-block
│   │               └── vpc-ipv4-cidr-blocks
│   ├── placement
│   │   └── availability-zone
│   ├── profile
│   ├── public-hostname
│   ├── public-ipv4
│   ├── public-keys
│   │   └── 0
│   │       └── openssh-key
│   ├── reservation-id
│   ├── security-groups
│   └── services
│       ├── domain
│       │   └── amazonaws.com
│       └── partition
└── tags
    ├── Tag1
    └── Tag2

備忘録までにそれぞれのコマンドがやっていることを軽く書いておく。 まず metadata ディレクトリを作っているところ。

$ mkdir metadata

EC2 インスタンスメタデータをマウントするディレクトリを作っている。 メタデータをマウントする場所はどこでもいいと思うけどユーザーが複数いてそれぞれのユーザーがメタデータを取得するのなら、メタデータはどのユーザーからも見える場所にマウントするとよいと思う。

次は ec2-metadatafs コマンドを実行しているところ。

$ ec2-metadatafs --tags metadata/
2019/08/12 05:38:35 [INFO] forked child with PID 3459
2019/08/12 05:38:35 [INFO] child process successfully mounted

ec2-metadatafs コマンドを使って EC2 インスタンスメタデータをさきほど作った metadata にマウントする。それだけ。

あと EC2 インスタンスのタグを取得するために --tags オプションを指定しているがタグは取得しないのなら指定する必要はない。

次は EC2 インスタンスメタデータをマウントした metadata ディレクトリを tree してみたところ。 EC2 インスタンスメタデータファイルシステム上にマウントされているのがわかる。

$ tree metadata/
metadata/
├── dynamic
│   └── instance-identity
│       ├── document
│       ├── pkcs7
│       ├── rsa2048
│       └── signature
└── meta-data
    ├── ami-id

# 長いので省略

ec2-metadatafs を使ってみる

EC2 インスタンスメタデータファイルシステム上にマウントされる、ただそれだけのことなのだが実際に使ってみると想像以上に便利なのでいくつか使用例を書いておく。

試しにインスタンスタイプを取得してみる。

$ cat metadata/meta-data/instance-type
t2.micro

簡単。

もう一つ試しに EC2 インスタンスが動いているアベイラビリティゾーンを取得してみる。

$ cat metadata/meta-data/placement/availability-zone
ap-northeast-1a

すごく簡単。

ec2-metadatafs が便利なところはシェルの補完機能が働くので「あのメタデータどこだっけ?」ってときも雰囲気で入力して補完機能に任せる、みたいな使い方ができること。これが本当に便利。

補完機能を使うのすら面倒なときは find コマンドとかを使えば一切考える必要もない。

$$ find metadata/ -name "*zone*"
metadata/meta-data/placement/availability-zone

繰り返すが便利。

あとタグを取得できるのが地味だけどかなり便利。

$ ls metadata/tags/
Tag1  Tag2

$ cat metadata/tags/Tag1
Tag1Value

EC2 インスタンスメタデータを取得する方法はいろいろある

EC2 インスタンスメタデータを取得する方法は ec2-metadatafs の他にもあるのでメモしておく。 それぞれがメリット・デメリットがあるので、状況によって使い分けるのがいいと思う。

http://169.254.169.254/latest/meta-data/

http://169.254.169.254/latest/meta-data/ にアクセスすると EC2 インスタンスメタデータを取得できる。

$ curl http://169.254.169.254/latest/meta-data/
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hostname
identity-credentials/
instance-action
instance-id
instance-type
local-hostname
local-ipv4
mac
metrics/
network/
placement/
profile
public-hostname
public-ipv4
public-keys/
reservation-id
security-groups
services/

インスタンスタイプを取得してみる。

$ curl http://169.254.169.254/latest/meta-data/instance-type
t2.micro

難しいことは一切ないが URL を打ち込むのが面倒くさいし URL を打ち間違えたときに 404 が返ってくるのがイラつく。コピペしたくなってくる。「あれ、インスタンスタイプの URL はなんだったっけ?」というときは http://169.254.169.254/latest/meta-data/ にアクセスして結果を眺めて「あ、instance-type だったな」とやる以外にないのが不便。

あと、どうやってもタグを取得できないのが地味に結構不便。

ただ、http://169.254.169.254/latest/meta-data/ の素晴らしいところは EC2 デフォルトの状態でも使えるということ。 あと、スクリプトの中からメタデータを取得したいときみたいなときは事前に知りたいメタデータの URL とかを調べているだろうし動作も確認しているだろうから、URL を打ち込むのが面倒くさいとか URL を打ち間違えたとかはないはず。

ec2-metadata コマンド

ec2-metadata は EC2 インスタンスメタデータを取得するコマンド。

$ ec2-metadata --help
ec2-metadata v0.1.2
Use to retrieve EC2 instance metadata from within a running EC2 instance.
e.g. to retrieve instance id: ec2-metadata -i
         to retrieve ami id: ec2-metadata -a
         to get help: ec2-metadata --help
For more information on Amazon EC2 instance meta-data, refer to the documentation at
http://docs.amazonwebservices.com/AWSEC2/2008-05-05/DeveloperGuide/AESDG-chapter-instancedata.html

Usage: ec2-metadata <option>
Options:
--all                     Show all metadata information for this host (also default).
-a/--ami-id               The AMI ID used to launch this instance
-l/--ami-launch-index     The index of this instance in the reservation (per AMI).
-m/--ami-manifest-path    The manifest path of the AMI with which the instance was launched.
-n/--ancestor-ami-ids     The AMI IDs of any instances that were rebundled to create this AMI.
-b/--block-device-mapping Defines native device names to use when exposing virtual devices.
-i/--instance-id          The ID of this instance
-t/--instance-type        The type of instance to launch. For more information, see Instance Types.
-h/--local-hostname       The local hostname of the instance.
-o/--local-ipv4           Public IP address if launched with direct addressing; private IP address if launched with public addressing.
-k/--kernel-id            The ID of the kernel launched with this instance, if applicable.
-z/--availability-zone    The availability zone in which the instance launched. Same as placement
-c/--product-codes        Product codes associated with this instance.
-p/--public-hostname      The public hostname of the instance.
-v/--public-ipv4          NATted public IP Address
-u/--public-keys          Public keys. Only available if supplied at instance launch time
-r/--ramdisk-id           The ID of the RAM disk launched with this instance, if applicable.
-e/--reservation-id       ID of the reservation.
-s/--security-groups      Names of the security groups the instance is launched in. Only available if supplied at instance launch time
-d/--user-data            User-supplied data.Only available if supplied at instance launch time.

インスタンスタイプを取得してみる。

$ ec2-metadata --instance-type
instance-type: t2.micro

<メタデータの名前>: <メタデータの値> みたいな感じで出力されるので、メタデータの値たとえばインスタンスタイプの t2.micro の部分だけを取得するなら cut とかで切り出す感じ。ちょっと面倒くさい。

$ ec2-metadata --instance-type | cut -d ' ' -f 2
t2.micro

URL を打ち込む必要がないしショートオプションを使うとタイプ量はさらに少なくなるのが便利。 あと AMI が Amazon Linux ならデフォルトで使えるメリットが大きい。

ただ、メタデータの値を cut とかで切り出すのが面倒くさい。 あと、どうやってもタグを取得できないのが地味に結構不便。

ec2-metadatafs のインストール

ec2-metadatafs コマンドが便利な点と使い方の雰囲気は書いたのでインストール方法も書いておく。

といっても、curlhttps://github.com/jszwedko/ec2-metadatafs/releases/download/<バージョン>/linux_amd64 からダウンロードして実行パーミッションを付けてパスが通ったところに置くだけ。

$ curl -sL https://github.com/jszwedko/ec2-metadatafs/releases/download/1.0.0/linux_amd64 > ec2-metadatafs
$ chmod +x ec2-metadatafs
$ sudo mv ec2-metadatafs /usr/bin/

ec2-metadatafs は EC2 メタデータファイルシステム上にマウントするために FUSE に依存しているので FUSE をインストールしておく。

 $ sudo yum install -y fuse

あとタグを取得するときは IAM ロールが必要になるのでつけておく。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [ "ec2:DescribeTags"],
      "Resource": ["*"]
    }
  ]
}

IAM ロールを設定したくないときは ec2-metadatafs コマンドを使うときに --aws-access-key-id オプションとか --aws-secret-access-key とかを指定してあげてもいい。

ec2-metadatafs を使い終わったら

ec2-metadatafs を使い終わったらというか「あんまり便利じゃないしやっぱ使わなくていいや」というお気持ちになったときは EC2 インスタンスメタデータをアンマウントしておく。

$ fusermount -u metadata

これだけ。