2014/09/26

AWS::IAMのロールを使う


最近AWSをぼちぼちさわっております。

クラウド環境でAPIが使えることで夢広がりingなのはいいんですが、昔はAPIリクエスト時にアクセスキーを埋め込んでいたものの、メンテナンス性やセキュリティの面からちょっと、と思っていたので、コマンドでたたくことはあってもスクリプト化するのはちょっとためらっていました。

時は流れてIAM(Identity and Access Management)が登場、インスタンスに対してロールを関連付けることができ、前述の難点も改善されています。
というわけで、今回はIAMでちょっと遊んでみました。



Roleを作る


webコンソールから作ってみましょう。
IAM > Rolesと進んで、「Create Role」を選択します。
名前は適当に「MinimumRole」とでもしておきます。ポリシーの中身はこんな感じで。
最低限、ec2::DescribeInstancesのみを許可しておきます。今回は、リソースに対する制限は行いません。

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

インスタンスに割り当てる


作成したら、インスタンスに割り当てましょう。
普段のお好みにかかわらず、Amazon Linuxで起動するのがベターです。Amazon Linuxは最初からコマンドラインツールが入っていますからね。なお、一度作成したEC2インスタンスへのRoleの割り当てはあとから差し替えできませんので悪しからず。

ちなみに、インスタンスに割り当てるのは(正確にいえば)RoleではなくInstanceProfileです。
また、InstanceProfileに対するRoleの追加/削除は可能なようですが、一度作成したEC2インスタンスに対するInstanceProfileの差し替えは無理なようです。(APIを見る限りそうっぽい)
が、記事を書いている時点でここに下記のようなことが書いてありますので、今回はいったん同一のものとして扱います。
If you use the AWS Management Console to create a role, the console creates an instance profile automatically and gives it the same name as the role it corresponds to. However, if you use the CLI, API, the AWS SDK, or a third-party tool to create roles and instance profiles, you create the roles and instance profiles as separate actions, and you might give them different names. In that case, you need to know the names of your instance profiles as well as the names of roles they contain so that you can choose the correct instance profile when you launch an Amazon EC2 instance.
【俺訳】コンソールを利用してroleを作成する場合、自動的に同一名のinstance profileが作成されますが、それ以外(CLI、API、SDK、サードパーティツールなど)で作成する場合、roleとinstance profileそれぞれの作成は別アクションとなります。roleとinstance profileに別の名前を付与して関連付けた場合、EC2インスタンスの作成時に、必要なroleを含んだ適切なinstance profileを指定する必要があります。

いざためす


というわけで、作成したらec2-userでログインし、いきなり実行してみましょう。

$ aws ec2 describe-instances
You must specify a region or set the AWS_DEFAULT_REGION environment variable. You can also configure your region by running "aws configure".

あらあら。文句を言われてしまいました。最低限リージョンは必要なようです。
aws configureはあとでやるとして、気を取り直してもう一度。

$ aws ec2 describe-instances --region us-west-2
{
    "Reservations": [
        {
            (ここは省略)
        }
    ]
}
ちゃんと出てくるようになりました。

configureする


プログラムから実行するときはあらかじめリージョンを指定しておけばいいのですが、CLIで毎回入力するのはちょっと面倒なので、aws configureをやって覚えさせましょう。

$ aws configure
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: us-west-2
Default output format [None]:

リージョン以外は入力していませんが、それでいいんです。
EC2インスタンスに対してRole(正確にはInstanceProfile)が関連付けられているので、ここでアクセスキーを埋め込まなくても大丈夫なんです。
ちなみに、ここでconfigureした結果は「~/.aws/config」に保存されます。やり直したい場合はこのファイルを消せば初期化されます。
また、ホームディレクトリに作成されますので、複数ユーザで実行する場合はユーザごとにaws configureを実行する必要があります。
#/etc/aws/configは認識してくれませんでした。危険な情報を埋め込んでいるので、当然と言えば当然です。

初期リージョンを覚えこませましたので、今度はリージョン指定がなくても通るはず。

$ aws ec2 describe-instances
{
    "Reservations": [
        {
            (ここは省略)
        }
    ]
}

まとめっぽい


これで、インスタンスから発行されるAPIの権限管理に関して、スクリプトをいじる必要がなくなりましたね。

スクリプトごとに権限を変える場合はどうするのかって?
一つのインスタンスが持つ役割(=Role)は単一化したほうが管理しやすくありませんか?