How to limit shared AWS EC2 accounts’ access to view and start all VMs yet stop only certain VMs
Posted on In Tutorial, Virtualization, WebIf a team with many accounts share and manages the virtual machines under that same AWS accounts, it is a common practice to limit AWS EC2 accounts’ access to view or start all VMs yet stop only certain VMs. For example, one account has 50 VMs tagged “prod” while 25 VMs tagged “dev”. The developers should be able to start all the “prod” and “dev” VMs while they only be able to stop the “dev” VMs unless they have accesses to the “prod” VMs. These limitations can avoid accidentally shutting down production virtual machines.
AWS gives the mechanism to achieve so in the IAM management. We show how to make use of the policies in AWS IAM management to achieve such goals.
In AWS, VMs can be tagged, and there are policies the can filter VMs by tags. There are user groups and users. User can be assgined to one or many user groups and the policies can be attached to the user groups to give access rights.
users---belong to---> user group <---attached to---policy
To limit certain users’ accesses, we can create user groups and policies attached to the user groups, and assign the users to these groups.
Table of Contents
Create policies
AWS’ policy system is very flexible and at fine granularity. The policies can be implemented as a JSON file and uploaded to AWS management console to take effect. In this example, we will create 2 policies to
- list all instances
- start all instances
- stop instances that have a tag “Prod/Dev” set to “dev”
We will implement the rules in 2 policies.
The policy control web page interface in the IAM management allows us to create new policies as follows.
We create two policies with JSON content as follows.
ListAndStartInstances
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:GetConsoleScreenshot"
],
"Resource": "arn:aws:ec2:*:*:instance/*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeAggregateIdFormat",
"ec2:DescribeVolumesModifications",
"ec2:GetHostReservationPurchasePreview",
"ec2:DescribeSnapshots",
"ec2:DescribePlacementGroups",
"ec2:DescribeHostReservationOfferings",
"ec2:DescribeInternetGateways",
"ec2:DescribeVolumeStatus",
"ec2:GetLaunchTemplateData",
"ec2:DescribeScheduledInstanceAvailability",
"ec2:DescribeSpotDatafeedSubscription",
"ec2:DescribeVolumes",
"ec2:DescribeFpgaImageAttribute",
"ec2:DescribeAccountAttributes",
"ec2:DescribeExportTasks",
"ec2:DescribeNetworkInterfacePermissions",
"ec2:DescribeReservedInstances",
"ec2:DescribeKeyPairs",
"ec2:DescribeNetworkAcls",
"ec2:DescribeRouteTables",
"ec2:DescribeEgressOnlyInternetGateways",
"ec2:DescribeReservedInstancesListings",
"ec2:DescribeSpotFleetRequestHistory",
"ec2:DescribeLaunchTemplates",
"ec2:DescribeSnapshotAttribute",
"ec2:DescribeVpcClassicLinkDnsSupport",
"ec2:DescribeVpcPeeringConnections",
"ec2:DescribeVpnConnections",
"ec2:DescribeIdFormat",
"ec2:DescribeReservedInstancesOfferings",
"ec2:DescribeFleetInstances",
"ec2:DescribeVpcEndpointServiceConfigurations",
"ec2:DescribePrefixLists",
"ec2:GetReservedInstancesExchangeQuote",
"ec2:DescribeInstanceCreditSpecifications",
"ec2:DescribeVolumeAttribute",
"ec2:DescribeVpcClassicLink",
"ec2:DescribeImportSnapshotTasks",
"ec2:DescribeVpcEndpointServicePermissions",
"ec2:GetPasswordData",
"ec2:DescribeScheduledInstances",
"ec2:DescribeImageAttribute",
"ec2:DescribeFleets",
"ec2:DescribeElasticGpus",
"ec2:DescribeReservedInstancesModifications",
"ec2:DescribeVpcEndpoints",
"ec2:DescribeSubnets",
"ec2:DescribeVpnGateways",
"ec2:DescribeMovingAddresses",
"ec2:DescribeFleetHistory",
"ec2:DescribeAddresses",
"ec2:DescribePrincipalIdFormat",
"ec2:DescribeInstanceAttribute",
"ec2:DescribeFlowLogs",
"ec2:DescribeRegions",
"ec2:DescribeDhcpOptions",
"ec2:DescribeVpcEndpointServices",
"ec2:DescribeSpotInstanceRequests",
"ec2:DescribeVpcAttribute",
"ec2:GetConsoleOutput",
"ec2:DescribeSpotPriceHistory",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeNetworkInterfaceAttribute",
"ec2:DescribeVpcEndpointConnections",
"ec2:DescribeInstanceStatus",
"ec2:DescribeHostReservations",
"ec2:DescribeIamInstanceProfileAssociations",
"ec2:DescribeTags",
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeBundleTasks",
"ec2:DescribeClassicLinkInstances",
"ec2:DescribeIdentityIdFormat",
"ec2:DescribeImportImageTasks",
"ec2:DescribeNatGateways",
"ec2:DescribeCustomerGateways",
"ec2:DescribeVpcEndpointConnectionNotifications",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSpotFleetRequests",
"ec2:DescribeHosts",
"ec2:DescribeImages",
"ec2:DescribeFpgaImages",
"ec2:DescribeSpotFleetInstances",
"ec2:DescribeSecurityGroupReferences",
"ec2:DescribeVpcs",
"ec2:DescribeConversionTasks",
"ec2:DescribeStaleSecurityGroups"
],
"Resource": "*"
}
StopDevInstances
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:StopInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Prod/Dev": "dev"
}
}
}
]
}
ListAndStartInstances allows users to view and start EC2 VMs. StopDevInstances allows users to shutdown VMs whose tag “Prod/Dev” is “dev”.
Create group
In the next step, we create a “devs” user group so that the policies can be attached to.
This can be done in the “Group” page.
Attach policies to the group
We can then attache the 2 policies to the “devs” user group.
Add users
If the users are not yet created, we need to create the users.
Add users to the group
Then we add these users to the “devs” user group.
Now, we are done in setting the “devs” user group and the policies to limit its accesses to control the VMs in AWS EC2. You can use the technique shown here further to control and manage other resources in AWS or implement other management rules.