column

コラム

新入社員に払い出すIAMユーザーの権限を考えてみる

  • TAG

    AWS IAM
  • UPDATE

    2023/03/21

はじめに

こんにちは、クラウドCoEの熊谷です。
来年度の新卒研修を担当することになり、2022年12月から準備を進めています。

BTCの新卒研修ではグループ演習として、新卒を5名ずつのチームに分け、簡易アプリを作ってもらう予定です。

簡易アプリの基盤として利用するのはAWSです。

今まで新卒が利用するIAMユーザーには、”MFAの設定をしない限り、あらゆる操作が出来ない”というカスタムポリシーを適用しつつも、AdministratorAccessを付与して自由に作業をしてもらっていました。

今回はその権限を見直してみようと思います。

この記事はTwitterで頂いた意見を参考にしています。
みなさま本当にありがとうございました。おひとりおひとりのTweetにこちらのブログで言及できないことについて、何卒ご容赦ください。

権限を見直す際の前提

今回は原則「使わせたくないサービスのみDenyをする」方針にします。

新卒全員にUdemyのビジネスプランアカウントを配布し、「会社が用意したコンテンツ以外にも、好きな動画を見ながら好きにサービス使って良いよ!」というのが基本スタンスです。

とは言え一部のサービスは使わせないようにしなきゃねということで「特定のサービスのみAllow」でなく「使わせたくないサービスのみDeny」することにしました。

結論(新しく作った権限)

MFA強制ポリシー以外に、以下のようなカスタムポリシーを作成してみました。


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        },
        {
            "Effect": "Deny",
            "Action": [
                "sagemaker:*",
                "comprehend:*",
                "lex:*",
                "machinelearning:*",
                "polly:*",
                "rekognition:*",
                "transcribe:*",
                "translate:*",
                "personalize:*",
                "forecast:*",
                "textract:*",
                "kendra:*"
            ],
            "Resource": "*"
        },
        {
            "Sid": "DenyDeleteHostedZone",
            "Effect": "Deny",
            "Action": "route53:DeleteHostedZone",
            "Resource": "arn:aws:route53:::hostedzone/xxxxxxxxxx.net"
        },
        {
            "Sid": "DenyAllActionsToSomeServices",
            "Effect": "Deny",
            "Action": [
                "acm-pca:*",
                "snowball:*",
                "route53domains:*",
                "network-firewall:*",
                "aws-marketplace:*",
                "shield:CreateSubscription"
            ],
            "Resource": "*"
        },
        {
            "Sid": "DenyPurchaseOrCreateActionsToSomeServices",
            "Effect": "Deny",
            "Action": [
                "ec2:PurchaseReservedInstancesOffering",
                "ec2:PurchaseHostReservation",
                "ec2:PurchaseScheduledInstances"
            ],
            "Resource": "*"
        },
        {
            "Sid": "RequireInstanceType",
            "Effect": "Deny",
            "Action": "ec2:RunInstances",
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringNotLike": {
                    "ec2:InstanceType": [
                        "t2.*",
                        "t3.*",
                        "m4.*",
                        "m5.*"
                    ]
                }
            }
        },
        {
            "Sid": "RequireDatabaseClass",
            "Effect": "Deny",
            "Action": "rds:CreateDBInstance",
            "Resource": "*",
            "Condition": {
                "StringNotLike": {
                    "rds:DatabaseClass": [
                        "db.t3.*",
                        "db.m5.*"
                    ]
                }
            }
        }
    ]
}

機械学習系のサービスは使わせない

今回の研修では、機械学習系のサービスは使わないため、主要な機械学習系のサービスを利用できないようにしました。


        {
            "Effect": "Deny",
            "Action": [
                "sagemaker:*",
                "comprehend:*",
                "lex:*",
                "machinelearning:*",
                "polly:*",
                "rekognition:*",
                "transcribe:*",
                "translate:*",
                "personalize:*",
                "forecast:*",
                "textract:*",
                "kendra:*"
            ],
            "Resource": "*"
        },

ちなみに新卒達は、研修終了後は機械学習系のサービスを使える学習用の環境を使うことが許されます!

特定のRoute53のホストゾーンを消してほしくない

今回の研修では、新卒がグループごとにアプリを作る予定です。
新卒には、会社で購入したドメインにホストを追加する形で、アプリにドメインを割り当ててもらいます。
ドメインは新卒が研修で利用するのと同じAWSアカウント内のRoute53で購入していますので、新卒が誤って当該ドメインのホストゾーンを消さないように以下のようにしました。


        {
            "Sid": "DenyDeleteHostedZone",
            "Effect": "Deny",
            "Action": "route53:DeleteHostedZone",
            "Resource": "arn:aws:route53:::hostedzone/xxxxxxxxxx.net"
        },


高い利用料が発生するAWSサービスや使ってほしくないサービスを制限する

以下のサービスについても利用制限を加えました。

Network Firewall
Snowball
Route53 Domain RegisterDomain
プライベートCA
マーケットプレイス
Shield Advanced

去年、Network Firewallを作って消し忘れてしまう新卒が2人居ました。
(私も一度学習用に立てて消し忘れ、チームメンバーに指摘されたことがあります)
Network Firewallはちょっと試してみたいサービスかと思いますが、月額利用料は$0.395/hr * 24h * 30day = $284.4(約3.7万円)と高めです。
是非社員に使ってみてほしいサービスではありますが、研修で使う予定はないので新卒が使えないよう制御します。

Snowballはよく試験に出てくるサービスなので、うっかり使いたくなる新卒が居るかもしれません。こちらも使えないよう制御します。

Route53 Domain RegisterDomainとは、ホストゾーンの作成ではなく、ドメインの購入権限です。
今回の研修では、新卒がアプリ用にドメインを購入する必要はないため、新卒がドメインを購入できないようにします。

研修ではACMのDV証明書は作成してもらいますが、プライベートCAを作る必要はないので、こちらも制限を加えます。

またマーケットプレイスからサードパーティの製品をSubscribeできないようにしました。

Shield Advancedは月額3,000 USDと高額なのに、「ボタンぽち」で購入できる恐ろしいサービスです。
他社さんで「画面ぽちーでうっかり購入」という事例があったそうなので、制御することにしました。


        {
            "Sid": "DenyAllActionsToSomeServices",
            "Effect": "Deny",
            "Action": [
                "acm-pca:*",
                "snowball:*",
                "route53domains:*",
                "network-firewall:*",
                "aws-marketplace:*",
                "shield:CreateSubscription"
            ],
            "Resource": "*"
        },


EC2のRIや専用ホストの予約をさせない

新卒がEC2を初めて作成するとき、EC2のテナンシー(共有・専用)をテキトーに選んでしまうかもしれません。
専用ホストをうっかり選んでしまうと、共有インスタンスと比較して利用料金の桁が変わりますので使わせないようにします。
また新卒研修は2か月間なので、RIを使う必要もありません。


        {
            "Sid": "DenyPurchaseOrCreateActionsToSomeServices",
            "Effect": "Deny",
            "Action": [
                "ec2:PurchaseReservedInstancesOffering",
                "ec2:PurchaseHostReservation",
                "ec2:PurchaseScheduledInstances"
            ],
            "Resource": "*"
        },


特定のEC2・RDSのインスタンスファミリー・世代のみ許可する

新卒が高額なEC2のインスタンスタイプを誤って選択しないよう、研修ではt2・t3系とm4・m5系のインスタンスファミリーのみを使ってもらうことにしました。


        {
            "Sid": "RequireInstanceType",
            "Effect": "Deny",
            "Action": "ec2:RunInstances",
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringNotLike": {
                    "ec2:InstanceType": [
                        "t2.*",
                        "t3.*",
                        "m4.*",
                        "m5.*"
                    ]
                }
            }
        },



RDSも同様に、特定のクラスのみ起動できるようにしました。

        {
            "Sid": "RequireDatabaseClass",
            "Effect": "Deny",
            "Action": "rds:CreateDBInstance",
            "Resource": "*",
            "Condition": {
                "StringNotLike": {
                    "rds:DatabaseClass": [
                        "db.t3.*",
                        "db.m5.*"
                    ]
                }
            }
        }


最後に

ブログは以上になります!
果たしてこのIAMポリシーで、問題なく新卒研修を乗り越えられるのか?!
何か問題が発生したら続編ブログを書きたいと思います!

RECOMMEND

おすすめ記事一覧