Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cloud9-alpha): add support for federated-user and assumed-role for Cloud9 environment ownership #27001

Merged
merged 28 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c3f82ab
Adds test case for roles as environment owners
markusz Sep 4, 2023
600a4dc
Implements Owner.role(..) to support role ownership in the cloud9 con…
markusz Sep 4, 2023
2f88452
Improves existing test case for user ownership by replacing a hardcod…
markusz Sep 4, 2023
7b2d115
Updates generated file THIRD_PARTY_LICENSES
markusz Sep 4, 2023
6646ca3
Fixes ESLint checks
markusz Sep 4, 2023
c557191
Merge branch 'main' into cloud9-support-role-as-env-owner
markusz Sep 4, 2023
1689f4d
Updates README to account for Owner.role(..)
markusz Sep 4, 2023
3914d4c
Adds Integration test
markusz Sep 4, 2023
75243ff
Merge remote-tracking branch 'origin/cloud9-support-role-as-env-owner…
markusz Sep 4, 2023
7848cc3
Splits Owner.role(..) into Owner.assumedRole(..) and Owner.federatedU…
markusz Sep 4, 2023
55ac9cf
Updates unit tests to account for splitting of Owner.role(..) into Ow…
markusz Sep 4, 2023
5adeeaa
Adds integration and CDK synth snapshot
markusz Sep 4, 2023
7e74a08
Updates README.md
markusz Sep 4, 2023
739e5ae
Fixes TS2304 error for assumedRole and federatedUser in README.md
markusz Sep 5, 2023
b1201c9
Merge branch 'main' into cloud9-support-role-as-env-owner
markusz Sep 5, 2023
4f01cba
Merge remote-tracking branch 'aws-cdk/main' into cloud9-support-role-…
markusz Sep 18, 2023
d263718
Cleans up import in unit tests
markusz Oct 6, 2023
7962a83
Cleans up import in integration tests
markusz Oct 6, 2023
8aaa538
Formats ARN regex as inline code
markusz Oct 6, 2023
91d8984
Clarifies required roles for cloud9 owners in README.md
markusz Oct 6, 2023
4ad73cd
Apply suggestions from code review
markusz Oct 17, 2023
170f23f
Removes forced synth in unit test
markusz Oct 17, 2023
598566e
Merge branch 'main' into cloud9-support-role-as-env-owner
vinayak-kukreja Oct 17, 2023
c4589cc
Makes integration test independent of used AWS account by creating us…
markusz Oct 23, 2023
86bcbd7
Adds updated snapshot of synthesized templates from integ.owner.ts
markusz Oct 23, 2023
4a2ec5c
Merge remote-tracking branch 'origin/cloud9-support-role-as-env-owner…
markusz Oct 23, 2023
0b5fdc9
Merge branch 'main' into cloud9-support-role-as-env-owner
vinayak-kukreja Nov 1, 2023
1b61f38
update snapshot
vinayak-kukreja Nov 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 43 additions & 3 deletions packages/@aws-cdk/aws-cloud9-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,16 @@ Every Cloud9 Environment has an **owner**. An owner has full control over the en

By default, the owner will be the identity that creates the Environment, which is most likely your CloudFormation Execution Role when the Environment is created using CloudFormation. Provider a value for the `owner` property to assign a different owner, either a specific IAM User or the AWS Account Root User.

`Owner` is a user that owns a Cloud9 environment . `Owner` has their own access permissions, resources. And we can specify an `Owner`in an Ec2 environment which could be of two types, 1. AccountRoot and 2. Iam User. It allows AWS to determine who has permissions to manage the environment, either an IAM user or the account root user (but using the account root user is not recommended, see [environment sharing best practices](https://docs.aws.amazon.com/cloud9/latest/user-guide/share-environment.html#share-environment-best-practices)).
`Owner` is an IAM entity that owns a Cloud9 environment. `Owner` has their own access permissions, and resources. You can specify an `Owner`in an EC2 environment which could be of the following types:

1. Account Root
2. IAM User
3. IAM Federated User
4. IAM Assumed Role

The ARN of the owner must satisfy the following regular expression: `^arn:(aws|aws-cn|aws-us-gov|aws-iso|aws-iso-b):(iam|sts)::\d+:(root|(user\/[\w+=/:,.@-]{1,64}|federated-user\/[\w+=/:,.@-]{2,32}|assumed-role\/[\w+=:,.@-]{1,64}\/[\w+=,.@-]{1,64}))$`
vinayak-kukreja marked this conversation as resolved.
Show resolved Hide resolved

Note: Using the account root user is not recommended, see [environment sharing best practices](https://docs.aws.amazon.com/cloud9/latest/user-guide/share-environment.html#share-environment-best-practices).

To specify the AWS Account Root User as the environment owner, use `Owner.accountRoot()`

Expand All @@ -114,13 +123,14 @@ declare const vpc: ec2.Vpc;
new cloud9.Ec2Environment(this, 'C9Env', {
vpc,
imageId: cloud9.ImageId.AMAZON_LINUX_2,

owner: cloud9.Owner.accountRoot('111111111')
})
```

To specify a specific IAM User as the environment owner, use `Owner.user()`. The user should have the `AWSCloud9Administrator` managed policy

The user should have the `AWSCloud9User` (preferred) or `AWSCloud9Administrator` managed policy attached.

```ts
import * as iam from 'aws-cdk-lib/aws-iam';

Expand All @@ -135,9 +145,39 @@ new cloud9.Ec2Environment(this, 'C9Env', {
})
```

To specify a specific IAM Federated User as the environment owner, use `Owner.federatedUser(accountId, userName)`.

The user should have the `AWSCloud9User` (preferred) or `AWSCloud9Administrator` managed policy attached.

```ts
import * as iam from 'aws-cdk-lib/aws-iam';

declare const vpc: ec2.Vpc;
new cloud9.Ec2Environment(this, 'C9Env', {
vpc,
imageId: cloud9.ImageId.AMAZON_LINUX_2,
owner: cloud9.Owner.federatedUser(Stack.of(this).account, "Admin/johndoe")
})
```

To specify an IAM Assumed Role as the environment owner, use `Owner.assumedRole(accountId: string, roleName: string)`.

The role should have the `AWSCloud9User` (preferred) or `AWSCloud9Administrator` managed policy attached.

```ts
import * as iam from 'aws-cdk-lib/aws-iam';

declare const vpc: ec2.Vpc;
new cloud9.Ec2Environment(this, 'C9Env', {
vpc,
imageId: cloud9.ImageId.AMAZON_LINUX_2,
owner: cloud9.Owner.assumedRole(Stack.of(this).account, "Admin/johndoe-role")
})
```

## Auto-Hibernation

A Cloud9 environemnt can automatically start and stop the associated EC2 instance to reduce costs.
A Cloud9 environment can automatically start and stop the associated EC2 instance to reduce costs.

Use `automaticStop` to specify the number of minutes until the running instance is shut down after the environment was last used.

Expand Down
20 changes: 20 additions & 0 deletions packages/@aws-cdk/aws-cloud9-alpha/lib/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,26 @@ export class Owner {
return { ownerArn: user.userArn };
}

/**
* Make an IAM assumed role the environment owner
*
* @param accountId The account id of the target account
* @param roleName The name of the assumed role
*/
public static assumedRole(accountId: string, roleName: string): Owner {
vinayak-kukreja marked this conversation as resolved.
Show resolved Hide resolved
vinayak-kukreja marked this conversation as resolved.
Show resolved Hide resolved
return { ownerArn: `arn:${cdk.Aws.PARTITION}:sts::${accountId}:assumed-role/${roleName}` };
}

/**
* Make an IAM federated user the environment owner
*
* @param accountId The AccountId of the target account
* @param userName The name of the federated user
*/
public static federatedUser(accountId: string, userName: string): Owner {
return { ownerArn: `arn:${cdk.Aws.PARTITION}:sts::${accountId}:federated-user/${userName}` };
vinayak-kukreja marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Make the Account Root User the environment owner (not recommended)
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,43 @@ test('environment owner can be an IAM user', () => {
imageId: cloud9.ImageId.AMAZON_LINUX_2,
owner: Owner.user(user),
});

// THEN
const userLogicalId = stack.getLogicalId(user.node.defaultChild as iam.CfnUser);
Template.fromStack(stack).hasResourceProperties('AWS::Cloud9::EnvironmentEC2', {
OwnerArn: {
'Fn::GetAtt': ['User00B015A1', 'Arn'],
'Fn::GetAtt': [userLogicalId, 'Arn'],
},
});
});

test('environment owner can be an IAM Assumed Role', () => {
// WHEN
new cloud9.Ec2Environment(stack, 'C9Env', {
vpc,
imageId: cloud9.ImageId.AMAZON_LINUX_2,
owner: Owner.assumedRole('123456789098', 'Admin'),
});
// THEN

Template.fromStack(stack).hasResourceProperties('AWS::Cloud9::EnvironmentEC2', {
OwnerArn: { 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':sts::123456789098:assumed-role/Admin']] },
});
});

test('environment owner can be an IAM Federated User', () => {
// WHEN
new cloud9.Ec2Environment(stack, 'C9Env', {
vpc,
imageId: cloud9.ImageId.AMAZON_LINUX_2,
owner: Owner.federatedUser('123456789098', 'Admin'),
});
// THEN
Template.fromStack(stack).hasResourceProperties('AWS::Cloud9::EnvironmentEC2', {
OwnerArn: { 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':sts::123456789098:federated-user/Admin']] },
});
});

test('environment owner can be account root', () => {
// WHEN
new cloud9.Ec2Environment(stack, 'C9Env', {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading