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: support for cross-account CodePipelines #1924

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ export interface DnsValidatedCertificateProps extends CertificateProps {
/**
* A certificate managed by AWS Certificate Manager. Will be automatically
* validated using DNS validation against the specified Route 53 hosted zone.
*
* @resource AWS::CertificateManager::Certificate
*/
export class DnsValidatedCertificate extends cdk.Construct implements ICertificate {
export class DnsValidatedCertificate extends cdk.Resource implements ICertificate {
public readonly certificateArn: string;
private normalizedZoneName: string;
private hostedZoneId: string;
Expand Down
24 changes: 18 additions & 6 deletions packages/@aws-cdk/aws-codebuild/lib/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ecr = require('@aws-cdk/aws-ecr');
import events = require('@aws-cdk/aws-events');
import iam = require('@aws-cdk/aws-iam');
import kms = require('@aws-cdk/aws-kms');
import { Aws, Construct, IResource, Resource, Stack, Token } from '@aws-cdk/cdk';
import { Aws, Construct, IResource, PhysicalName, Resource, ResourceIdentifiers, Stack, Token } from '@aws-cdk/cdk';
import { BuildArtifacts, CodePipelineBuildArtifacts, NoBuildArtifacts } from './artifacts';
import { Cache } from './cache';
import { CfnProject } from './codebuild.generated';
Expand Down Expand Up @@ -451,7 +451,7 @@ export interface CommonProjectProps {
*
* @default - Name is automatically generated.
*/
readonly projectName?: string;
readonly projectName?: PhysicalName;

/**
* VPC network to place codebuild network interfaces
Expand Down Expand Up @@ -616,13 +616,16 @@ export class Project extends ProjectBase {
private _securityGroups: ec2.ISecurityGroup[] = [];

constructor(scope: Construct, id: string, props: ProjectProps) {
super(scope, id);
super(scope, id, {
physicalName: props.projectName,
});

if (props.buildScriptAssetEntrypoint && !props.buildScriptAsset) {
throw new Error('To use buildScriptAssetEntrypoint, supply buildScriptAsset as well.');
}

this.role = props.role || new iam.Role(this, 'Role', {
roleName: PhysicalName.auto({ crossEnvironment: true }),
assumedBy: new iam.ServicePrincipal('codebuild.amazonaws.com')
});
this.grantPrincipal = this.role;
Expand Down Expand Up @@ -700,16 +703,25 @@ export class Project extends ProjectBase {
encryptionKey: props.encryptionKey && props.encryptionKey.keyArn,
badgeEnabled: props.badge,
cache: cache._toCloudFormation(),
name: props.projectName,
name: this.physicalName.value,
timeoutInMinutes: props.timeout,
secondarySources: new Token(() => this.renderSecondarySources()),
secondaryArtifacts: new Token(() => this.renderSecondaryArtifacts()),
triggers: this.source._buildTriggers(),
vpcConfig: this.configureVpc(props),
});

this.projectArn = resource.projectArn;
this.projectName = resource.projectName;
const resourceIdentifiers = new ResourceIdentifiers(this, {
arn: resource.projectArn,
name: resource.projectName,
arnComponents: {
service: 'codebuild',
resource: 'project',
resourceName: this.physicalName.value,
},
});
this.projectArn = resourceIdentifiers.arn;
this.projectName = resourceIdentifiers.name;

this.addToRolePolicy(this.createLoggingPermission());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ export interface LambdaDeploymentGroupAttributes {
readonly deploymentGroupName: string;
}

class ImportedLambdaDeploymentGroup extends cdk.Construct implements ILambdaDeploymentGroup {
class ImportedLambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploymentGroup {
public readonly application: ILambdaApplication;
public readonly deploymentGroupName: string;
public readonly deploymentGroupArn: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export class CodeBuildAction extends codepipeline.Action {
artifactBounds: { minInputs: 1, maxInputs: 5, minOutputs: 0, maxOutputs: 5 },
inputs: [props.input, ...props.extraInputs || []],
outputs: getOutputs(props),
resource: props.project,
configuration: {
ProjectName: props.project.projectName,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ function _stackArn(stackName: string, scope: cdk.IConstruct): string {
});
}

class PipelineDouble extends cdk.Construct implements codepipeline.IPipeline {
class PipelineDouble extends cdk.Resource implements codepipeline.IPipeline {
public readonly pipelineName: string;
public readonly pipelineArn: string;
public readonly role: iam.Role;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,59 +8,6 @@
}
}
},
"ActionRole60B0EDF7": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::",
{
"Ref": "AWS::AccountId"
},
":root"
]
]
}
}
}
],
"Version": "2012-10-17"
}
}
},
"ActionRoleDefaultPolicyCA33BE56": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "sqs:*",
"Effect": "Allow",
"Resource": "*"
}
],
"Version": "2012-10-17"
},
"PolicyName": "ActionRoleDefaultPolicyCA33BE56",
"Roles": [
{
"Ref": "ActionRole60B0EDF7"
}
]
}
},
"MyPipelineRoleC0D47CA4": {
"Type": "AWS::IAM::Role",
"Properties": {
Expand Down Expand Up @@ -157,54 +104,14 @@
]
},
{
"Action": "iam:PassRole",
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"MyPipelineCFNCFNDeployRole9CC99B3F",
"ActionRole60B0EDF7",
"Arn"
]
}
},
{
"Action": [
"cloudformation:CreateStack",
"cloudformation:DescribeStack*",
"cloudformation:GetStackPolicy",
"cloudformation:GetTemplate*",
"cloudformation:SetStackPolicy",
"cloudformation:UpdateStack",
"cloudformation:ValidateTemplate"
],
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":cloudformation:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":stack/aws-cdk-codepipeline-cross-region-deploy-stack/*"
]
]
}
},
{
"Action": [
"sts:AssumeRole",
"iam:PassRole"
],
"Effect": "Allow",
"Resource": "*"
}
],
"Version": "2012-10-17"
Expand Down Expand Up @@ -305,6 +212,101 @@
"MyPipelineRoleC0D47CA4"
]
},
"ActionRole60B0EDF7": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::",
{
"Ref": "AWS::AccountId"
},
":root"
]
]
}
}
}
],
"Version": "2012-10-17"
}
}
},
"ActionRoleDefaultPolicyCA33BE56": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "sqs:*",
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "iam:PassRole",
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"MyPipelineCFNCFNDeployRole9CC99B3F",
"Arn"
]
}
},
{
"Action": [
"cloudformation:CreateStack",
"cloudformation:DescribeStack*",
"cloudformation:GetStackPolicy",
"cloudformation:GetTemplate*",
"cloudformation:SetStackPolicy",
"cloudformation:UpdateStack",
"cloudformation:ValidateTemplate"
],
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":cloudformation:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":stack/aws-cdk-codepipeline-cross-region-deploy-stack/*"
]
]
}
}
],
"Version": "2012-10-17"
},
"PolicyName": "ActionRoleDefaultPolicyCA33BE56",
"Roles": [
{
"Ref": "ActionRole60B0EDF7"
}
]
}
},
"MyPipelineCFNCFNDeployRole9CC99B3F": {
"Type": "AWS::IAM::Role",
"Properties": {
Expand Down Expand Up @@ -333,4 +335,4 @@
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,12 @@ const cfnStage = {
],
};

const pipeline = new codepipeline.Pipeline(stack, 'MyPipeline', {
new codepipeline.Pipeline(stack, 'MyPipeline', {
artifactBucket: bucket,
stages: [
sourceStage,
cfnStage,
],
});
pipeline.addToRolePolicy(new iam.PolicyStatement()
.addActions("sts:AssumeRole", "iam:PassRole")
.addAllResources()
);

app.synth();
Loading