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

fix(apprunner): startCommand and environment are ignored in imageConfiguration #16939

Merged
merged 10 commits into from
Nov 30, 2021
32 changes: 31 additions & 1 deletion packages/@aws-cdk/aws-apprunner/lib/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ export class Runtime {
private constructor(public readonly name: string) { }
}

/**
* The environment variable for the service.
*/
interface EnvironmentVariable {
readonly name: string;
readonly value: string;
}

/**
* Result of binding `Source` into a `Service`.
Expand Down Expand Up @@ -707,6 +714,10 @@ export class Service extends cdk.Resource {
private readonly props: ServiceProps;
private accessRole?: iam.IRole;
private source: SourceConfig;
/**
* Environment variables for this service
*/
private environment?: { [key: string]: string } = {};

/**
* The ARN of the Service.
Expand Down Expand Up @@ -798,25 +809,44 @@ export class Service extends cdk.Resource {

}
private renderCodeConfigurationValues(props: CodeConfigurationValues): any {
this.environment = props.environment;
return {
...props,
port: props.port,
buildCommand: props.buildCommand,
runtime: props.runtime.name,
runtimeEnvironmentVariables: this.renderEnvironmentVariables(),
startCommand: props.startCommand,
};
}
private renderImageRepository(): any {
const repo = this.source.imageRepository!;
this.environment = repo.imageConfiguration?.environment;
if (repo.imageConfiguration?.port) {
// convert port from type number to string
return Object.assign(repo, {
imageConfiguration: {
port: repo.imageConfiguration.port.toString(),
startCommand: repo.imageConfiguration.startCommand,
runtimeEnvironmentVariables: this.renderEnvironmentVariables(),
pahud marked this conversation as resolved.
Show resolved Hide resolved
},
});
} else {
return repo;
}
}

private renderEnvironmentVariables(): EnvironmentVariable[] | undefined {
if (this.environment) {
let env: EnvironmentVariable[] = [];
for (const [key, value] of Object.entries(this.environment)) {
env.push({ name: key, value: value });
}
pahud marked this conversation as resolved.
Show resolved Hide resolved
return env;
} else {
return undefined;
}
}

private generateDefaultRole(): iam.Role {
const accessRole = new iam.Role(this, 'AccessRole', {
assumedBy: new iam.ServicePrincipal('build.apprunner.amazonaws.com'),
Expand Down
104 changes: 104 additions & 0 deletions packages/@aws-cdk/aws-apprunner/test/service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,50 @@ test('create a service with ECR Public(image repository type: ECR_PUBLIC)', () =
});
});

test('custom environment variables and start commands are allowed for imageConfiguration', () => {
// GIVEN
const app = new cdk.App();
const stack = new cdk.Stack(app, 'demo-stack');
// WHEN
new Service(stack, 'DemoService', {
source: Source.fromEcrPublic({
imageConfiguration: {
port: 8000,
environment: {
foo: 'fooval',
bar: 'barval',
},
startCommand: '/root/start-command.sh',
},
imageIdentifier: 'public.ecr.aws/aws-containers/hello-app-runner:latest',
}),
});
// we should have the service
Template.fromStack(stack).hasResourceProperties('AWS::AppRunner::Service', {
SourceConfiguration: {
AuthenticationConfiguration: {},
ImageRepository: {
ImageConfiguration: {
Port: '8000',
RuntimeEnvironmentVariables: [
{
Name: 'foo',
Value: 'fooval',
},
{
Name: 'bar',
Value: 'barval',
},
],
StartCommand: '/root/start-command.sh',
},
ImageIdentifier: 'public.ecr.aws/aws-containers/hello-app-runner:latest',
ImageRepositoryType: 'ECR_PUBLIC',
},
},
});
});

test('create a service from existing ECR repository(image repository type: ECR)', () => {
// GIVEN
const app = new cdk.App();
Expand Down Expand Up @@ -249,6 +293,66 @@ test('create a service with github repository - undefined branch name is allowed
});
});

test('create a service with github repository - buildCommand, environment and startCommand are allowed', () => {
// GIVEN
const app = new cdk.App();
const stack = new cdk.Stack(app, 'demo-stack');
// WHEN
new Service(stack, 'DemoService', {
source: Source.fromGitHub({
repositoryUrl: 'https://github.com/aws-containers/hello-app-runner',
configurationSource: ConfigurationSourceType.API,
codeConfigurationValues: {
runtime: Runtime.PYTHON_3,
port: '8000',
buildCommand: '/root/build.sh',
environment: {
foo: 'fooval',
bar: 'barval',
},
startCommand: '/root/start.sh',
},
connection: GitHubConnection.fromConnectionArn('MOCK'),
}),
});

// THEN
// we should have the service with the branch value as 'main'
Template.fromStack(stack).hasResourceProperties('AWS::AppRunner::Service', {
SourceConfiguration: {
AuthenticationConfiguration: {
ConnectionArn: 'MOCK',
},
CodeRepository: {
CodeConfiguration: {
CodeConfigurationValues: {
Port: '8000',
Runtime: 'PYTHON_3',
BuildCommand: '/root/build.sh',
RuntimeEnvironmentVariables: [
{
Name: 'foo',
Value: 'fooval',
},
{
Name: 'bar',
Value: 'barval',
},
],
StartCommand: '/root/start.sh',
},
ConfigurationSource: 'API',
},
RepositoryUrl: 'https://github.com/aws-containers/hello-app-runner',
SourceCodeVersion: {
Type: 'BRANCH',
Value: 'main',
},
},
},
});
});


test('import from service name', () => {
// GIVEN
Expand Down