As mentioned in my past blog, Eucalyptus has the concept of EUARE (IAM) Roles which pretty much work the same way as AWS IAM Roles. This blog with discuss how to set up cross-account API access using EUARE (IAM) Roles in Eucalyptus 4.0.2. Cross-account API access is very useful for use cases where there are multiple Eucalyptus EUARE accounts that need to access the same resources. A great example of this can be found in the AWS IAM documentation regarding this same feature.
To establish cross-account access, in the trusting account (Account A), you create an IAM role that designates Account B as the trusted account. The role also defines permissions that allow Account B access to specific resources in Account A. Account B can then delegate this access to its own users (IAM users or federated users). Account B cannot delegate more access to its users than the permissions that it has been granted by Account A.
To demonstrate this feature, a user in Account A will set up a role to allow DescribeInstances API access for a user in Account B.
Prerequisites
Before getting started, the following resources are needed:
- Eucalyptus 4.0.2 Cloud with Eucalyptus DNS enabled
- Two non-‘eucalyptus‘ accounts created (for example, AccountA and AccountB)
- Eucalyptus Machine Images (EMIs) available to be launched as instances
- Running instance(s) under AccountA
- Latest version of euca2ools
Once these prerequisites are met, the cross-account role use case can be deployed.
NOTE: All actions are assumed to be performed by a user under the given account. All IAM actions can be done by the cloud administrator (i.e. user under the ‘eucalyptus’ account) if so desired.
Account A EUARE (IAM) Setup
Before setting up the role in Account A, the minimal EUARE (IAM) access policy needed by the user in Account A in order to create the role. The access policy can be found here:
This policy allows the user to perform the following EUARE (IAM) API actions:
- Create a role
- List roles
- Upload a policy to a role
Using IAM best practices, apply this policy to the group that has this user as a member under Account A, using the euare-groupuploadpolicy command.
Trust Policy for Role in Account A
In order for the user in Account B (in this example, the user is ‘user12’) to be able to assume the role under Account A, a trust policy needs to be associated with the role. Below is an example of the trust policy (which can be downloaded from here):
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::325271821652:user/user12"}, "Action": "sts:AssumeRole" }] }
This states that ‘user12’ under the Account ID ‘325271821652‘ (which maps to Account B) can assume this role. To create the role, use the euare-rolecreate command as follows:
# euare-rolecreate --role-name cross-describe-instances --file-name euare-accountA-role-trust.policy
IAM Access Policy for Role under Account A
After creating the role, now the API access (in this case – DescribeInstances) needs to be associated by uploading an IAM access policy for the role. Here is an example of the policy:
{ "Statement": [ { "Sid": "Stmt1417530823611", "Action": [ "ec2:DescribeInstances" ], "Effect": "Allow", "Resource": "*" } ] }
This policy can be downloaded from here. Use euare-roleuploadpolicy to upload the access policy to the role. For example:
# euare-roleuploadpolicy --role-name cross-describe-instances --policy-name describe-instances --policy-document euare-accountA-role-access.policy
Once this has been completed, all work is done under Account A. Next, the user under Account B needs to be allowed to assume the role. The only important information needed from Account A, is the ARN for the role – which in this use case is the following:
arn:aws:iam::290122656840:role/cross-describe-instances
Account B EUARE (IAM) Setup
Before applying the policy to allow assuming the role to the group where ‘user12’ is a member, the user needs to be able to do the following at a minimum:
- Generate Access Keys
- List Access Keys
- List groups
- Upload IAM policies to groups
An example IAM access policy of these actions can be found here:
As mentioned above, apply this policy to the group that has ‘user12’ as a member under Account B, using the euare-groupuploadpolicy command.
Assume Role Access
To allow ‘user12’ under Account B to assume the role under Account A, we need to upload another policy. This can be done to the group that has ‘user12’ as a member, or directly to ‘user12’ by using euare-useruploadpolicy. The key information needed in the IAM policy is the ARN of the role (arn:aws:iam::290122656840:role/cross-describe-instances). The policy should look something similar to this:
{ "Statement": [ { "Sid": "Stmt1417531456446", "Action": [ "sts:AssumeRole" ], "Effect": "Allow", "Resource": "arn:aws:iam::290122656840:role/cross-describe-instances" } ] }
This policy can be downloaded from here:
To keep consistent with IAM best practices, euare-groupuploadpolicy will be used to upload the policy to the group that has ‘user12’ as a member:
# euare-groupuploadpolicy --policy-name assume-role-run-describe-instances --group-name Testers --policy-document euare-accountB-assume-role.policy
Once the policy is uploaded, we just need to test out the cross-account access.
Testing with Python Boto
To confirm that the cross-account access works, we will use the boto – a python interface to AWS, which also works with Eucalyptus. Below is an example script with performs the following actions:
- Accesses the Eucalyptus STS service to obtain a temporary access key, secret key and token of the assumed role
- Performs the DescribeInstances API call
#!/bin/env python import boto from boto.sts import STSConnection from boto.ec2.connection import EC2Connection if __name__ == "__main__": """ Assuming 'describe-instances' role by AccountB, User12 user """ STSConnection.DefaultRegionEndpoint = "tokens.future.euca-hasp.cs.prc.eucalyptus-systems.com" sts_connection = STSConnection(aws_access_key_id="<Account B User Access Key>", aws_secret_access_key="<Account B User Secret Key>", is_secure=False, port="8773") assumedRoleObject = sts_connection.assume_role( role_arn="arn:aws:iam::290122656840:role/cross-describe-instances", role_session_name="Acct2User12DescribeInstancesSession") EC2Connection.DefaultRegionEndpoint = "compute.future.euca-hasp.cs.prc.eucalyptus-systems.com" ec2_connection = EC2Connection(aws_access_key_id=assumedRoleObject.credentials.access_key, aws_secret_access_key=assumedRoleObject.credentials.secret_key, security_token=assumedRoleObject.credentials.session_token, is_secure=False, port="8773") reservations = ec2_connection.get_all_instances() if len(reservations) > 0: print "Instance Information:" for reservation in reservations: for instance in reservation.instances: print "\t--------------------------------------" print "\tInstance ID:\t" + instance.id print "\tInstance State:\t" + instance.state print "\tPublic DNS Name:\t" + instance.public_dns_name print "\tLaunch Time:\t" + instance.launch_time else: print "No Instance Reservations Available."
The script can be downloaded from here:
To use the script, the following information is needed:
- For STSConnection.DefaultRegionEndpoint, use the Eucalyptus DNS name for Eucalyptus Token service associated with your Eucalyptus 4.0.2 cloud (e.g. “tokens.future.euca-hasp.cs.prc.eucalyptus-systems.com“)
- For EC2Connection.DefaultRegionEndpoint, use the Eucalyptus DNS name for Eucalyptus Compute service associated with your Eucalyptus 4.0.2 cloud (e.g. “compute.future.euca-hasp.cs.prc.eucalyptus-systems.com“)
- Access Key ID and Secret Access Key of the ‘user12’ user under Account B.
Running the Script
After downloading the script, and perform the edits to match your Eucalyptus 4.0.2 environment, make sure the executable bit is set on the script, and run it:
# ./describe-instance-script.py
Instance Information: -------------------------------------- Instance ID: i-f97462d3 Instance State: running Public DNS Name: euca-10-104-7-27.future.future.euca-hasp.cs.prc.eucalyptus-systems.com Launch Time: 2014-12-03T16:22:54.113Z
Observe how the script has listed the instance under Account A. Confirm this by using the credentials of a user under Account A, and running euca-describe-instances:
# euca-describe-instances --region accountA-user01@ RESERVATION r-370ded0a 290122656840 default INSTANCE i-f97462d3 emi-bdcec010 euca-10-104-7-27.future.future.euca-hasp.cs.prc.eucalyptus-systems.com euca-172-17-176-24.future.internal running account1-user01 0 m1.medium 2014-12-03T16:22:54.113Z Honest monitoring-disabled 10.104.7.27 172.17.176.24 instance-store hvm sg-525fe580 x86_64
Conclusion
Cross-account access using Eucalyptus EUARE (IAM) roles are very powerful. It allows cloud administrators and account administrators to provide access to limited resources in different accounts without having the hassle of creating/managing users. Please refer to the AWS IAM documentation for further examples and use cases. Enjoy!