Skip to main content
All CollectionsFor Administrators
Cloud Labs: Bring Your Own AWS Account – Advanced
Cloud Labs: Bring Your Own AWS Account – Advanced

Advanced process to grant Vocareum permission to use your AWS account.

M
Written by Mary Gordanier
Updated this week

For Admins

In order for Vocareum to provision AWS resources in Cloud Labs, you will need to grant Vocareum permission to manage relevant aspects of your AWS account.

The standard process for connecting AWS with Vocareum entails creating an AWS User or Role, which gives Vocareum permission to generate and manage AWS accounts and policies. Vocareum clients have used this process for over 10 years and we have found it serves most organizations well.

The standard process for connecting AWS with Vocareum can be found here: Cloud Labs: Bring Your Own AWS Account.

However, some organizations have internal security policies that prohibit granting the required AWS permissions to a 3rd party provider like Vocareum. The following advanced guide covers an alternative setup process designed for organizations who wish to grant Vocareum more restricted privileges in AWS.

In this setup, you will create an Organizational Unit (OU) in your AWS Organization and add new linked accounts. You will also create a set of Service Control Policies (SCPs), attach them to your Organization Root, and finally upload a list of the new accounts to Vocareum. Vocareum will configure and provision the accounts to your users as needed for Cloud Labs based on your Organization, Course, and Assignment settings.

AWS Advanced Setup Steps

Perform the following steps in the AWS account you would like to connect with Vocareum:

  1. Create an Organizational Unit (OU) for Vocareum.

  2. Create AWS user accounts with the following root email and role specifications:

    $result = $orgclient->createAccount([
    'AccountName' => $my_id,
    'Email' => $my_email,
    'IamUserAccessToBilling' => 'ALLOW',
    'RoleName' => 'vocareum',
    ]);
    $my_id: ADD YOUR UNIQUE ID OF CHOICE HERE
    $my_email: "awslabs{$myid}" . '@vocareum.com'

    The email domain '@vocareum.com' in the linked accounts allows Vocareum to access accounts using root emails in case of need.

  3. Move the created accounts into the Vocareum OU.

  4. Create the following Service Control Policies: VocProtections and VocUnconditionalDeny.

  5. Attach FullAWSAccess, VocProtections, VocUnconditionalDeny, and any other SCPs you require to the Organization Root.

  6. In Vocareum, navigate from the course dashboard to the Control Center, then select AWS from the sidebar menu.

  7. Select Payers from the AWS menu to access the Payers page.

  8. Click the "Add payer" button.

  9. Fill out required information in the the Add Payer form and Save.

  10. Download a list of the user accounts you would like to share with Vocareum from AWS. Export the list as a CSV file and ensure it includes columns for user account ID and email.

  11. Upload the list of user accounts on the Vocareum AWS Payers page.

  12. Email support@vocareum.com to notify us of your newly-connected accounts.

From there, the Vocareum team will import your account list and use the Vocareum role to perform setup and verification steps in the linked accounts. Once the accounts are verified, we will activate your AWS payer account in Vocareum and notify you when the setup is complete.

Service Control Policies

Apply the following Service Control Policies (SCP) as indicated in the proceeding instructions.

FullAWSAccess

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}

VocProtections

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"iam:DetachRolePolicy",
"iam:DeleteRolePolicy",
"iam:DeleteRole",
"iam:GetRolePolicy",
"iam:PutRolePolicy"
],
"Resource": [
"arn:aws:iam::*:role/vocareum"
]
},
{
"Effect": "Deny",
"Action": [
"iam:DetachRolePolicy",
"iam:DeleteRolePolicy",
"iam:DeleteRole",
"iam:GetRolePolicy",
"iam:PutRolePolicy"
],
"Resource": [
"arn:aws:iam::*:role/vocareum-eventbridge"
],
"Condition": {
"StringNotLikeIfExists": {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/vocareum"
]
}
}
},
{
"Effect": "Deny",
"Action": [
"iam:GetRole",
"iam:GetRolePolicy",
"iam:UpdateAssumeRolePolicy",
"iam:UntagRole",
"iam:TagRole",
"iam:PutRolePolicy",
"iam:PutRolePermissionsBoundary",
"iam:AddRoleToInstanceProfile",
"iam:PassRole",
"iam:ListRolePolicies",
"iam:AttachRolePolicy",
"iam:UpdateRole",
"iam:RemoveRoleFromInstanceProfile",
"iam:UpdateRoleDescription"
],
"Resource": [
"arn:aws:iam::*:role/vocareum",
"arn:aws:iam::*:role/vocareum-eventbridge"
],
"Condition": {
"StringNotLikeIfExists": {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/vocareum"
]
}
}
},
{
"Sid": "IAMVocLabsDefaultPolicyMirror",
"Effect": "Deny",
"Action": [
"iam:DeletePolicy",
"iam:DeletePolicyVersion",
"iam:CreatePolicy",
"iam:CreatePolicyVersion",
"iam:GetPolicy",
"iam:GetPolicyVersion"
],
"Resource": [
"arn:aws:iam::*:policy/voc-cancel-cred",
"arn:aws:iam::*:policy/Pvoclabs*",
"arn:aws:iam::*:policy/Pvocuser*"
],
"Condition": {
"StringNotLikeIfExists": {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/vocareum"
]
}
}
},
{
"Sid": "IAMVocLabsDefaultRoleMirror",
"Effect": "Deny",
"Action": [
"iam:GetRole",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"iam:DeleteRolePolicy",
"iam:DeleteRole",
"iam:DeleteRolePermissionsBoundary",
"iam:PutRolePermissionsBoundary",
"iam:UpdateAssumeRolePolicy",
"iam:UpdateRole",
"iam:UpdateRoleDescription",
"iam:GetRolePolicy"
],
"Resource": [
"arn:aws:iam::*:role/voclabs"
],
"Condition": {
"StringNotLikeIfExists": {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/vocareum"
]
}
}
},
{
"Sid": "IAMVocLabsDefaultUserMirror",
"Effect": "Deny",
"Action": [
"iam:GetUser",
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:UpdateAccessKey",
"iam:AttachUserPolicy",
"iam:DetachUserPolicy",
"iam:DeleteUserPolicy",
"iam:DeleteUser",
"iam:GetUserPolicy",
"iam:AddUserToGroup",
"iam:DeleteUserPermissionsBoundary",
"iam:PutUserPermissionsBoundary",
"iam:UpdateUser"
],
"Resource": [
"arn:aws:iam::*:user/vocuser"
],
"Condition": {
"StringNotLikeIfExists": {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/vocareum"
]
}
}
},
{
"Sid": "ProtectEventBridge",
"Effect": "Deny",
"Action": [
"events:*"
],
"Resource": [
"arn:aws:events:*:*:rule/voc-*"
],
"Condition": {
"ArnNotLike": {
"aws:PrincipalArn": "arn:aws:iam::*:role/vocareum"
}
}
}
]
}

VocUnconditionalDeny

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"iam:DetachRolePolicy",
"iam:DeleteRolePolicy",
"iam:DeleteRole",
"iam:GetRolePolicy",
"iam:PutRolePolicy"
],
"Resource": [
"arn:aws:iam::*:role/vocareum"
]
},
{
"Effect": "Deny",
"Action": [
"iam:DetachRolePolicy",
"iam:DeleteRolePolicy",
"iam:DeleteRole",
"iam:GetRolePolicy",
"iam:PutRolePolicy"
],
"Resource": [
"arn:aws:iam::*:role/vocareum-eventbridge"
],
"Condition": {
"StringNotLikeIfExists": {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/vocareum"
]
}
}
},
{
"Effect": "Deny",
"Action": [
"iam:GetRole",
"iam:GetRolePolicy",
"iam:UpdateAssumeRolePolicy",
"iam:UntagRole",
"iam:TagRole",
"iam:PutRolePolicy",
"iam:PutRolePermissionsBoundary",
"iam:AddRoleToInstanceProfile",
"iam:PassRole",
"iam:ListRolePolicies",
"iam:AttachRolePolicy",
"iam:UpdateRole",
"iam:RemoveRoleFromInstanceProfile",
"iam:UpdateRoleDescription"
],
"Resource": [
"arn:aws:iam::*:role/vocareum",
"arn:aws:iam::*:role/vocareum-eventbridge"
],
"Condition": {
"StringNotLikeIfExists": {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/vocareum"
]
}
}
},
{
"Sid": "IAMVocLabsDefaultPolicyMirror",
"Effect": "Deny",
"Action": [
"iam:DeletePolicy",
"iam:DeletePolicyVersion",
"iam:CreatePolicy",
"iam:CreatePolicyVersion",
"iam:GetPolicy",
"iam:GetPolicyVersion"
],
"Resource": [
"arn:aws:iam::*:policy/voc-cancel-cred",
"arn:aws:iam::*:policy/Pvoclabs*",
"arn:aws:iam::*:policy/Pvocuser*"
],
"Condition": {
"StringNotLikeIfExists": {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/vocareum"
]
}
}
},
{
"Sid": "IAMVocLabsDefaultRoleMirror",
"Effect": "Deny",
"Action": [
"iam:GetRole",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"iam:DeleteRolePolicy",
"iam:DeleteRole",
"iam:DeleteRolePermissionsBoundary",
"iam:PutRolePermissionsBoundary",
"iam:UpdateAssumeRolePolicy",
"iam:UpdateRole",
"iam:UpdateRoleDescription",
"iam:GetRolePolicy"
],
"Resource": [
"arn:aws:iam::*:role/voclabs"
],
"Condition": {
"StringNotLikeIfExists": {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/vocareum"
]
}
}
},
{
"Sid": "IAMVocLabsDefaultUserMirror",
"Effect": "Deny",
"Action": [
"iam:GetUser",
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:UpdateAccessKey",
"iam:AttachUserPolicy",
"iam:DetachUserPolicy",
"iam:DeleteUserPolicy",
"iam:DeleteUser",
"iam:GetUserPolicy",
"iam:AddUserToGroup",
"iam:DeleteUserPermissionsBoundary",
"iam:PutUserPermissionsBoundary",
"iam:UpdateUser"
],
"Resource": [
"arn:aws:iam::*:user/vocuser"
],
"Condition": {
"StringNotLikeIfExists": {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/vocareum"
]
}
}
},
{
"Sid": "ProtectEventBridge",
"Effect": "Deny",
"Action": [
"events:*"
],
"Resource": [
"arn:aws:events:*:*:rule/voc-*"
],
"Condition": {
"ArnNotLike": {
"aws:PrincipalArn": "arn:aws:iam::*:role/vocareum"
}
}
}
]
}

Did this answer your question?