Amazon EC2 APIのサポートされていないリソースレベルのアクセス許可について

はじめに

オペレーションチームの高橋です。

Amazon EC2 APIの多くはリソースレベルでのアクセス許可制限が可能です。
しかしながらリソールレベルのアクセス許可がサポートされていないアクションもあります。
サポートされていないアクションは見落としがちです。
今回は、リソースレベルのアクセス許可でサポートされていないアクションを指定した場合のIAMポリシー作成時のエラー内容と回避策をご紹介します。

作成するIAMポリシー

例として以下IAMポリシーを作成します。

  • Resources:特定のEC2インスタンス
  • Actions:EC2インスタンスの停止、起動、再起動、AMIの作成
  • Effect: 許可

エラーになるIAMポリシー

「Policy Generator」で以下IAMポリシーを作成したとします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt000",
            "Effect": "Allow",
            "Action": [
                "ec2:Describe*",
                "ec2:CreateImage",
                "ec2:CreateSnapshot",
                "ec2:RebootInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-west-2:<aws account id>:instance/<instance id>"
            ]
        }
    ]
}

問題ないように見えますがこの中にリソースレベルでのアクセス許可がサポートされていないアクションがあります。
そのため、リソースレベルでサポートされていないアクションを実行すると「You are not authorized to perform this operation.」とエラーが発生します。

$ aws ec2 create-image --no-reboot --name "backup-${today}-${instance-id}" --instance-id ${instance-id}

An error occurred (UnauthorizedOperation) when calling the CreateImage operation: You are not authorized to perform this operation.

修正後のIAMポリシー

リソースレベルのアクセス許可がサポートされているアクションとサポートされていないアクションでStatementを分けて作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt000",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateImage",
                "ec2:CreateSnapshot",
                "ec2:Describe*"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "Stmt001",
            "Effect": "Allow",
            "Action": [
                "ec2:RebootInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-west-2:<aws account id>:instance/<instance id>"
            ]
        }
    ]
}

リソースレベルでサポートされているアクション

  • RebootInstances
  • StartInstances
  • StopInstances

これらのアクションはリソースレベルでのアクセス許可が可能ですので「Resource element」を使用して制御します。

{
            "Sid": "Stmt001",
            "Effect": "Allow",
            "Action": [
                "ec2:RebootInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-west-2:<aws account id>:instance/<instance id>"
            ]
        }

リソースレベルレベルでサポートされていないアクション

  • CreateSnapshot
  • CreateImage
  • Describe*

これらのアクションはリソースレベルでのアクセス許可がサポートされていません。
そのため「Resource element」は「*」で対応しないとなりません。

        {
            "Sid": "Stmt000",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateImage",
                "ec2:CreateSnapshot",
                "ec2:Describe*"
            ],
            "Resource": [
                "*"
            ]
        },

リソールレベルでの制御がサポートされていないアクション一覧

現時点で以下のアクションに対してはリソースレベルでの制御が許可されていません。
そのため、先ほどのIAMポリシーのように「Resource element」は「*」で対応します。

Granting IAM Users Required Permissions for Amazon EC2 Resources | Unsupported Resource-Level Permissions

AcceptReservedInstancesExchangeQuote
AllocateAddress
AllocateHosts
AssignIpv6Addresses
AssignPrivateIpAddresses
AssociateAddress
AssociateDhcpOptions
AssociateRouteTable
AssociateSubnetCidrBlock
AssociateVpcCidrblock
AttachInternetGateway
AttachNetworkInterface
AttachVpnGateway
BundleInstance
CancelBundleTask
CancelConversionTask
CancelExportTask
CancelImportTask
CancelReservedInstancesListing
CancelSpotFleetRequests
CancelSpotInstanceRequests
ConfirmProductInstance
CopyImage
CopySnapshot
CreateCustomerGateway
CreateDefaultVpc
CreateDhcpOptions
CreateEgressOnlyInternetGateway
CreateFlowLogs
CreateFpgaImage
CreateImage
CreateInstanceExportTask
CreateInternetGateway
CreateKeyPair
CreateNatGateway
CreateNetworkAcl
CreateNetworkAclEntry
CreateNetworkInterface
CreateNetworkInterfacePermission
CreatePlacementGroup
CreateReservedInstancesListing
CreateRoute
CreateRouteTable
CreateSecurityGroup
CreateSnapshot
CreateSpotDatafeedSubscription
CreateSubnet
CreateVpc
CreateVpcEndpoint
CreateVpnConnection
CreateVpnConnectionRoute
CreateVpnGateway
DeleteEgressOnlyInternetGateway
DeleteFlowLogs
DeleteKeyPair
DeleteNatGateways
DeleteNetworkInterface
DeleteNetworkInterfacePermission
DeletePlacementGroup
DeleteSnapshot
DeleteSpotDatafeedSubscription
DeleteSubnet
DeleteVpc
DeleteVpcEndpoints
DeleteVpnConnection
DeleteVpnConnectionRoute
DeleteVpnGateway
DeregisterImage
DescribeAccountAttributes
DescribeAddresses
DescribeAvailabilityZones
DescribeBundleTasks
DescribeClassicLinkInstances
DescribeConversionTasks
DescribeCustomerGateways
DescribeDhcpOptions
DescribeEgressOnlyInternetGateways
DescribeElasticGpus
DescribeExportTasks
DescribeFlowLogs
DescribeFpgaImages
DescribeHosts
DescribeIamInstanceProfileAssociations
DescribeIdentityIdFormat
DescribeIdFormat
DescribeImageAttribute
DescribeImages
DescribeImportImageTasks
DescribeImportSnapshotTasks
DescribeInstanceAttribute
DescribeInstances
DescribeInstanceStatus
DescribeInternetGateways
DescribeKeyPairs
DescribeMovingAddresses
DescribeNatGateways
DescribeNetworkAcls
DescribeNetworkInterfaceAttribute
DescribeNetworkInterfacePermissions
DescribeNetworkInterfaces
DescribePlacementGroups
DescribePrefixLists
DescribeRegions
DescribeReservedInstances
DescribeReservedInstancesListings
DescribeReservedInstancesModifications
DescribeReservedInstancesOfferings
DescribeRouteTables
DescribeScheduledInstanceAvailability
DescribeScheduledInstances
DescribeSecurityGroupReferences
DescribeSecurityGroups
DescribeSnapshotAttribute
DescribeSnapshots
DescribeSpotDatafeedSubscription
DescribeSpotFleetInstances
DescribeSpotFleetRequestHistory
DescribeSpotFleetRequests
DescribeSpotInstanceRequests
DescribeSpotPriceHistory
DescribeStaleSecurityGroups
DescribeSubnets
DescribeTags
DescribeVolumeAttribute
DescribeVolumes
DescribeVolumesModifications
DescribeVolumeStatus
DescribeVpcAttribute
DescribeVpcClassicLink
DescribeVpcClassicLinkDnsSupport
DescribeVpcEndpoints
DescribeVpcEndpointServices
DescribeVpcPeeringConnections
DescribeVpcs
DescribeVpnConnections
DescribeVpnGateways
DetachInternetGateway
DetachNetworkInterface
DetachVpnGateway
DisableVgwRoutePropagation
DisableVpcClassicLinkDnsSupport
DisassociateAddress
DisassociateRouteTable
DisassociateSubnetCidrBlock
DisassociateVpcCidrBlock
EnableVgwRoutePropagation
EnableVolumeIO
EnableVpcClassicLinkDnsSupport
GetConsoleOutput
GetHostReservationPurchasePreview
GetPasswordData
GetReservedInstancesExchangeQuote
ImportImage
ImportInstance
ImportKeyPair
ImportSnapshot
ImportVolume
ModifyHosts
ModifyIdentityIdFormat
ModifyIdFormat
ModifyImageAttribute
ModifyInstanceAttribute
ModifyInstancePlacement
ModifyNetworkInterfaceAttribute
ModifyReservedInstances
ModifySnapshotAttribute
ModifySpotFleetRequest
ModifySubnetAttribute
ModifyVolume
ModifyVolumeAttribute
ModifyVpcAttribute
ModifyVpcEndpoint
ModifyVpcPeeringConnectionOptions
MonitorInstances
MoveAddressToVpc
PurchaseHostReservation
PurchaseReservedInstancesOffering
PurchaseScheduledInstances
RegisterImage
ReleaseAddress
ReleaseHosts
ReplaceNetworkAclAssociation
ReplaceNetworkAclEntry
ReplaceRoute
ReplaceRouteTableAssociation
ReportInstanceStatus
RequestSpotFleet
RequestSpotInstances
ResetImageAttribute
ResetInstanceAttribute
ResetNetworkInterfaceAttribute
ResetSnapshotAttribute
RestoreAddressToClassic
RunScheduledInstances
UnassignIpv6Addresses
UnassignPrivateIpAddresses
UnmonitorInstances

まとめ

今回はAMIの作成を許可するポリシーを例に、リソースレベルのアクセス許可がサポートされているアクション、
されていないアクションのご紹介や、対応方法についてご紹介しました。

参考URL

Granting IAM Users Required Permissions for Amazon EC2 Resources Demystifying EC2 Resource-Level Permissions

ではまた。