ばーろぐわにる

SIerからWEB系?インフラエンジニアにジョブチェンジした見習いの備忘録

EC2のNameタグにプレフィックスがついてるインスタンスだけ操作させたい

やりたいこと

Nameタグに任意のプレフィックスが付与されているインスタンスのみを対象に起動・停止・再起動ができるIAMポリシーを作りたい。たとえば"dev-*"みたいな感じ。操作できる環境を定義するのに利用できる。まあベストなのは"Env"みたいなタグを作ってそれで判断させるのが一番なんだろうけど

IAMポリシー

Condition エレメント、条件演算子StringLike を利用すれば実現できそう。

Condition

日付、時間、IPアドレス、ユーザ名、ユーザエージェントなどを条件値として設定し、権限が許可される条件を細かく設定できる。例えばこんな感じ。

  • 08:00~20:00の間だけインスタンスを起動できる
  • 特定のリージョンにのみインスタンスを作成できる
  • MFA認証が一定時間内に実施されたアカウントの操作のみを許可する

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_condition-keys.html

StringLike

大文字、小文字を区別。複数文字、1文字一致のワイルドカードを利用することができる

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html

設定

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:RebootInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Condition": {
                "StringLike": {
                    "ec2:ResourceTag/Name": "dev-*"
                }
            },
            "Resource": [
                "*"
            ]
        }
    ]
}

動作確認

インスタンス

$ aws ec2 describe-instances --profile private | jq '.Reservations[].Instances[] | [.InstanceId, .Tags]'
[
  "i-0bc3ba07b14a60389",
  [
    {
      "Key": "Name",
      "Value": "WEB01"
    }
  ]
]
[
  "i-08b9186b607b904cb",
  [
    {
      "Key": "Name",
      "Value": "dev-web01"
    }
  ]
]

WEB01を停止しようとすると...

$ aws ec2 stop-instances --instance-ids i-0bc3ba07b14a60389 --profile dev-stopper

An error occurred (UnauthorizedOperation) when calling the StopInstances operation: You are not authorized to perform this operation. Encoded authorization failure message: ...

dev-web01を停止しようとすると...

$ aws ec2 stop-instances --instance-ids i-08b9186b607b904cb --profile dev-stopper
{
    "StoppingInstances": [
        {
            "CurrentState": {
                "Code": 64,
                "Name": "stopping"
            },
            "InstanceId": "i-08b9186b607b904cb",
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}

感想

普段はStringEquals使うことのほうが多いかもしれませんが、StringLikeも中々に便利そう。