From 742538edb1fd9556e6f93ec7283cfc92c4da2d90 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 24 Nov 2021 18:12:43 +0100 Subject: [PATCH 1/8] feat(iam): enable session tagging To allow session tagging, the `sts:TagSession` permission needs to be added to the role's AssumeRolePolicyDocument. Introduce a new principal which enables this, and add a convenience method `.withSessionTags()` to the `PrincipalBase` class so all built-in principals will have this convenience method by default. To build this, we had to get rid of some cruft and assumptions around policy documents and statements, and defer more power to the `IPrincipal` objects themselves. In order not to break existing implementors, introduce a new interface `IAssumeRolePrincipal` which knows how to add itself to an AssumeRolePolicyDocument and gets complete freedom doing so. That same new interface could be used to lift some old limitations on `CompositePrincipal` so did that as well. Fixes #15908, closes #16725, fixes #2041, fixes #1578. --- packages/@aws-cdk/aws-iam/README.md | 30 +++- packages/@aws-cdk/aws-iam/lib/principals.ts | 148 +++++++++++++----- .../aws-iam/lib/private/assume-role-policy.ts | 25 +++ .../aws-iam/lib/private/policydoc-adapter.ts | 17 ++ packages/@aws-cdk/aws-iam/lib/role.ts | 42 ++--- .../aws-iam/test/policy-document.test.ts | 76 +++++++-- .../@aws-cdk/aws-iam/test/principals.test.ts | 32 ++++ 7 files changed, 288 insertions(+), 82 deletions(-) create mode 100644 packages/@aws-cdk/aws-iam/lib/private/assume-role-policy.ts create mode 100644 packages/@aws-cdk/aws-iam/lib/private/policydoc-adapter.ts diff --git a/packages/@aws-cdk/aws-iam/README.md b/packages/@aws-cdk/aws-iam/README.md index a81b25d53e6ba..5cb6a1f076371 100644 --- a/packages/@aws-cdk/aws-iam/README.md +++ b/packages/@aws-cdk/aws-iam/README.md @@ -155,7 +155,7 @@ To add a principal to a policy statement you can either use the abstract * `addServicePrincipal` or `new ServicePrincipal(service)` for `{ "Service": service }` * `addAccountRootPrincipal` or `new AccountRootPrincipal()` for `{ "AWS": { "Ref: "AWS::AccountId" } }` * `addCanonicalUserPrincipal` or `new CanonicalUserPrincipal(id)` for `{ "CanonicalUser": id }` -* `addFederatedPrincipal` or `new FederatedPrincipal(federated, conditions, assumeAction)` for +* `addFederatedPrincipal` or `new FederatedPrincipal(federated, conditions, [assumeAction], [sessionTags])` for `{ "Federated": arn }` and a set of optional conditions and the assume role action to use. * `addAnyPrincipal` or `new AnyPrincipal` for `{ "AWS": "*" }` @@ -209,13 +209,31 @@ The `WebIdentityPrincipal` class can be used as a principal for web identities l Cognito, Amazon, Google or Facebook, for example: ```ts -const principal = new iam.WebIdentityPrincipal('cognito-identity.amazonaws.com') - .withConditions({ - "StringEquals": { "cognito-identity.amazonaws.com:aud": "us-east-2:12345678-abcd-abcd-abcd-123456" }, - "ForAnyValue:StringLike": {"cognito-identity.amazonaws.com:amr": "unauthenticated" }, - }); +const principal = new iam.WebIdentityPrincipal('cognito-identity.amazonaws.com', { + 'StringEquals': { 'cognito-identity.amazonaws.com:aud': 'us-east-2:12345678-abcd-abcd-abcd-123456' }, + 'ForAnyValue:StringLike': {'cognito-identity.amazonaws.com:amr': 'unauthenticated' }, +}); ``` +If your identity provider is configured to assume a Role with [session +tags](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html), you +need to call `.withSessionTags()` to add the required permissions to the Role's +policy document: + +```ts +new iam.Role(this, 'Role', { + assumedBy: new iam.WebIdentityPrincipal('cognito-identity.amazonaws.com', { + 'StringEquals': { + 'cognito-identity.amazonaws.com:aud': 'us-east-2:12345678-abcd-abcd-abcd-123456', + }, + 'ForAnyValue:StringLike': { + 'cognito-identity.amazonaws.com:amr': 'unauthenticated', + }, + }).withSessionTags(), +}); +``` + + ## Parsing JSON Policy Documents The `PolicyDocument.fromJson` and `PolicyStatement.fromJson` static methods can be used to parse JSON objects. For example: diff --git a/packages/@aws-cdk/aws-iam/lib/principals.ts b/packages/@aws-cdk/aws-iam/lib/principals.ts index 001792cbcc475..d211916d07c11 100644 --- a/packages/@aws-cdk/aws-iam/lib/principals.ts +++ b/packages/@aws-cdk/aws-iam/lib/principals.ts @@ -1,7 +1,9 @@ import * as cdk from '@aws-cdk/core'; import { Default, RegionInfo } from '@aws-cdk/region-info'; import { IOpenIdConnectProvider } from './oidc-provider'; +import { PolicyDocument } from './policy-document'; import { Condition, Conditions, PolicyStatement } from './policy-statement'; +import { defaultAddPrincipalToAssumeRole } from './private/assume-role-policy'; import { ISamlProvider } from './saml-provider'; import { LITERAL_STRING_KEY, mergePrincipal } from './util'; @@ -68,6 +70,25 @@ export interface IPrincipal extends IGrantable { addToPrincipalPolicy(statement: PolicyStatement): AddToPrincipalPolicyResult; } +/** + * A type of principal that has more control over its own representation in AssumeRolePolicyDocuments + * + * More complex types of identity providers need more control over Role's policy documents + * than simply `{ Effect: 'Allow', Action: 'AssumeRole', Principal: }`. + * + * If that control is necessary, they can implement `IAssumeRolePrincipal` to get full + * access to a Role's AssumeRolePolicyDocument. + */ +export interface IAssumeRolePrincipal extends IPrincipal { + /** + * Add the princpial to the AssumeRolePolicyDocument + * + * Add the statements to the AssumeRolePolicyDocument necessary to give this principal + * permissions to assume the given role. + */ + addToAssumeRolePolicy(document: PolicyDocument): void; +} + /** * Result of calling `addToPrincipalPolicy` */ @@ -89,7 +110,7 @@ export interface AddToPrincipalPolicyResult { /** * Base class for policy principals */ -export abstract class PrincipalBase implements IPrincipal { +export abstract class PrincipalBase implements IAssumeRolePrincipal { public readonly grantPrincipal: IPrincipal = this; public readonly principalAccount: string | undefined = undefined; @@ -113,6 +134,14 @@ export abstract class PrincipalBase implements IPrincipal { return { statementAdded: false }; } + public addToAssumeRolePolicy(document: PolicyDocument): void { + // Default implementation of this protocol, compatible with the legacy behavior + document.addStatements(new PolicyStatement({ + actions: [this.assumeRoleAction], + principals: [this], + })); + } + public toString() { // This is a first pass to make the object readable. Descendant principals // should return something nicer. @@ -138,9 +167,39 @@ export abstract class PrincipalBase implements IPrincipal { * * @returns a new PrincipalWithConditions object. */ - public withConditions(conditions: Conditions): IPrincipal { + public withConditions(conditions: Conditions): PrincipalBase { return new PrincipalWithConditions(this, conditions); } + + /** + * Returns a new principal using this principal as the base, with session tags enabled. + * + * @returns a new SessionTagsPrincipal object. + */ + public withSessionTags(): PrincipalBase { + return new SessionTagsPrincipal(this); + } +} + +/** + * Base class for Principals that wrap other principals + */ +class PrincipalAdapter extends PrincipalBase { + public readonly assumeRoleAction = this.wrapped.assumeRoleAction; + public readonly principalAccount = this.wrapped.principalAccount; + + constructor(protected readonly wrapped: IPrincipal) { + super(); + } + + public get policyFragment(): PrincipalPolicyFragment { return this.wrapped.policyFragment; } + + addToPolicy(statement: PolicyStatement): boolean { + return this.wrapped.addToPolicy(statement); + } + addToPrincipalPolicy(statement: PolicyStatement): AddToPrincipalPolicyResult { + return this.wrapped.addToPrincipalPolicy(statement); + } } /** @@ -149,15 +208,11 @@ export abstract class PrincipalBase implements IPrincipal { * For more information about conditions, see: * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html */ -export class PrincipalWithConditions implements IPrincipal { - public readonly grantPrincipal: IPrincipal = this; - public readonly assumeRoleAction: string = this.principal.assumeRoleAction; +export class PrincipalWithConditions extends PrincipalAdapter { private additionalConditions: Conditions; - constructor( - private readonly principal: IPrincipal, - conditions: Conditions, - ) { + constructor(principal: IPrincipal, conditions: Conditions) { + super(principal); this.additionalConditions = conditions; } @@ -186,27 +241,15 @@ export class PrincipalWithConditions implements IPrincipal { * See [the IAM documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html). */ public get conditions() { - return this.mergeConditions(this.principal.policyFragment.conditions, this.additionalConditions); + return this.mergeConditions(this.wrapped.policyFragment.conditions, this.additionalConditions); } public get policyFragment(): PrincipalPolicyFragment { - return new PrincipalPolicyFragment(this.principal.policyFragment.principalJson, this.conditions); - } - - public get principalAccount(): string | undefined { - return this.principal.principalAccount; - } - - public addToPolicy(statement: PolicyStatement): boolean { - return this.addToPrincipalPolicy(statement).statementAdded; - } - - public addToPrincipalPolicy(statement: PolicyStatement): AddToPrincipalPolicyResult { - return this.principal.addToPrincipalPolicy(statement); + return new PrincipalPolicyFragment(this.wrapped.policyFragment.principalJson, this.conditions); } public toString() { - return this.principal.toString(); + return this.wrapped.toString(); } /** @@ -247,6 +290,30 @@ export class PrincipalWithConditions implements IPrincipal { } } +/** + * Enables session tags on role assumptions from a principal + * + * For more information on session tags, see: + * https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html + */ +export class SessionTagsPrincipal extends PrincipalAdapter { + constructor(principal: IPrincipal) { + super(principal); + } + + public addToAssumeRolePolicy(doc: PolicyDocument) { + // Lazy import to avoid circular import dependencies during startup + + // eslint-disable-next-line @typescript-eslint/no-require-imports + const adapter: typeof import('./private/policydoc-adapter') = require('./private/policydoc-adapter'); + + defaultAddPrincipalToAssumeRole(this.wrapped, new adapter.MutatingPolicyDocumentAdapter(doc, (statement) => { + statement.addActions('sts:TagSession'); + return statement; + })); + } +} + /** * A collection of the fields in a PolicyStatement that can be used to identify a principal. * @@ -440,6 +507,7 @@ export class FederatedPrincipal extends PrincipalBase { * @param federated federated identity provider (i.e. 'cognito-identity.amazonaws.com' for users authenticated through Cognito) * @param conditions The conditions under which the policy is in effect. * See [the IAM documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html). + * @param sessionTags Whether to enable session tagging (see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html) */ constructor( public readonly federated: string, @@ -470,6 +538,7 @@ export class WebIdentityPrincipal extends FederatedPrincipal { * @param identityProvider identity provider (i.e. 'cognito-identity.amazonaws.com' for users authenticated through Cognito) * @param conditions The conditions under which the policy is in effect. * See [the IAM documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html). + * @param sessionTags Whether to enable session tagging (see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html) */ constructor(identityProvider: string, conditions: Conditions = {}) { super(identityProvider, conditions ?? {}, 'sts:AssumeRoleWithWebIdentity'); @@ -605,9 +674,9 @@ export class StarPrincipal extends PrincipalBase { */ export class CompositePrincipal extends PrincipalBase { public readonly assumeRoleAction: string; - private readonly principals = new Array(); + private readonly principals = new Array(); - constructor(...principals: PrincipalBase[]) { + constructor(...principals: IPrincipal[]) { super(); if (principals.length === 0) { throw new Error('CompositePrincipals must be constructed with at least 1 Principal but none were passed.'); @@ -622,28 +691,29 @@ export class CompositePrincipal extends PrincipalBase { * * @param principals IAM principals that will be added to the composite principal */ - public addPrincipals(...principals: PrincipalBase[]): this { - for (const p of principals) { - if (p.assumeRoleAction !== this.assumeRoleAction) { - throw new Error( - 'Cannot add multiple principals with different "assumeRoleAction". ' + - `Expecting "${this.assumeRoleAction}", got "${p.assumeRoleAction}"`); - } + public addPrincipals(...principals: IPrincipal[]): this { + this.principals.push(...principals); + return this; + } + + public addToAssumeRolePolicy(doc: PolicyDocument) { + for (const p of this.principals) { + defaultAddPrincipalToAssumeRole(p, doc); + } + } + public get policyFragment(): PrincipalPolicyFragment { + // We only have a problem with conditions if we are trying to render composite + // princpals into a single statement (which is when `policyFragment` would get called) + for (const p of this.principals) { const fragment = p.policyFragment; if (fragment.conditions && Object.keys(fragment.conditions).length > 0) { throw new Error( 'Components of a CompositePrincipal must not have conditions. ' + `Tried to add the following fragment: ${JSON.stringify(fragment)}`); } - - this.principals.push(p); } - return this; - } - - public get policyFragment(): PrincipalPolicyFragment { const principalJson: { [key: string]: string[] } = {}; for (const p of this.principals) { diff --git a/packages/@aws-cdk/aws-iam/lib/private/assume-role-policy.ts b/packages/@aws-cdk/aws-iam/lib/private/assume-role-policy.ts new file mode 100644 index 0000000000000..9a2a474fcb2d4 --- /dev/null +++ b/packages/@aws-cdk/aws-iam/lib/private/assume-role-policy.ts @@ -0,0 +1,25 @@ +import { PolicyDocument } from '../policy-document'; +import { PolicyStatement } from '../policy-statement'; +import { IPrincipal, IAssumeRolePrincipal } from '../principals'; + +/** + * Add a principal to an AssumeRolePolicyDocument in the right way + * + * Delegate to the principal if it can do the job itself, do a default job if it can't. + */ +export function defaultAddPrincipalToAssumeRole(principal: IPrincipal, doc: PolicyDocument) { + if (isAssumeRolePrincipal(principal)) { + // Principal knows how to add itself + principal.addToAssumeRolePolicy(doc); + } else { + // Principal can't add itself, we do it for them + doc.addStatements(new PolicyStatement({ + actions: [principal.assumeRoleAction], + principals: [principal], + })); + } +} + +function isAssumeRolePrincipal(principal: IPrincipal): principal is IAssumeRolePrincipal { + return !!(principal as IAssumeRolePrincipal).addToAssumeRolePolicy; +} diff --git a/packages/@aws-cdk/aws-iam/lib/private/policydoc-adapter.ts b/packages/@aws-cdk/aws-iam/lib/private/policydoc-adapter.ts new file mode 100644 index 0000000000000..c6f95631ea495 --- /dev/null +++ b/packages/@aws-cdk/aws-iam/lib/private/policydoc-adapter.ts @@ -0,0 +1,17 @@ +import { PolicyDocument } from '../policy-document'; +import { PolicyStatement } from '../policy-statement'; + +/** + * A PolicyDocument adapter that can modify statements flowing through it + */ +export class MutatingPolicyDocumentAdapter extends PolicyDocument { + constructor(private readonly wrapped: PolicyDocument, private readonly mutator: (s: PolicyStatement) => PolicyStatement) { + super(); + } + + public addStatements(...statements: PolicyStatement[]): void { + for (const st of statements) { + this.wrapped.addStatements(this.mutator(st)); + } + } +} diff --git a/packages/@aws-cdk/aws-iam/lib/role.ts b/packages/@aws-cdk/aws-iam/lib/role.ts index b103b21231e23..ac48fdd3d7710 100644 --- a/packages/@aws-cdk/aws-iam/lib/role.ts +++ b/packages/@aws-cdk/aws-iam/lib/role.ts @@ -8,7 +8,9 @@ import { Policy } from './policy'; import { PolicyDocument } from './policy-document'; import { PolicyStatement } from './policy-statement'; import { AddToPrincipalPolicyResult, ArnPrincipal, IPrincipal, PrincipalPolicyFragment } from './principals'; +import { defaultAddPrincipalToAssumeRole } from './private/assume-role-policy'; import { ImmutableRole } from './private/immutable-role'; +import { MutatingPolicyDocumentAdapter } from './private/policydoc-adapter'; import { AttachedPolicies, UniqueStringSet } from './util'; /** @@ -484,17 +486,21 @@ export interface IRole extends IIdentity { } function createAssumeRolePolicy(principal: IPrincipal, externalIds: string[]) { - const statement = new AwsStarStatement(); - statement.addPrincipals(principal); - statement.addActions(principal.assumeRoleAction); + const actualDoc = new PolicyDocument(); + + // If requested, add externalIds to every statement added to this doc + const addDoc = externalIds.length === 0 + ? actualDoc + : new MutatingPolicyDocumentAdapter(actualDoc, (statement) => { + statement.addCondition('StringEquals', { + 'sts:ExternalId': externalIds.length === 1 ? externalIds[0] : externalIds, + }); + return statement; + }); - if (externalIds.length) { - statement.addCondition('StringEquals', { 'sts:ExternalId': externalIds.length === 1 ? externalIds[0] : externalIds }); - } + defaultAddPrincipalToAssumeRole(principal, addDoc); - const doc = new PolicyDocument(); - doc.addStatements(statement); - return doc; + return actualDoc; } function validateMaxSessionDuration(duration?: number) { @@ -507,24 +513,6 @@ function validateMaxSessionDuration(duration?: number) { } } -/** - * A PolicyStatement that normalizes its Principal field differently - * - * Normally, "anyone" is normalized to "Principal: *", but this statement - * normalizes to "Principal: { AWS: * }". - */ -class AwsStarStatement extends PolicyStatement { - public toStatementJson(): any { - const stat = super.toStatementJson(); - - if (stat.Principal === '*') { - stat.Principal = { AWS: '*' }; - } - - return stat; - } -} - /** * Options for the `withoutPolicyUpdates()` modifier of a Role */ diff --git a/packages/@aws-cdk/aws-iam/test/policy-document.test.ts b/packages/@aws-cdk/aws-iam/test/policy-document.test.ts index bf93e31901c6c..8815bd3b3e4ba 100644 --- a/packages/@aws-cdk/aws-iam/test/policy-document.test.ts +++ b/packages/@aws-cdk/aws-iam/test/policy-document.test.ts @@ -2,7 +2,7 @@ import '@aws-cdk/assert-internal/jest'; import { Lazy, Stack, Token } from '@aws-cdk/core'; import { AccountPrincipal, Anyone, AnyPrincipal, ArnPrincipal, CanonicalUserPrincipal, CompositePrincipal, - Effect, FederatedPrincipal, IPrincipal, PolicyDocument, PolicyStatement, PrincipalPolicyFragment, ServicePrincipal, + Effect, FederatedPrincipal, IPrincipal, PolicyDocument, PolicyStatement, PrincipalPolicyFragment, ServicePrincipal, Role, } from '../lib'; describe('IAM policy document', () => { @@ -481,10 +481,46 @@ describe('IAM policy document', () => { expect(stack.resolve(statement.toStatementJson())).toEqual({ Effect: 'Allow', Principal: { AWS: 'i:am:an:arn' } }); }); - test('conditions are not allowed on individual principals of a composite', () => { - const p = new CompositePrincipal(new ArnPrincipal('i:am')); - expect(() => p.addPrincipals(new FederatedPrincipal('federated', { StringEquals: { 'aws:some-key': 'some-value' } }))) - .toThrow(/Components of a CompositePrincipal must not have conditions/); + test('conditions are allowed in an assumerolepolicydocument', () => { + const stack = new Stack(); + new Role(stack, 'Role', { + assumedBy: new CompositePrincipal( + new ArnPrincipal('i:am'), + new FederatedPrincipal('federated', { StringEquals: { 'aws:some-key': 'some-value' } }), + ), + }); + + expect(stack).toHaveResourceLike('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { AWS: 'i:am' }, + }, + { + Action: 'sts:AssumeRole', + Condition: { + StringEquals: { 'aws:some-key': 'some-value' }, + }, + Effect: 'Allow', + Principal: { Federated: 'federated' }, + }, + ], + }, + }); + }); + + test('conditions are not allowed when used in a single statement', () => { + + expect(() => { + new PolicyStatement({ + actions: ['s3:test'], + principals: [new CompositePrincipal( + new ArnPrincipal('i:am'), + new FederatedPrincipal('federated', { StringEquals: { 'aws:some-key': 'some-value' } }))], + }); + }).toThrow(/Components of a CompositePrincipal must not have conditions/); }); test('principals and conditions are a big nice merge', () => { @@ -519,13 +555,33 @@ describe('IAM policy document', () => { }); }); - test('cannot mix types of assumeRoleAction in a single composite', () => { - // GIVEN - const p = new CompositePrincipal(new ArnPrincipal('arn')); // assumeRoleAction is "sts:AssumeRule" + test('can mix types of assumeRoleAction in a single composite', () => { + const stack = new Stack(); + + // WHEN + new Role(stack, 'Role', { + assumedBy: new CompositePrincipal( + new ArnPrincipal('arn'), + new FederatedPrincipal('fed', {}, 'sts:Boom')), + }); // THEN - expect(() => p.addPrincipals(new FederatedPrincipal('fed', {}, 'sts:Boom'))) - .toThrow(/Cannot add multiple principals with different "assumeRoleAction". Expecting "sts:AssumeRole", got "sts:Boom"/); + expect(stack).toHaveResourceLike('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { AWS: 'arn' }, + }, + { + Action: 'sts:Boom', + Effect: 'Allow', + Principal: { Federated: 'fed' }, + }, + ], + }, + }); }); }); diff --git a/packages/@aws-cdk/aws-iam/test/principals.test.ts b/packages/@aws-cdk/aws-iam/test/principals.test.ts index 1bf7d47950875..c19d7ccd6d719 100644 --- a/packages/@aws-cdk/aws-iam/test/principals.test.ts +++ b/packages/@aws-cdk/aws-iam/test/principals.test.ts @@ -243,4 +243,36 @@ test('PrincipalWithConditions inherits principalAccount from AccountPrincipal ', // THEN expect(accountPrincipal.principalAccount).toStrictEqual('123456789012'); expect(principalWithConditions.principalAccount).toStrictEqual('123456789012'); +}); + +test('Can enable session tags', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new iam.Role(stack, 'Role', { + assumedBy: new iam.WebIdentityPrincipal( + 'cognito-identity.amazonaws.com', + { + 'StringEquals': { 'cognito-identity.amazonaws.com:aud': 'asdf' }, + 'ForAnyValue:StringLike': { 'cognito-identity.amazonaws.com:amr': 'authenticated' }, + }).withSessionTags(), + }); + + // THEN + expect(stack).toHaveResourceLike('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: ['sts:AssumeRoleWithWebIdentity', 'sts:TagSession'], + Condition: { + 'StringEquals': { 'cognito-identity.amazonaws.com:aud': 'asdf' }, + 'ForAnyValue:StringLike': { 'cognito-identity.amazonaws.com:amr': 'authenticated' }, + }, + Effect: 'Allow', + Principal: { Federated: 'cognito-identity.amazonaws.com' }, + }, + ], + }, + }); }); \ No newline at end of file From 79e12907a38029713d8583a2dd9c81281d41ad2b Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 24 Nov 2021 18:19:40 +0100 Subject: [PATCH 2/8] Update README.md --- packages/@aws-cdk/aws-iam/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-iam/README.md b/packages/@aws-cdk/aws-iam/README.md index 5cb6a1f076371..fe5ae926f1a1f 100644 --- a/packages/@aws-cdk/aws-iam/README.md +++ b/packages/@aws-cdk/aws-iam/README.md @@ -155,7 +155,7 @@ To add a principal to a policy statement you can either use the abstract * `addServicePrincipal` or `new ServicePrincipal(service)` for `{ "Service": service }` * `addAccountRootPrincipal` or `new AccountRootPrincipal()` for `{ "AWS": { "Ref: "AWS::AccountId" } }` * `addCanonicalUserPrincipal` or `new CanonicalUserPrincipal(id)` for `{ "CanonicalUser": id }` -* `addFederatedPrincipal` or `new FederatedPrincipal(federated, conditions, [assumeAction], [sessionTags])` for +* `addFederatedPrincipal` or `new FederatedPrincipal(federated, conditions, assumeAction)` for `{ "Federated": arn }` and a set of optional conditions and the assume role action to use. * `addAnyPrincipal` or `new AnyPrincipal` for `{ "AWS": "*" }` From 1837d346143f5ee6de4257f2462662e1f507bde9 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 25 Nov 2021 10:29:26 +0100 Subject: [PATCH 3/8] Fix test --- packages/@aws-cdk/aws-iam/test/role.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/@aws-cdk/aws-iam/test/role.test.ts b/packages/@aws-cdk/aws-iam/test/role.test.ts index f251f8388a6d2..ffa1ccd305c58 100644 --- a/packages/@aws-cdk/aws-iam/test/role.test.ts +++ b/packages/@aws-cdk/aws-iam/test/role.test.ts @@ -309,6 +309,12 @@ describe('IAM role', () => { Effect: 'Allow', Principal: { Service: 'boom.amazonaws.test', + }, + }, + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { AWS: '1111111', }, }, From ab3cc68190347867113728ce434280a73fe0c8aa Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 25 Nov 2021 11:18:18 +0100 Subject: [PATCH 4/8] Update snapshot --- .../aws-iam/test/integ.composite-principal.expected.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-iam/test/integ.composite-principal.expected.json b/packages/@aws-cdk/aws-iam/test/integ.composite-principal.expected.json index a715e411d83ae..4090b7be4e15e 100644 --- a/packages/@aws-cdk/aws-iam/test/integ.composite-principal.expected.json +++ b/packages/@aws-cdk/aws-iam/test/integ.composite-principal.expected.json @@ -19,7 +19,13 @@ } ] ] - }, + } + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { "AWS": "*" } } From 251f5b913f9a2adf613d98a0340af26e729a7d5a Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 25 Nov 2021 13:23:45 +0100 Subject: [PATCH 5/8] Fix type checks in AWS Lambda --- packages/@aws-cdk/aws-lambda/lib/function-base.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda/lib/function-base.ts b/packages/@aws-cdk/aws-lambda/lib/function-base.ts index 8a28f2e423657..a370b910fdfde 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function-base.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function-base.ts @@ -238,6 +238,8 @@ export abstract class FunctionBase extends Resource implements IFunction, ec2.IC return; } + // eslint-disable-next-line no-console + console.log(permission); const principal = this.parsePermissionPrincipal(permission.principal); const { sourceAccount, sourceArn } = this.parseConditions(permission.principal) ?? {}; const action = permission.action ?? 'lambda:InvokeFunction'; @@ -400,9 +402,9 @@ export abstract class FunctionBase extends Resource implements IFunction, ec2.IC // Try some specific common classes first. // use duck-typing, not instance of // @deprecated: after v2, we can change these to 'instanceof' - if ('conditions' in principal) { + if ('wrapped' in principal) { // eslint-disable-next-line dot-notation - principal = principal['principal']; + principal = principal['wrapped']; } if ('accountId' in principal) { From 807e751ae3849cc8f0ae4bbf404291b6982f8fb5 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 25 Nov 2021 14:23:05 +0100 Subject: [PATCH 6/8] Update snapshot --- .../test/fargate/integ.executionrole.expected.json | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.executionrole.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.executionrole.expected.json index 6d2654abe539c..dc83169a668a9 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.executionrole.expected.json +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.executionrole.expected.json @@ -367,10 +367,14 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": [ - "ecs.amazonaws.com", - "ecs-tasks.amazonaws.com" - ] + "Service": "ecs.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" } } ], From 9217aecdbe2ae1f8c68da2ddd214e436ec17e58c Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 25 Nov 2021 15:17:46 +0100 Subject: [PATCH 7/8] CDK Pipelines --- .../pipelines/test/compliance/assets.test.ts | 56 ++++++++++++------- .../integ.newpipeline-with-vpc.expected.json | 8 ++- ...ne-with-assets-single-upload.expected.json | 8 ++- .../integ.pipeline-with-assets.expected.json | 8 ++- 4 files changed, 57 insertions(+), 23 deletions(-) diff --git a/packages/@aws-cdk/pipelines/test/compliance/assets.test.ts b/packages/@aws-cdk/pipelines/test/compliance/assets.test.ts index 68b10d259683f..d78c7073dd4f3 100644 --- a/packages/@aws-cdk/pipelines/test/compliance/assets.test.ts +++ b/packages/@aws-cdk/pipelines/test/compliance/assets.test.ts @@ -387,18 +387,26 @@ describe('basic pipeline', () => { function THEN_codePipelineExpectation() { Template.fromStack(pipelineStack).hasResourceProperties('AWS::IAM::Role', { AssumeRolePolicyDocument: { - Statement: [{ - Action: 'sts:AssumeRole', - Effect: 'Allow', - Principal: { - Service: 'codebuild.amazonaws.com', - AWS: { - 'Fn::Join': ['', [ - 'arn:', { Ref: 'AWS::Partition' }, `:iam::${PIPELINE_ENV.account}:root`, - ]], + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'codebuild.amazonaws.com', }, }, - }], + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + AWS: { + 'Fn::Join': ['', [ + 'arn:', { Ref: 'AWS::Partition' }, `:iam::${PIPELINE_ENV.account}:root`, + ]], + }, + }, + }, + ], }, }); Template.fromStack(pipelineStack).hasResourceProperties('AWS::IAM::Policy', @@ -493,18 +501,26 @@ describe('basic pipeline', () => { function THEN_codePipelineExpectation() { Template.fromStack(pipelineStack).hasResourceProperties('AWS::IAM::Role', { AssumeRolePolicyDocument: { - Statement: [{ - Action: 'sts:AssumeRole', - Effect: 'Allow', - Principal: { - Service: 'codebuild.amazonaws.com', - AWS: { - 'Fn::Join': ['', [ - 'arn:', { Ref: 'AWS::Partition' }, `:iam::${PIPELINE_ENV.account}:root`, - ]], + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'codebuild.amazonaws.com', }, }, - }], + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + AWS: { + 'Fn::Join': ['', [ + 'arn:', { Ref: 'AWS::Partition' }, `:iam::${PIPELINE_ENV.account}:root`, + ]], + }, + }, + }, + ], }, }); Template.fromStack(pipelineStack).hasResourceProperties('AWS::IAM::Policy', diff --git a/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json b/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json index 80a17d7243cb1..b10333fdc0ca9 100644 --- a/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json @@ -1970,7 +1970,13 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": "codebuild.amazonaws.com", + "Service": "codebuild.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { "AWS": { "Fn::Join": [ "", diff --git a/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets-single-upload.expected.json b/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets-single-upload.expected.json index 85f20ecf8995f..d5143a1b24ecf 100644 --- a/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets-single-upload.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets-single-upload.expected.json @@ -1344,7 +1344,13 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": "codebuild.amazonaws.com", + "Service": "codebuild.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { "AWS": { "Fn::Join": [ "", diff --git a/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets.expected.json b/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets.expected.json index e236dbdb569ac..545dc0f39651e 100644 --- a/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets.expected.json @@ -1370,7 +1370,13 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": "codebuild.amazonaws.com", + "Service": "codebuild.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { "AWS": { "Fn::Join": [ "", From 88c56c657e772fa91290f0237c06293cd7059e60 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 16 Dec 2021 10:40:01 +0100 Subject: [PATCH 8/8] Update snapshots --- ...nteg.job-submission-workflow.expected.json | 70 ++++++++------- .../integ.start-job-run.expected.json | 88 ++++++++++--------- 2 files changed, 83 insertions(+), 75 deletions(-) diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.job-submission-workflow.expected.json b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.job-submission-workflow.expected.json index a3b99bf3fb6ed..ec1551086d626 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.job-submission-workflow.expected.json +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.job-submission-workflow.expected.json @@ -1127,7 +1127,7 @@ }, "/", { - "Ref": "AssetParameters8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945S3BucketC636D050" + "Ref": "AssetParameters5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81S3BucketD82D4551" }, "/", { @@ -1137,7 +1137,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945S3VersionKey40C5ADFE" + "Ref": "AssetParameters5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81S3VersionKey897D64BB" } ] } @@ -1150,7 +1150,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945S3VersionKey40C5ADFE" + "Ref": "AssetParameters5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81S3VersionKey897D64BB" } ] } @@ -1172,11 +1172,11 @@ "Arn" ] }, - "referencetoawsstepfunctionstasksemrcontainersallservicesintegAssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3Bucket42FF7F94Ref": { - "Ref": "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3Bucket3B443230" + "referencetoawsstepfunctionstasksemrcontainersallservicesintegAssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3Bucket1AC4E28ARef": { + "Ref": "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3Bucket9AE1EC0F" }, - "referencetoawsstepfunctionstasksemrcontainersallservicesintegAssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3VersionKeyD44C8135Ref": { - "Ref": "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3VersionKeyAA4674FB" + "referencetoawsstepfunctionstasksemrcontainersallservicesintegAssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3VersionKeyEFDBE51DRef": { + "Ref": "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3VersionKey451EAA56" }, "referencetoawsstepfunctionstasksemrcontainersallservicesintegAssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3Bucket5978B8B5Ref": { "Ref": "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1" @@ -1304,21 +1304,25 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": [ - "emr-containers.amazonaws.com", - { - "Fn::Join": [ - "", - [ - "states.", - { - "Ref": "AWS::Region" - }, - ".amazonaws.com" - ] + "Service": "emr-containers.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "states.", + { + "Ref": "AWS::Region" + }, + ".amazonaws.com" ] - } - ] + ] + } } } ], @@ -1721,17 +1725,17 @@ "Type": "String", "Description": "Artifact hash for asset \"26ac61b4195cccf80ff73f332788ad7ffaab36d81ce570340a583a8364901665\"" }, - "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3Bucket3B443230": { + "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3Bucket9AE1EC0F": { "Type": "String", - "Description": "S3 bucket for asset \"5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720\"" + "Description": "S3 bucket for asset \"00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5af\"" }, - "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3VersionKeyAA4674FB": { + "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3VersionKey451EAA56": { "Type": "String", - "Description": "S3 key for asset version \"5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720\"" + "Description": "S3 key for asset version \"00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5af\"" }, - "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720ArtifactHash3D7A279D": { + "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afArtifactHash761F4689": { "Type": "String", - "Description": "Artifact hash for asset \"5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720\"" + "Description": "Artifact hash for asset \"00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5af\"" }, "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1": { "Type": "String", @@ -1781,17 +1785,17 @@ "Type": "String", "Description": "Artifact hash for asset \"ea17febe6d04c66048f3e8e060c71685c0cb53122abceff44842d27bc0d4a03e\"" }, - "AssetParameters8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945S3BucketC636D050": { + "AssetParameters5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81S3BucketD82D4551": { "Type": "String", - "Description": "S3 bucket for asset \"8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945\"" + "Description": "S3 bucket for asset \"5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81\"" }, - "AssetParameters8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945S3VersionKey40C5ADFE": { + "AssetParameters5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81S3VersionKey897D64BB": { "Type": "String", - "Description": "S3 key for asset version \"8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945\"" + "Description": "S3 key for asset version \"5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81\"" }, - "AssetParameters8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945ArtifactHash89120E1C": { + "AssetParameters5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81ArtifactHash8B07F4C4": { "Type": "String", - "Description": "Artifact hash for asset \"8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945\"" + "Description": "Artifact hash for asset \"5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81\"" }, "AssetParameters249207c004483eea61658aceb796afc5f7a8b39d3b2333951c04ac8787af6d50S3BucketDBE4A868": { "Type": "String", diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.start-job-run.expected.json b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.start-job-run.expected.json index 3ec75b7ba0384..1cd5ed999f0b5 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.start-job-run.expected.json +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.start-job-run.expected.json @@ -1186,7 +1186,7 @@ }, "/", { - "Ref": "AssetParameters3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591S3BucketC38C4355" + "Ref": "AssetParameters8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35S3Bucket37C1382F" }, "/", { @@ -1196,7 +1196,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591S3VersionKey31FFCA42" + "Ref": "AssetParameters8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35S3VersionKey5D044A85" } ] } @@ -1209,7 +1209,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591S3VersionKey31FFCA42" + "Ref": "AssetParameters8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35S3VersionKey5D044A85" } ] } @@ -1231,11 +1231,11 @@ "Arn" ] }, - "referencetoawsstepfunctionstasksemrcontainersstartjobrunintegtestAssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3Bucket7AE1E7DBRef": { - "Ref": "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3Bucket3B443230" + "referencetoawsstepfunctionstasksemrcontainersstartjobrunintegtestAssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3Bucket90E6B403Ref": { + "Ref": "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3Bucket9AE1EC0F" }, - "referencetoawsstepfunctionstasksemrcontainersstartjobrunintegtestAssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3VersionKey5842C10ARef": { - "Ref": "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3VersionKeyAA4674FB" + "referencetoawsstepfunctionstasksemrcontainersstartjobrunintegtestAssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3VersionKeyAD902FD9Ref": { + "Ref": "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3VersionKey451EAA56" }, "referencetoawsstepfunctionstasksemrcontainersstartjobrunintegtestAssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3Bucket977A6FD0Ref": { "Ref": "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1" @@ -1384,21 +1384,25 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": [ - "emr-containers.amazonaws.com", - { - "Fn::Join": [ - "", - [ - "states.", - { - "Ref": "AWS::Region" - }, - ".amazonaws.com" - ] + "Service": "emr-containers.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "states.", + { + "Ref": "AWS::Region" + }, + ".amazonaws.com" ] - } - ] + ] + } } } ], @@ -1712,7 +1716,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E" + "Ref": "AssetParameters3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87S3Bucket36F31A16" }, "S3Key": { "Fn::Join": [ @@ -1725,7 +1729,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" + "Ref": "AssetParameters3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87S3VersionKeyF80D542B" } ] } @@ -1738,7 +1742,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" + "Ref": "AssetParameters3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87S3VersionKeyF80D542B" } ] } @@ -2142,17 +2146,17 @@ "Type": "String", "Description": "Artifact hash for asset \"26ac61b4195cccf80ff73f332788ad7ffaab36d81ce570340a583a8364901665\"" }, - "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3Bucket3B443230": { + "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3Bucket9AE1EC0F": { "Type": "String", - "Description": "S3 bucket for asset \"5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720\"" + "Description": "S3 bucket for asset \"00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5af\"" }, - "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3VersionKeyAA4674FB": { + "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3VersionKey451EAA56": { "Type": "String", - "Description": "S3 key for asset version \"5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720\"" + "Description": "S3 key for asset version \"00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5af\"" }, - "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720ArtifactHash3D7A279D": { + "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afArtifactHash761F4689": { "Type": "String", - "Description": "Artifact hash for asset \"5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720\"" + "Description": "Artifact hash for asset \"00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5af\"" }, "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1": { "Type": "String", @@ -2202,17 +2206,17 @@ "Type": "String", "Description": "Artifact hash for asset \"ea17febe6d04c66048f3e8e060c71685c0cb53122abceff44842d27bc0d4a03e\"" }, - "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": { + "AssetParameters3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87S3Bucket36F31A16": { "Type": "String", - "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" + "Description": "S3 bucket for asset \"3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87\"" }, - "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": { + "AssetParameters3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87S3VersionKeyF80D542B": { "Type": "String", - "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" + "Description": "S3 key for asset version \"3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87\"" }, - "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": { + "AssetParameters3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87ArtifactHash40DDF5EE": { "Type": "String", - "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" + "Description": "Artifact hash for asset \"3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87\"" }, "AssetParametersb866fb0fd5a9b4215d1e23188632d74c01f3195f6f9d706134b197b400afb680S3Bucket56B5C500": { "Type": "String", @@ -2226,17 +2230,17 @@ "Type": "String", "Description": "Artifact hash for asset \"b866fb0fd5a9b4215d1e23188632d74c01f3195f6f9d706134b197b400afb680\"" }, - "AssetParameters3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591S3BucketC38C4355": { + "AssetParameters8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35S3Bucket37C1382F": { "Type": "String", - "Description": "S3 bucket for asset \"3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591\"" + "Description": "S3 bucket for asset \"8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35\"" }, - "AssetParameters3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591S3VersionKey31FFCA42": { + "AssetParameters8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35S3VersionKey5D044A85": { "Type": "String", - "Description": "S3 key for asset version \"3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591\"" + "Description": "S3 key for asset version \"8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35\"" }, - "AssetParameters3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591ArtifactHash2A3C4E8F": { + "AssetParameters8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35ArtifactHash907D4CC2": { "Type": "String", - "Description": "Artifact hash for asset \"3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591\"" + "Description": "Artifact hash for asset \"8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35\"" }, "AssetParameters922360c7d159ef358ec5feeac54b70297766064bb1dc00b03a7f147d6f3a882bS3Bucket6FC76F07": { "Type": "String",