【AWS】EC2をリソースレベルでアクセス許可してみた

2013.07.10

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

はじめに

こんにちは植木和樹です。2013年7月9日に「EC2とRDSをリソースレベルでアクセス制限する機能」が発表されましたので、さっそく使ってみました。

【AWS発表】EC2とRDSのリソースにリソースレベルのアクセス許可を設定可能に

この機能を聞いて最初に思いついたのが、学校の授業などでAWSを使うケースです。生徒ごとに専用EC2やRDSインスタンスを割り当て、自分所有のインスタンス以外は停止・破棄できないように制限するという使い方です。学校の授業や会社のオペトレ時のように「利用者ごとにAWSアカウントを分けることは難しいけれど、利用者がお互いのリソースに干渉するのは防ぎたい」というシチュエーションには便利な機能ではないでしょうか。

ちなみにクラスメソッドでは、開発環境と本番環境はAWSアカウントレベルで区別することを推奨しているため「開発者に本番環境を操作させたくない・・・」といったシチュエーションは少ないかもです。

IAMを用いたリソースのアクセス制限

IAMによるリソース制限を簡単にまとめると次のような制限が可能です。

人/動作/リソース 設定対象 設定例
誰が IAMユーザ または IAMグループ iam-user-A
iam-admin-group
何に リソース または 条件 arn:aws:ec2:ap-northeast-1:123456789012:instance/i-12345678
タグ: Name=WebServer
どのような操作ができるか アクション ec2:StartInstances
ec2:describe*

実際に確認してみる

EC2インスタンスの作成

まずはEC2インスタンスを2つ用意しましょう。t1.micro でまったく同じ構成です。起動後分かりやすいように名前(Name)をつけておきましょう。

130709-0005

IAMユーザの作成

作成した2台のEC2インスタンス(node-A,node-B)をそれぞれ専有する2人のユーザ(iam-user-A、iam-user-B)を作成しましょう。2ユーザの権限は次のように設定したいと思います。

ユーザ 対象リソース 可能な操作
ユーザA、ユーザB すべてのEC2 情報の表示
ユーザA EC2: node-A EC2の起動、停止、リブート
ユーザB EC2: node-B EC2の起動、停止、リブート、ターミネイト

まずはマネージメントコンソールのIAMのページで2つのユーザを作成します。

130709-0003

マネージメントコンソールにログインできるようパスワードも設定しておきましょう。

130709-0016

次にユーザAのポリシーを設定します。

130709-0004

130710-0001

カスタムポリシーで下記JSONをテキストエリアに貼り付けて"Apply Policy"します。Resourceで arn を指定することで node-A のみをStartInstance/RebootInstance/StopInstance 操作できます。arnの"123456789012"はAWSアカウントIDです。("::"でアカウントID省略記法が使えるか試したのですが、省略はできないようです)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "ec2:describe*"
      ],
      "Sid": "Stmt1373379895000",
      "Resource": [
        "*"
      ],
      "Effect": "Allow"
    },
    {
      "Action": [
        "ec2:StartInstances",
        "ec2:RebootInstances",
        "ec2:StopInstances"
      ],
      "Sid": "Stmt1373378552000",
      "Resource": [
        "arn:aws:ec2:ap-northeast-1:123456789012:instance/i-54440856"
      ],
      "Effect": "Allow"
    }
  ]
}

ユーザBについては次のポリシーを設定します。こちらは arn ではなく、タグ(Name=node-B)でリソースを指定しています。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "ec2:describe*"
      ],
      "Sid": "Stmt1373379896000",
      "Resource": [
        "*"
      ],
      "Effect": "Allow"
    },
    {
      "Action": [
        "ec2:RebootInstances",
        "ec2:StartInstances",
        "ec2:StopInstances",
        "ec2:TerminateInstances"
      ],
      "Sid": "Stmt1373381303000",
      "Condition": {
        "StringEquals": {
          "ec2:ResourceTag/Name": "node-B"
        }
      },
      "Resource": [
        "*"
      ],
      "Effect": "Allow"
    }
  ]
}

なおIAMのポリシーJSONを作成するときは「Policy Generator」を使って生成されるJSONを確認しながら進めると楽です。

マネージメントコンソールからEC2を操作する

マネージメントコンソールでユーザA、ユーザBそれぞれでログインし、ここまでに設定してきたアクセスが可能か確認してみましょう。

まず ユーザA でログインします。

130709-0019

ユーザAは node-A の起動、停止、リブートはできますがターミネイトはできません。

130709-0020 130709-0022

またユーザAは node-B については情報をみる以外、一切操作できません。

次に ユーザB でログインします。ユーザBは node-B の起動、停止、リブートができ、ターミネイトもできます。node-A については情報をみる以外、一切操作できません。

130709-0030

インスタンスを両方同時に停止しようとしても操作ができません。

130709-0024

まとめ

今回はEC2のARNとEC2のタグで指定したリソースに対してアクセス制限を行なってみました。発表ではRDSもリソース単位の制限がかけられるようになったそうなので機会をみて試してみたいです。

またIAMを用いたリソースレベルのアクセス制限は、条件(Condition)によってより高度な制限がかけられるようになっています(条件については今回タグ名でリソースを指定するのに使用しています)。例えば "StringEquals" : { "ec2Region" : "ap-northeast-1" } と指定することでTokyoリージョン以外ではEC2インスタンスを起動できなくしたり、ec2InstanceTypeで m1.small 以外のインスタンスタイプを使えなくしたりすることも(CreateInstanceアクションが設定対象になれば将来的には)できそうです。(指定できる条件のリスト

授業中生徒に「時間あたり460ドルのコストを払って、ハイストレージ・エイトエクストララージ(hs1.8xlarge) を100台起動!」なんてことをされないよう、必要に応じてアクセス制限はかけておきたいものです。