Skip to content

Commit

Permalink
add the poky ami build to the pipeline as a new project.
Browse files Browse the repository at this point in the history
  • Loading branch information
nateglims committed Sep 7, 2023
1 parent 8759d1d commit 35bd376
Show file tree
Hide file tree
Showing 4 changed files with 2,185 additions and 8 deletions.
75 changes: 67 additions & 8 deletions lib/demo-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as iam from 'aws-cdk-lib/aws-iam';
import * as efs from 'aws-cdk-lib/aws-efs';

import {
BuildEnvironmentVariableType,
BuildSpec,
ComputeType,
FileSystemLocation,
Expand All @@ -24,8 +25,9 @@ import {
Port,
SecurityGroup,
} from 'aws-cdk-lib/aws-ec2';
import { Bucket } from 'aws-cdk-lib/aws-s3';
import { Bucket, IBucket } from 'aws-cdk-lib/aws-s3';
import { SourceRepo, ProjectKind } from './constructs/source-repo';
import { VMImportBucket } from './vm-import-bucket';

/**
* Properties to allow customizing the build.
Expand All @@ -37,8 +39,8 @@ export interface DemoPipelineProps extends cdk.StackProps {
readonly imageTag?: string;
/** VPC where the networking setup resides. */
readonly vpc: IVpc;
/** The type of Layer */
readonly distroKind?: ProjectKind;
/** The type of project being built. */
readonly projectKind?: ProjectKind;
/** A name for the layer-repo that is created. Default is 'layer-repo' */
readonly layerRepoName?: string;
}
Expand Down Expand Up @@ -66,12 +68,34 @@ export class DemoPipelineStack extends cdk.Stack {
const dlFS = this.addFileSystem('Downloads', props.vpc, projectSg);
const tmpFS = this.addFileSystem('Temp', props.vpc, projectSg);

let artifactBucket: IBucket;
let environmentVariables = {};

if (props.projectKind && props.projectKind == ProjectKind.PokyAmi) {
/** The bucket our images are sent to. */
artifactBucket = new VMImportBucket(this, 'DemoArtifact', {
versioned: true,
enforceSSL: true,
});
environmentVariables = {
IMPORT_BUCKET: {
type: BuildEnvironmentVariableType.PLAINTEXT,
value: artifactBucket.bucketName,
},
};
} else {
artifactBucket = new Bucket(this, 'DemoArtifact', {
versioned: true,
enforceSSL: true,
});
}

/** Create our CodePipeline Actions. */

const sourceRepo = new SourceRepo(this, 'SourceRepo', {
...props,
repoName: props.layerRepoName ?? `layer-repo-${this.stackName}`,
kind: props.distroKind ?? ProjectKind.Poky,
kind: props.projectKind ?? ProjectKind.Poky,
});

const sourceOutput = new codepipeline.Artifact();
Expand All @@ -93,6 +117,7 @@ export class DemoPipelineStack extends cdk.Stack {
props.imageTag
),
privileged: true,
environmentVariables,
},
timeout: cdk.Duration.hours(4),
vpc: props.vpc,
Expand All @@ -116,6 +141,11 @@ export class DemoPipelineStack extends cdk.Stack {
],
});

if (props.projectKind && props.projectKind == ProjectKind.PokyAmi) {
artifactBucket.grantReadWrite(project);
project.addToRolePolicy(this.addVMExportPolicy());
}

const buildOutput = new codepipeline.Artifact();
const buildAction = new codepipeline_actions.CodeBuildAction({
input: sourceOutput,
Expand All @@ -124,10 +154,6 @@ export class DemoPipelineStack extends cdk.Stack {
project,
});

const artifactBucket = new Bucket(this, 'DemoArtifact', {
versioned: true,
enforceSSL: true,
});
const artifactAction = new codepipeline_actions.S3DeployAction({
actionName: 'Demo-Artifact',
input: buildOutput,
Expand Down Expand Up @@ -243,4 +269,37 @@ def handler(event, context):

return `${fsId}.efs.${region}.amazonaws.com:/`;
}

private addVMExportPolicy(): iam.PolicyStatement {
return new iam.PolicyStatement({
actions: [
'ec2:CancelConversionTask',
'ec2:CancelExportTask',
'ec2:CreateImage',
'ec2:CreateInstanceExportTask',
'ec2:CreateTags',
'ec2:DescribeConversionTasks',
'ec2:DescribeExportTasks',
'ec2:DescribeExportImageTasks',
'ec2:DescribeImages',
'ec2:DescribeInstanceStatus',
'ec2:DescribeInstances',
'ec2:DescribeSnapshots',
'ec2:DescribeTags',
'ec2:ExportImage',
'ec2:ImportInstance',
'ec2:ImportVolume',
'ec2:StartInstances',
'ec2:StopInstances',
'ec2:TerminateInstances',
'ec2:ImportImage',
'ec2:ImportSnapshot',
'ec2:DescribeImportImageTasks',
'ec2:DescribeImportSnapshotTasks',
'ec2:CancelImportTask',
'ec2:RegisterImage',
],
resources: ['*'],
});
}
}
41 changes: 41 additions & 0 deletions lib/vm-import-bucket.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';

/**
* ...
*/
export class VMImportBucket extends s3.Bucket {
constructor(scope: Construct, id: string, props: s3.BucketProps) {
super(scope, id, {
...props,
});

// Adapted from meta-aws-ewaol and
// https://docs.aws.amazon.com/vm-import/latest/userguide/required-permissions.html
const importPolicy = new iam.PolicyDocument({
statements: [
new iam.PolicyStatement({
actions: ['s3:GetBucketLocation', 's3:GetObject', 's3:ListBucket'],
resources: [this.bucketArn, `${this.bucketArn}/*`],
}),
new iam.PolicyStatement({
actions: [
'ec2:ModifySnapshotAttribute',
'ec2:CopySnapshot',
'ec2:RegisterImage',
'ec2:Describe*',
],
resources: ['*'],
}),
],
});

new iam.Role(scope, 'VMImportRole', {
roleName: 'vmimport',
assumedBy: new iam.ServicePrincipal('vmie.amazonaws.com'),
externalIds: ['vmimport'],
inlinePolicies: { importPolicy },
});
}
}
Loading

0 comments on commit 35bd376

Please sign in to comment.