-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Create construct for cross account role
Co-Authored-By: Jacob Winch <[email protected]>
- Loading branch information
1 parent
aa5f363
commit 077464a
Showing
3 changed files
with
152 additions
and
0 deletions.
There are no files selected for viewing
51 changes: 51 additions & 0 deletions
51
src/experimental/constructs/iam/roles/__snapshots__/cross-account-role.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`The GuCrossAccountRoleExperimental construct can create a cross account role 1`] = ` | ||
{ | ||
"Metadata": { | ||
"gu:cdk:constructs": [ | ||
"GuStack", | ||
"GuCrossAccountRoleExperimental", | ||
], | ||
"gu:cdk:version": "TEST", | ||
}, | ||
"Resources": { | ||
"testCrossAccountRole975BA7C0": { | ||
"Properties": { | ||
"AssumeRolePolicyDocument": { | ||
"Statement": [ | ||
{ | ||
"Action": "sts:AssumeRole", | ||
"Effect": "Allow", | ||
"Principal": { | ||
"AWS": "arn:aws:iam::1234:role/nameOfRoleInOtherAccountWhichCanAssumeThis-STAGE", | ||
}, | ||
}, | ||
], | ||
"Version": "2012-10-17", | ||
}, | ||
"RoleName": "crossAccountRole", | ||
"Tags": [ | ||
{ | ||
"Key": "gu:cdk:version", | ||
"Value": "TEST", | ||
}, | ||
{ | ||
"Key": "gu:repo", | ||
"Value": "guardian/cdk", | ||
}, | ||
{ | ||
"Key": "Stack", | ||
"Value": "test-stack", | ||
}, | ||
{ | ||
"Key": "Stage", | ||
"Value": "TEST", | ||
}, | ||
], | ||
}, | ||
"Type": "AWS::IAM::Role", | ||
}, | ||
}, | ||
} | ||
`; |
59 changes: 59 additions & 0 deletions
59
src/experimental/constructs/iam/roles/cross-account-role.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { Template } from "aws-cdk-lib/assertions"; | ||
import { ServicePrincipal } from "aws-cdk-lib/aws-iam"; | ||
import { GuRole } from "../../../../constructs/iam"; | ||
import { simpleGuStackForTesting } from "../../../../utils/test"; | ||
import { GuCrossAccountRoleExperimental } from "./cross-account-role"; | ||
|
||
describe("The GuCrossAccountRoleExperimental construct", () => { | ||
it("can create a cross account role", () => { | ||
const stack = simpleGuStackForTesting(); | ||
new GuCrossAccountRoleExperimental(stack, "testCrossAccountRole", { | ||
nameOfRoleWhichCanAssumeThisRole: "nameOfRoleInOtherAccountWhichCanAssumeThis-STAGE", | ||
roleName: "crossAccountRole", | ||
accountId: "1234" | ||
}); | ||
expect(Template.fromStack(stack).toJSON()).toMatchSnapshot(); | ||
}); | ||
|
||
it("can create a cross account role that can be assumed by a service in another account", () => { | ||
const stackThatCreatesTheRole = simpleGuStackForTesting(); | ||
new GuCrossAccountRoleExperimental(stackThatCreatesTheRole, "testCrossAccountRole", { | ||
nameOfRoleWhichCanAssumeThisRole: "nameOfRoleInOtherAccountWhichCanAssumeThisNewlyCreatedOne-CODE", | ||
roleName: "crossAccountRole", | ||
accountId: "1234" | ||
}); | ||
|
||
Template.fromStack(stackThatCreatesTheRole).hasResourceProperties("AWS::IAM::Role", { | ||
RoleName: "crossAccountRole", | ||
AssumeRolePolicyDocument: { | ||
Statement: [{ | ||
Action: "sts:AssumeRole", | ||
Effect: "Allow", | ||
Principal: { | ||
AWS: "arn:aws:iam::1234:role/nameOfRoleInOtherAccountWhichCanAssumeThisNewlyCreatedOne-CODE" | ||
} | ||
}] | ||
} | ||
}) | ||
|
||
const stackThatAssumesTheRole = simpleGuStackForTesting(); | ||
new GuRole(stackThatAssumesTheRole, "idForRole", { | ||
assumedBy: new ServicePrincipal("ec2.amazonaws.com"), | ||
roleName: "nameOfRoleInOtherAccountWhichCanAssumeThisNewlyCreatedOne-CODE" | ||
}); | ||
|
||
Template.fromStack(stackThatAssumesTheRole).hasResourceProperties("AWS::IAM::Role", { | ||
RoleName: "nameOfRoleInOtherAccountWhichCanAssumeThisNewlyCreatedOne-CODE", | ||
AssumeRolePolicyDocument: { | ||
Statement: [{ | ||
Action: "sts:AssumeRole", | ||
Effect: "Allow", | ||
Principal: { | ||
Service: "ec2.amazonaws.com" | ||
} | ||
}] | ||
} | ||
}); | ||
}) | ||
}); | ||
|
42 changes: 42 additions & 0 deletions
42
src/experimental/constructs/iam/roles/cross-account-role.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { ArnPrincipal } from "aws-cdk-lib/aws-iam"; | ||
import type { GuStack } from "../../../../constructs/core"; | ||
import type { GuRoleProps} from "../../../../constructs/iam"; | ||
import {GuRole} from "../../../../constructs/iam"; | ||
|
||
export interface GuCrossAccountRoleExperimentalProps extends Omit<GuRoleProps, "assumedBy"> { | ||
/** | ||
* The name of the role that will assume this new GuCrossAccountRoleExperimental. | ||
* It should be the full name including the stage (if appropriate). | ||
*/ | ||
nameOfRoleWhichCanAssumeThisRole: string; | ||
|
||
/** | ||
* The AWS account ID associated with the resource that will consume this new GuCrossAccountRoleExperimental. | ||
* | ||
* If this construct is being used on a public repo it would be advisable to use | ||
* [private-infrastructure-config](https://github.com/guardian/private-infrastructure-config) so that any account ID | ||
* is not publicly available. | ||
*/ | ||
accountId: string; | ||
} | ||
|
||
/** | ||
* A construct to create a cross account role. | ||
* | ||
* In order to use this construct the name of the role that will assume this cross account role must be provided, along | ||
* with the corresponding AWS account ID of the assuming role. | ||
* | ||
* The resulting role can only be assumed by the specified role in the given AWS account. When this role has been | ||
* created it can be extended to grant permissions for specific actions, allowing a resource in one AWS account to | ||
* perform actions in another. | ||
*/ | ||
export class GuCrossAccountRoleExperimental extends GuRole { | ||
constructor(scope: GuStack, id: string, props: GuCrossAccountRoleExperimentalProps) { | ||
const { nameOfRoleWhichCanAssumeThisRole, accountId } = props; | ||
|
||
super(scope, id, { | ||
assumedBy: new ArnPrincipal(`arn:aws:iam::${accountId}:role/${nameOfRoleWhichCanAssumeThisRole}`), | ||
...props | ||
}); | ||
} | ||
} |