We're starting our platform journey of adopting Pu...
# general
t
We're starting our platform journey of adopting Pulumi in our org. I'm writing component resources that encapsulate specific architecture patterns we have agreed upon. We have a specific naming convention we'd like all of our resources defined in our pulumi projects to follow. Something like: env + stack-name + resource-name. For example,
devBackupStackSchedulerFunction
. We're going down this path to ensure we can support ephemeral deployments within a specific environment (i.e. account) for our cloud providers (helps us avoid naming collisions). ๐Ÿงต
My first thought (after going through some Pulumi tutorials) is something like this:
Copy code
import { ComponentResource, ComponentResourceOptions, Inputs } from "@pulumi/pulumi";
import { currentStack } from "../../core/common/stacks";
import { getEnvPrefix } from "../../core/common/utils";


/**
 * Base VDC Component Resource. All other component resources should extend this component.
 *
 * A component resource must register a unique type name with the base constructor.
 * To reduce the potential of other type name conflicts, this name contains the package and module name, in addition to the type: <package>:<module>:<type>.
 * These names are namespaced alongside non-component resources, such as aws:lambda:Function.
 *
 * @param type
 *  The type of the resource. Pattern: <pkg>:<module>:
 */
export class VdcComponentResource extends ComponentResource {
    readonly stack: string
    readonly env: string

    constructor(type: string, name: string, args?: Inputs, opts?: ComponentResourceOptions, remote?: boolean, packageRef?: Promise<string | undefined>) {
        const stack = currentStack;
        const env = getEnvPrefix(stack);
        const resourceName = env + name;

        // Customize the name of component resources to adhere to our naming convention
        super(`pkg:${type}:${resourceName}`, resourceName, args, opts, remote, packageRef);

        this.stack = stack;
        this.env = env;

        this.registerOutputs({ stack: this.stack, env: this.env })
    }
}

export class AzureComponentResource extends VdcComponentResource {
    constructor(name: string, args?: Inputs, opts?: ComponentResourceOptions, remote?: boolean, packageRef?: Promise<string | undefined>) {
        super('azure', name, args, opts, remote, packageRef);
    }
}
And so any additional component resources created that use the azure cloud should extend
AzureComponentResource
which follow our established naming convention.
Am I going about this the right way? My initial thought is yes but curious if other folks are accomplishing this another way. We currently have a lot of resources named like:
Copy code
this.apiManagement = new ApiManagementService(
      `${envPrefix}${name}Service`,...)

this.exampleSvcBackend = new Backend(
      `${envPrefix}${name}ExampleSvcBackend`, ...)
And while it works, makes it easy for engineers to make mistakes and forget formatting the name in such a way.
e
take a look at the config part in the yaml:
Copy code
pulumi:autonaming:
    mode: default
    providers:
      azure-native:
        resources:
          "azure-native:resources:ResourceGroup":
            pattern: "rg-${config.regionAbbreviation}-${stack}-${name}"
l
@thankful-painting-31068 having a company standard in resource naming is what we frequently heard from customers. Hence, we released this less than 2 weeks ago: https://www.pulumi.com/blog/autonaming-configuration/
t
thanks! I'll take a stab at that ๐Ÿ™Œ๐Ÿฝ
We have an existing function that does something like:
Copy code
/**
 * Returns the prefix to use for resources based on the current stack.
 *
 * @param currentStack The name of the current stack.
 * @returns The prefix to use for resources.
 */
function getEnvPrefix(currentStack: string): string {
  return currentStack.includes("-personal")
    ? toTitleCase(currentStack)
        .replace("something", "")
        .replace("something-else", "")
        .replace(/[^a-zA-Z0-9]/g, "")
        .substring(0, 7)
    : toTitleCase(currentStack).replace(/[^a-zA-Z0-9]/g, "");
}
Is there a way to accomplish something similar using the feature above? I see https://www.pulumi.com/docs/iac/concepts/resources/names/#custom-naming-pattern that can help with string length but what about transformations?
l
remember that many azure resources have extremely specific naming requirements, both for characters allowed, and length. It may be easier to use tags to implement a "one-size-fits-all" naming scheme and let the name itself be more or less autogenerated. Esp services that use the name to generate a globally unique hostname can be problematic, such as azure keyvault.
t
Thanks! Coming from the AWS serverless world and working with Azure is..... great.
Although IIRC AWS also some resource constraints when it comes to naming particular resources (albeit fewer than what I've had to deal with in Azure)
l
that is correct, AWS naming often just means "what's the value of the tag 'Name'" so its more flexible.