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

@aws-cdk/aws-servicecatalogappregistry-alpha: Using Fn::Join with Name attribute in AWS::ServiceCatalogAppRegistry::Application generates Outputs that is not deployable #23641

Closed
knihit opened this issue Jan 11, 2023 · 2 comments · Fixed by #23652
Labels
@aws-cdk/aws-servicecatalogappregistry bug This issue is a bug. needs-triage This issue or PR still needs to be triaged.

Comments

@knihit
Copy link

knihit commented Jan 11, 2023

Describe the bug

Using Fn.join in applicationName attribute when creating Application using https://docs.aws.amazon.com/cdk/api/v2/docs/@aws-cdk_aws-servicecatalogappregistry-alpha.Application.html to generate AWS::ServiceCatalogAppRegistry::Application also generates generates a Description in Outputs that is not deployable.

        const application = new appreg.Application(this, 'RegistrySetup', {
            applicationName: `App-${cdk.Aws.STACK_NAME}-application-name`,
            description: `Service Catalog application to track and manage all your resources for the solution ${this.solutionName}`
        });

Expected Behavior

Because the applicationName is dynamic, do not use it for Description for Outputs

Current Behavior

The above code also generates Outputs

   "Description": {
    "Fn::Join": [
     "",
     [
      "Application manager url for application App-",
      {
       "Ref": "AWS::StackName"
      },
      "-application-name"
     ]
    ]
   },
   "Value": {
    "Fn::Join": [
     "",
     [
      "https://",
      {
       "Ref": "AWS::Region"
      },
      ".console.aws.amazon.com/systems-manager/appmanager/application/AWS_AppRegistry_Application-App-",
      {
       "Ref": "AWS::StackName"
      },
      "-application-name"
     ]
    ]
   }
  }

Because the Description is not a string, the stack becomes undeployable

Reproduction Steps

Refer method createAppForAppRegistry

import * as cdk from 'aws-cdk-lib';
import * as applicationinsights from 'aws-cdk-lib/aws-applicationinsights';
import * as appreg from '@aws-cdk/aws-servicecatalogappregistry-alpha';
import { Construct, IConstruct } from 'constructs';

export class AppRegistry extends Construct implements cdk.IAspect {
    /**
     * Name of the solution as set through from cdk.json
     */
    private solutionName: string;

    /**
     * Name of the application used to create an entry in AppRegistry as set through cdk.json
     */
    private applicationName: string;

    /**
     * Solution ID as set through cdk.json
     */
    private solutionID: string;

    /**
     * Solution version as set through cdk.json
     */
    private solutionVersion: string;

    /**
     * An AttributeGroupName initialized in the constructor of this class
     */
    private attributeGroupName: string;

    /**
     * An application type attribute initialized in the constructor of this class
     */
    private applicationType: string;

    /**
     * The instance of application that the solution stacks should be associated with
     */
    private application: appreg.Application;

    constructor(scope: Construct, id: string) {
        super(scope, id);
        this.solutionName = scope.node.tryGetContext('solution_name');
        this.applicationName = scope.node.tryGetContext('app_registry_name');
        this.solutionID = scope.node.tryGetContext('solution_id');
        this.solutionVersion = scope.node.tryGetContext('solution_version');
        this.applicationType = scope.node.tryGetContext('application_type');
    }

    /**
     * Method invoked as a `Visitor` pattern to inject aspects during cdk synthesis
     *
     * @param node
     */
    public visit(node: IConstruct): void {
        if (node instanceof cdk.Stack) {
            const stack = node as cdk.Stack;
            // parent stack
            if (!stack.nested) {
                this.createAppForAppRegistry();
                this.createAttributeGroup();
                this.createAppForAppInsights();
            }
            this.addTagsforApplication();
            this.application.associateAllStacksInScope(stack);
        }
    }

    /**
     * Method to initialize an Application in AppRegistry service
     *
     * @returns - Instance of AppRegistry's Application class
     */
    private createAppForAppRegistry(): void {
        this.application = new appreg.Application(this, 'RegistrySetup', {
            applicationName: cdk.Fn.join('-', [this.applicationName, cdk.Aws.REGION, cdk.Aws.ACCOUNT_ID]),
            description: `Service Catalog application to track and manage all your resources for the solution ${this.solutionName}`
        });
    }

    /**
     * Method to add tags to the AppRegistry's Application instance
     *
     */
    private addTagsforApplication(): void {
        if (!this.application) {
            this.createAppForAppRegistry();
        }

        cdk.Tags.of(this.application).add('Solutions:SolutionID', this.solutionID);
        cdk.Tags.of(this.application).add('Solutions:SolutionName', this.solutionName);
        cdk.Tags.of(this.application).add('Solutions:SolutionVersion', this.solutionVersion);
        cdk.Tags.of(this.application).add('Solutions:ApplicationType', this.applicationType);
    }

    /**
     * Method to create AttributeGroup to be associated with the Application's instance in AppRegistry
     *
     */
    private createAttributeGroup(): void {
        if (!this.application) {
            this.createAppForAppRegistry();
        }

        this.application.associateAttributeGroup(
            new appreg.AttributeGroup(this, 'AppAttributes', {
                attributeGroupName: cdk.Aws.STACK_NAME,
                description: 'Attributes for Solutions Metadata',
                attributes: {
                    applicationType: this.applicationType,
                    version: this.solutionVersion,
                    solutionID: this.solutionID,
                    solutionName: this.solutionName
                }
            })
        );
    }

    /**
     * Method to create resources to enable application insights
     */
    private createAppForAppInsights(): void {
        if (!this.application) {
            this.createAppForAppRegistry();
        }
        new applicationinsights.CfnApplication(this, 'AppInsightsSetup', {
            resourceGroupName: cdk.Fn.join('-', [
                'AWS_AppRegistry_Application',
                this.applicationName,
                cdk.Aws.REGION,
                cdk.Aws.ACCOUNT_ID
            ]),
            autoConfigurationEnabled: true,
            cweMonitorEnabled: true,
            opsCenterEnabled: true
        }).addDependency(this.application.node.defaultChild as cdk.CfnResource);
    }
}

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.59.0

Framework Version

2.59.0

Node.js Version

16.16.0

OS

Ventura (Mac OSX)

Language

Typescript

Language Version

4.7.4

Other information

No response

@knihit knihit added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jan 11, 2023
@knihit knihit changed the title @aws-cdk/aws-servicecatalogappregistry-alpha: Using Fn::Join with Name attribute in AWS::ServiceCatalogAppRegistry::Application generates a CfnOutput that is not deployable @aws-cdk/aws-servicecatalogappregistry-alpha: Using Fn::Join with Name attribute in AWS::ServiceCatalogAppRegistry::Application generates Outputs that is not deployable Jan 11, 2023
@knihit
Copy link
Author

knihit commented Jan 11, 2023

I am currently able to work around the problem with the following escape hatch

        const appRegistryCfnOutput = this.application.node.findChild('ApplicationManagerUrl') as cdk.CfnOutput;
        appRegistryCfnOutput.description = 'Application Manager url';

@mergify mergify bot closed this as completed in #23652 Jan 12, 2023
mergify bot pushed a commit that referenced this issue Jan 12, 2023
As a customer, if I want to generate my application name from dynamic parameters then `CfnOutput` description for Application manager url is in undeployable state as `Description` only supports string.
This fixes #23641

### All Submissions:

* [ X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Construct Runtime Dependencies:

* [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies)

### New Features

* [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-servicecatalogappregistry bug This issue is a bug. needs-triage This issue or PR still needs to be triaged.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant