Skip to content

Commit

Permalink
fix(apprunner): incorrect serviceName (#26015)
Browse files Browse the repository at this point in the history
The AppRunner `Service` L2 construct returns `serviceArn` attribute as the `serviceName`. As Cloudformation does not return serivceName attribute(see [return values](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apprunner-service.html#aws-resource-apprunner-service-return-values)). This PR splits the serviceArn to extract the serviceName instead.

Closes #26002 

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
pahud authored Jun 20, 2023
1 parent 37e0c43 commit ad89f01
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 17 deletions.
11 changes: 9 additions & 2 deletions packages/@aws-cdk/aws-apprunner-alpha/lib/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1041,7 +1041,6 @@ export class Service extends cdk.Resource {

/**
* The name of the service.
* @attribute
*/
readonly serviceName: string;

Expand Down Expand Up @@ -1106,7 +1105,15 @@ export class Service extends cdk.Resource {
this.serviceId = resource.attrServiceId;
this.serviceUrl = resource.attrServiceUrl;
this.serviceStatus = resource.attrStatus;
this.serviceName = resource.ref;
/**
* Cloudformaton does not return the serviceName attribute so we extract it from the serviceArn.
* The ARN comes with this format:
* arn:aws:apprunner:us-east-1:123456789012:service/SERVICE_NAME/SERVICE_ID
*/
// First, get the last element by splitting with ':'
const resourceFullName = cdk.Fn.select(5, cdk.Fn.split(':', this.serviceArn));
// Now, split the resourceFullName with '/' to get the serviceName
this.serviceName = cdk.Fn.select(1, cdk.Fn.split('/', resourceFullName));
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":"31.0.0"}
{"version":"32.0.0"}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"version": "31.0.0",
"version": "32.0.0",
"files": {
"f00e06a7824495556404fb0a324a2b16e71836ea8aee2588858ad09bad6da100": {
"798d29f00c3d8f856bf85b7138c6e647084b39d095a48e9fe00157a314591215": {
"source": {
"path": "integ-apprunner-ecr-public.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "f00e06a7824495556404fb0a324a2b16e71836ea8aee2588858ad09bad6da100.json",
"objectKey": "798d29f00c3d8f856bf85b7138c6e647084b39d095a48e9fe00157a314591215.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,58 @@
]
]
}
},
"ServiceName": {
"Value": {
"Fn::Select": [
1,
{
"Fn::Split": [
"/",
{
"Fn::Select": [
5,
{
"Fn::Split": [
":",
{
"Fn::GetAtt": [
"Service1EDCC8134",
"ServiceArn"
]
}
]
}
]
}
]
}
]
}
},
"ServiceId": {
"Value": {
"Fn::GetAtt": [
"Service1EDCC8134",
"ServiceId"
]
}
},
"ServiceStatus": {
"Value": {
"Fn::GetAtt": [
"Service1EDCC8134",
"Status"
]
}
},
"ServiceArn": {
"Value": {
"Fn::GetAtt": [
"Service1EDCC8134",
"ServiceArn"
]
}
}
},
"Parameters": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "31.0.0",
"version": "32.0.0",
"testCases": {
"integ.service-ecr-public": {
"stacks": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "31.0.0",
"version": "32.0.0",
"artifacts": {
"integ-apprunner-ecr-public.assets": {
"type": "cdk:asset-manifest",
Expand All @@ -17,7 +17,7 @@
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/f00e06a7824495556404fb0a324a2b16e71836ea8aee2588858ad09bad6da100.json",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/798d29f00c3d8f856bf85b7138c6e647084b39d095a48e9fe00157a314591215.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
Expand Down Expand Up @@ -45,6 +45,30 @@
"data": "URL1"
}
],
"/integ-apprunner-ecr-public/ServiceName": [
{
"type": "aws:cdk:logicalId",
"data": "ServiceName"
}
],
"/integ-apprunner-ecr-public/ServiceId": [
{
"type": "aws:cdk:logicalId",
"data": "ServiceId"
}
],
"/integ-apprunner-ecr-public/ServiceStatus": [
{
"type": "aws:cdk:logicalId",
"data": "ServiceStatus"
}
],
"/integ-apprunner-ecr-public/ServiceArn": [
{
"type": "aws:cdk:logicalId",
"data": "ServiceArn"
}
],
"/integ-apprunner-ecr-public/BootstrapVersion": [
{
"type": "aws:cdk:logicalId",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,43 +38,75 @@
}
},
"constructInfo": {
"fqn": "@aws-cdk/aws-apprunner.CfnService",
"fqn": "aws-cdk-lib.aws_apprunner.CfnService",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/aws-apprunner.Service",
"fqn": "@aws-cdk/aws-apprunner-alpha.Service",
"version": "0.0.0"
}
},
"URL1": {
"id": "URL1",
"path": "integ-apprunner-ecr-public/URL1",
"constructInfo": {
"fqn": "@aws-cdk/core.CfnOutput",
"fqn": "aws-cdk-lib.CfnOutput",
"version": "0.0.0"
}
},
"ServiceName": {
"id": "ServiceName",
"path": "integ-apprunner-ecr-public/ServiceName",
"constructInfo": {
"fqn": "aws-cdk-lib.CfnOutput",
"version": "0.0.0"
}
},
"ServiceId": {
"id": "ServiceId",
"path": "integ-apprunner-ecr-public/ServiceId",
"constructInfo": {
"fqn": "aws-cdk-lib.CfnOutput",
"version": "0.0.0"
}
},
"ServiceStatus": {
"id": "ServiceStatus",
"path": "integ-apprunner-ecr-public/ServiceStatus",
"constructInfo": {
"fqn": "aws-cdk-lib.CfnOutput",
"version": "0.0.0"
}
},
"ServiceArn": {
"id": "ServiceArn",
"path": "integ-apprunner-ecr-public/ServiceArn",
"constructInfo": {
"fqn": "aws-cdk-lib.CfnOutput",
"version": "0.0.0"
}
},
"BootstrapVersion": {
"id": "BootstrapVersion",
"path": "integ-apprunner-ecr-public/BootstrapVersion",
"constructInfo": {
"fqn": "@aws-cdk/core.CfnParameter",
"fqn": "aws-cdk-lib.CfnParameter",
"version": "0.0.0"
}
},
"CheckBootstrapVersion": {
"id": "CheckBootstrapVersion",
"path": "integ-apprunner-ecr-public/CheckBootstrapVersion",
"constructInfo": {
"fqn": "@aws-cdk/core.CfnRule",
"fqn": "aws-cdk-lib.CfnRule",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/core.Stack",
"fqn": "aws-cdk-lib.Stack",
"version": "0.0.0"
}
},
Expand All @@ -83,12 +115,12 @@
"path": "Tree",
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.1.252"
"version": "10.2.52"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/core.App",
"fqn": "aws-cdk-lib.App",
"version": "0.0.0"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ const service1 = new Service(stack, 'Service1', {
autoDeploymentsEnabled: false,
});
new cdk.CfnOutput(stack, 'URL1', { value: `https://${service1.serviceUrl}` });
new cdk.CfnOutput(stack, 'ServiceName', { value: service1.serviceName });
new cdk.CfnOutput(stack, 'ServiceId', { value: service1.serviceId });
new cdk.CfnOutput(stack, 'ServiceStatus', { value: service1.serviceStatus });
new cdk.CfnOutput(stack, 'ServiceArn', { value: service1.serviceArn });
19 changes: 19 additions & 0 deletions packages/@aws-cdk/aws-apprunner-alpha/test/service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,25 @@ test('import from service attributes', () => {
expect(svc).toHaveProperty('serviceUrl');
});

test('serviceName validation', () => {
// GIVEN
const app = new cdk.App();
const stack = new cdk.Stack(app, 'demo-stack');
// WHEN
const svc = new apprunner.Service(stack, 'CustomService', {
source: apprunner.Source.fromEcrPublic({
imageConfiguration: { port: 8000 },
imageIdentifier: 'public.ecr.aws/aws-containers/hello-app-runner:latest',
}),
});

// THEN
// the serviceName should not be the resource.ref
expect(svc.serviceName).not.toEqual((svc.node.defaultChild as cdk.CfnResource).ref);
// serviceName and serviceArn should be different
expect(svc.serviceName).not.toEqual(svc.serviceArn);
});

test('undefined imageConfiguration port is allowed', () => {
// GIVEN
const app = new cdk.App();
Expand Down

0 comments on commit ad89f01

Please sign in to comment.