AWS Organizations SCP でパブリックサブネット上のリソース作成を制御できるか試してみた

AWS Organizations SCP でパブリックサブネット上のリソース作成を制御できるか試してみた

Clock Icon2025.03.17

こんにちは!コンサルティング部のくろすけです!

AWS Organizations のサービスコントロールポリシー(以下、SCP)を使用して、パブリックサブネット上の指定以外の AWS リソース作成を制御したい。
というご要望がありましたので、技術的に可能か試してみました。

やりたいこと

AWS Organizations の SCP を使用して、パブリックサブネット上の指定以外の AWS リソース作成を制御できるかを検証しました。
具体的には、以下のようなリソースの作成を制御することを目指しました。

  • VPC エンドポイント
  • NATGateway
  • ELB
  • EC2 インスタンス
  • RDS インスタンス
  • などなど...

また、指定のアクションは許可したいという要件があったため、今回はロードバランサーの作成 (elasticloadbalancing:CreateLoadBalancer) を許可する設定を試しました。

結論

調査の結果、AWS Organizations の SCP のみでパブリックサブネット上のすべての AWS リソース作成を制御するのは難しい という結論に至りました。
理由としては、SCP で制御できるのは 「リソースタイプに subnet がある」かつ「条件キーに ResourceTag が使用可能」なアクションのみ であり、実際に制御できたのは VPC や EC2 の一部のリソースに限られたためです。

調査 & やってみた

やってみたこと

まず試してみたのは下記のような SCP です。

  1. パブリックサブネットの定義
  • 特定のリソースタグ (SubnetType=Public) を付与したサブネットをパブリックサブネットと定義。
  1. SCP の設定
  • Resource セクションと Condition セクションで、特定のリソースタグ (SubnetType=Public) が付与されたサブネットに制御を限定。
  • Deny をベースとし、NotAction を使用して必要なアクションのみ許可。
SCP
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Condition": {
        "ForAnyValue:StringEqualsIfExists": {
          "aws:ResourceTag/SubnetType": "Public"
        },
        "ArnNotLike": {
          "aws:PrincipalARN": ${制御対象外ロールなどのリスト}
        }
      },
      "NotAction": [
        "elasticloadbalancing:CreateLoadBalancer"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:subnet/*"
      ],
      "Effect": "Deny"
    }
  ]
}

結果

  • 制御できたアクション

    • ec2:CreateVpcEndpoint (VPC エンドポイントの作成)
    • ec2:CreateNatGateway (NATGatewayの作成)
    • ec2:RunInstances (EC2 インスタンスの作成)
    • など、VPC や EC2 の一部のアクション
  • 制御できなかったアクション

    • lambda:CreateFunction (Lambda 関数の作成)
    • ecs:CreateService (ECS サービスの作成)
    • rds:CreateDBInstance (RDS インスタンスの作成)
    • elasticloadbalancing:CreateLoadBalancer (ELB の作成)
    • などなど...

ここまで試して気づきましたが、きちんとドキュメントに記載がありました。

[リソースタイプ] テーブルには、Resource ポリシー要素で ARN として指定できるすべてのリソースタイプが一覧表示されます。すべてのアクションで、すべてのリソースタイプを指定できるわけではありません。一部のリソースタイプは、特定のアクションでのみ動作します。リソースタイプをサポートしないアクションを使用してステートメントでそのリソースタイプを指定する場合、ステートメントではアクセスが許可されません。Resource 要素の詳細については、「IAM JSON ポリシーの要素: リソース」を参照してください。

AWS サービスのアクション、リソース、および条件キー - サービス認可リファレンスより抜粋

[条件キー] 列には、ポリシーステートメントの Condition 要素で指定できるキーが含まれます。条件キーは、アクション、またはアクションと特定のリソースでサポートされる場合があります。キーが特定のリソースタイプと同じ行にあるかどうかには細心の注意を払ってください。このテーブルには、アクションに使用可能な、または無関係な状況のグローバル条件キーは含まれていません。グローバル条件キーの詳細については、「AWS グローバル条件コンテキストキー」を参照してください。

AWS サービスのアクション、リソース、および条件キー - サービス認可リファレンスより抜粋

よって先ほどの SCP では制御対象は、「リソースタイプに subnet がある」 かつ 「条件キーで ResourceTag が使用可能」 なアクションのみ になります。
つまり、VPC や EC2 の一部のアクションしか制御できず、パブリックサブネット上のすべてのリソース作成を SCP だけで制御するのは困難 という結論に至りました。

ちなみに、上述の SCP で elasticloadbalancing:CreateLoadBalancerNotAction に含めていますが、そもそも ELB の作成アクションは subnet をリソースとして指定できないため、この SCP では制御できません。
よって事実上のSCPは下記のようなイメージになっています。
※ただし実際は NotAction を空のリストにはできないので、下記はあくまでもイメージです。

事実上のSCPのイメージ
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Condition": {
        "ForAnyValue:StringEqualsIfExists": {
          "aws:ResourceTag/SubnetType": "Public"
        },
        "ArnNotLike": {
          "aws:PrincipalARN": ${制御対象外ロールなどのリスト}
        }
      },
      "NotAction": [],
      "Resource": [
        "arn:aws:ec2:*:*:subnet/*"
      ],
      "Effect": "Deny"
    }
  ]
}

あとがき

今回の検証では、パブリックサブネット上のすべてのリソース作成を SCP だけで制御するのは困難という結論になりました。
今回の検証範囲は SCP のみでしたが、IAM ポリシーでも同様に 「リソースタイプに subnet を指定できるか」「条件キーに ResourceTag を使用できるか」 に依存するため、IAM だけで完全に制御するのも難しい可能性があります。

個人的にはこの制御は需要ありそうだなと思っていたので、困難ということが意外でした。

もし実現可能な方法をご存知であれば、ぜひ教えてください!
以上、AWS Organizations SCP を使ったパブリックサブネット上のリソース作成制御の検証結果でした!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.