EC2インスタンスの作成や起動/停止をタグベースのIAMポリシーで制御する例

タグベースのIAMポリシーを使ったEC2インスタンスへのオペレーション制御例です
2020.12.18

目次

  1. 概要
    1. EC2 利用制限の内容
  2. Developer のIAMポリシー設計
    1. 始めにまとめ
    2. DenyUntagRole
    3. DenyRunInstancesCondition
    4. DenyEC2OperationsCondition
    5. DenyEC2DeleteTagsCondition
    6. DenyEC2CreateTagsCondition
  3. 動作確認
    1. 前提
    2. インスタンスの起動
    3. インスタンスの起動/停止/再起動/終了
    4. タグの編集・削除対策
  4. まとめ
  5. 参考

概要

img

  • 管理者(Administrator) が開発者(Developer)の IAMロールを管理
    • 所属するプロジェクト Project を示すタグを付与する
  • 開発者(Developer) は 自身のロールに付与された Project タグの値に基づいて、 EC2利用が制限される

上記を実現させるための IAMポリシー例を紹介します。

EC2 利用制限の内容

IAMロールに タグ Project: XXX が付与された開発者がいたとします。 この開発者は以下に記す制限を受けるようにします。

インスタンス作成

インスタンス作成(RunInstances)時に タグ Project: XXX を付与しないといけません。

インスタンス起動/停止/再起動/終了

タグ Project: XXX が付与されたインスタンスのみ 実施できます。

Developer のIAMポリシー設計

前提として PowerUserAccess をベースに設計します。 PowerUserAccess に追加の Deny ポリシーを付与して実現します。

始めにまとめ

始めに 追加するポリシー全体の json を載せます。 それぞれの内容を後述で解説します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyUntagRole",
            "Effect": "Deny",
            "Action": "iam:UntagRole",
            "Resource": "*"
        },
        {
            "Sid": "DenyRunInstancesCondition",
            "Effect": "Deny",
            "Action": "ec2:RunInstances",
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringNotEqualsIfExists": {
                    "aws:RequestTag/Project": "${aws:PrincipalTag/Project}"
                }
            }
        },
        {
            "Sid": "DenyEC2OperationsCondition",
            "Effect": "Deny",
            "Action": [
              "ec2:StartInstances",
              "ec2:StopInstances",
              "ec2:RebootInstances",
              "ec2:TerminateInstances"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringNotEqualsIfExists": {
                    "ec2:ResourceTag/Project": "${aws:PrincipalTag/Project}"
                }
            }
        },
        {
            "Sid": "DenyEC2DeleteTagsCondition",
            "Effect": "Deny",
            "Action": "ec2:DeleteTags",
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringLike": {
                    "aws:RequestTag/Project": "*"
                }
            }
        },
        {
            "Sid": "DenyEC2CreateTagsCondition",
            "Effect": "Deny",
            "Action": "ec2:CreateTags",
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringLike": {
                    "aws:RequestTag/Project": "*"
                },
                "StringNotEquals": {
                  "ec2:CreateAction" : "RunInstances"
                }
            }
        }
    ]
}

DenyUntagRole

"Effect": "Deny",
"Action": "iam:UntagRole",
"Resource": "*"

タグ周りルール敷設のためのポリシーです。 開発者が自身のIAMロールの Project タグを削除できないようにするためのポリシーです。

DenyRunInstancesCondition

"Sid": "DenyRunInstancesCondition",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
    "StringNotEqualsIfExists": {
        "aws:RequestTag/Project": "${aws:PrincipalTag/Project}"
    }
}

インスタンスの起動を以下のケース時に拒否します。

  • Project タグを設定していないとき
  • Project タグの値が「実行者 IAMロールの Project タグの値」と異なるとき

DenyEC2OperationsCondition

"Sid": "DenyEC2OperationsCondition",
"Effect": "Deny",
"Action": [
  "ec2:StartInstances",
  "ec2:StopInstances",
  "ec2:RebootInstances",
  "ec2:TerminateInstances"
],
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
    "StringNotEqualsIfExists": {
        "ec2:ResourceTag/Project": "${aws:PrincipalTag/Project}"
    }
}

インスタンスのオペレーション(起動/停止/再起動/終了)を以下のケース時に拒否します。

  • 「対象インスタンスに付与された Project タグの値」が 「実行者 IAMロールの Project タグの値」と異なるとき

DenyEC2DeleteTagsCondition

"Sid": "DenyEC2DeleteTagsCondition",
"Effect": "Deny",
"Action": "ec2:DeleteTags",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
    "StringLike": {
        "aws:RequestTag/Project": "*"
    }
}

タグ周りルール敷設のためのポリシーです。 Project タグを削除できないようにしています。

DenyEC2CreateTagsCondition

"Sid": "DenyEC2CreateTagsCondition",
"Effect": "Deny",
"Action": "ec2:CreateTags",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
    "StringLike": {
        "aws:RequestTag/Project": "*"
    },
    "StringNotEquals": {
      "ec2:CreateAction" : "RunInstances"
    }
}

タグ周りルール敷設のためのポリシーです。 Project タグを作成・更新できないようにしています。

ただし インスタンス新規作成(RunInstances)時には このアクションは許可しないといけないため、例外としています。

動作確認

前提

Developer に以下IAMポリシーを割り当てています。 ec2-restriction は先程のIAMポリシーです。

img

タグには Developer の所属プロジェクトを表す Project:XXX を付与しています。

img

インスタンスの起動

Project:XXX を指定するとインスタンス起動(RunInstances)は成功します

aws ec2 run-instances --image-id ami-00f045aed21a55240 --instance-type t3.nano \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Project,Value=XXX},{Key=Name,Value=test}]'
# Groups: []
# Instances:
# - AmiLaunchIndex: 0
#   Architecture: x86_64
#   BlockDeviceMappings: []
#   CapacityReservationSpecification:
#     CapacityReservationPreference: open
# (以下略)

Project タグの値が XXX でないと実行は失敗します

aws ec2 run-instances --image-id ami-00f045aed21a55240 --instance-type t3.nano \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Project,Value=YYY},{Key=Name,Value=test}]'
# An error occurred (UnauthorizedOperation) when calling the RunInstances operation:
# You are not authorized to perform this operation. Encoded authorization failure message: f1lELk...

▼ もちろん Project タグを付けずに作成はできません

aws ec2 run-instances --image-id ami-00f045aed21a55240 --instance-type t3.nano \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=test}]'
# An error occurred (UnauthorizedOperation) when calling the RunInstances operation:
# You are not authorized to perform this operation. Encoded authorization failure message: oYBLbJUS...

インスタンスの起動/停止/再起動/終了

事前に所属プロジェクト情報を付与した 2インスタンスを準備します。

### Project:XXX のインスタンス情報
aws ec2 describe-instances --query 'Reservations[].Instances[].Tags' --output table \
--filters Name=instance-id,Values=$ID_XXX
# ---------------------------------
# |       DescribeInstances       |
# +----------+--------------------+
# |    Key   |       Value        |
# +----------+--------------------+
# |  Project |  XXX               |
# |  Name    |  instance-for-XXX  |
# +----------+--------------------+

### Project:YYY のインスタンス情報
aws ec2 describe-instances --query 'Reservations[].Instances[].Tags' --output table \
--filters Name=instance-id,Values=$ID_YYY
# ---------------------------------
# |       DescribeInstances       |
# +----------+--------------------+
# |    Key   |       Value        |
# +----------+--------------------+
# |  Project |  YYY               |
# |  Name    |  instance-for-YYY  |
# +----------+--------------------+

プロジェクトの同じインスタンスへのオペレーション

起動/停止/再起動/終了が成功します。

aws ec2 start-instances --instance-ids $ID_XXX
# StartingInstances:
# - CurrentState:
#     Code: 0
#     Name: pending
# (以下略)

aws ec2 reboot-instances --instance-ids $ID_XXX
# (成功)

aws ec2 stop-instances --instance-ids $ID_XXX
# StoppingInstances:
# - CurrentState:
#     Code: 64
#     Name: stopping
# (以下略)

aws ec2 terminate-instances --instance-ids $ID_XXX
# TerminatingInstances:
# - CurrentState:
#     Code: 48
#     Name: terminated
# (以下略)

プロジェクトの異なるインスタンスへのオペレーション

プロジェクトが異なる場合は、全て失敗します。

aws ec2 start-instances --instance-ids $ID_YYY
# An error occurred (UnauthorizedOperation) when calling the StartInstances operation: You are not authorized to perform this operation...

aws ec2 reboot-instances --instance-ids $ID_YYY
# An error occurred (UnauthorizedOperation) when calling the RebootInstances operation: You are not authorized to perform this operation...

aws ec2 stop-instances --instance-ids $ID_YYY
# An error occurred (UnauthorizedOperation) when calling the StopInstances operation: You are not authorized to perform this operation...

aws ec2 terminate-instances --instance-ids $ID_YYY
# An error occurred (UnauthorizedOperation) when calling the TerminateInstances operation: You are not authorized to perform this operation...

タグの編集・削除対策

以下のように Project タグは編集・削除できないようになっています。

aws ec2 create-tags --resources $ID_XXX --tags Key=Project,Value=ZZZ
# An error occurred (UnauthorizedOperation) when calling the CreateTags operation: You are not authorized to perform this operation...

aws ec2 create-tags --resources $ID_YYY --tags Key=Project,Value=ZZZ
# An error occurred (UnauthorizedOperation) when calling the CreateTags operation: You are not authorized to perform this operation...

aws ec2 delete-tags --resources $ID_XXX --tags Key=Project,Value=XXX
# An error occurred (UnauthorizedOperation) when calling the DeleteTags operation: You are not authorized to perform this operation...

aws ec2 delete-tags --resources $ID_YYY --tags Key=Project,Value=YYY
# An error occurred (UnauthorizedOperation) when calling the DeleteTags operation: You are not authorized to perform this operation...

まとめ

少しでもどなたかのお役に立てば幸いです。

タグベースの制御はポリシーの作成だけではなく、 タグの管理/運用も必要になってきます。 まずはAWSアカウントによる権限分離で対応できないか、検討しましょう。

参考