diff --git a/packages/cli-plugin-deploy-pulumi/commands/build.js b/packages/cli-plugin-deploy-pulumi/commands/build.js index 13a192a5df..76c74d7e9c 100644 --- a/packages/cli-plugin-deploy-pulumi/commands/build.js +++ b/packages/cli-plugin-deploy-pulumi/commands/build.js @@ -6,9 +6,9 @@ module.exports = (params, context) => { name: "build", createProjectApplicationWorkspace: true, command: async ({ inputs, context, projectApplication }) => { - const { env } = inputs; + const { env, variant } = inputs; - const hookArgs = { context, env, inputs, projectApplication }; + const hookArgs = { context, env, variant, inputs, projectApplication }; await runHook({ hook: "hook-before-build", diff --git a/packages/cli-plugin-deploy-pulumi/commands/deploy.js b/packages/cli-plugin-deploy-pulumi/commands/deploy.js index 78fe6000a5..e8059093a6 100644 --- a/packages/cli-plugin-deploy-pulumi/commands/deploy.js +++ b/packages/cli-plugin-deploy-pulumi/commands/deploy.js @@ -13,9 +13,9 @@ module.exports = (params, context) => { telemetry: true, command: async commandParams => { const { inputs, context, projectApplication, pulumi, getDuration } = commandParams; - const { env, folder, build, deploy } = inputs; + const { env, variant, folder, build, deploy } = inputs; - const hookArgs = { context, env, inputs, projectApplication }; + const hookArgs = { context, env, variant, inputs, projectApplication }; context.info("Webiny version: %s", context.version); console.log(); diff --git a/packages/cli-plugin-deploy-pulumi/commands/deploy/pulumiLoginSelectStack.js b/packages/cli-plugin-deploy-pulumi/commands/deploy/pulumiLoginSelectStack.js index 90f85426b7..39cd8b97a9 100644 --- a/packages/cli-plugin-deploy-pulumi/commands/deploy/pulumiLoginSelectStack.js +++ b/packages/cli-plugin-deploy-pulumi/commands/deploy/pulumiLoginSelectStack.js @@ -1,24 +1,18 @@ const { login } = require("../../utils"); +const { getStackName } = require("../../utils/getStackName"); module.exports = async ({ inputs, projectApplication, pulumi }) => { const { env, variant } = inputs; await login(projectApplication); - console.log("------> stack", { - env, - variant - }); - const PULUMI_SECRETS_PROVIDER = process.env.PULUMI_SECRETS_PROVIDER; const PULUMI_CONFIG_PASSPHRASE = process.env.PULUMI_CONFIG_PASSPHRASE; - /** - * We want to have stack name as env-variant. - * If there is no variant sent, just env will be used - this is to maintain backward compatibility. - */ - const stackName = [env, variant].filter(Boolean).join("-"); - console.log("------> run command", ["stack", "select", stackName].join(" ")); + const stackName = getStackName({ + env, + variant + }); await pulumi.run({ command: ["stack", "select", stackName], @@ -32,15 +26,4 @@ module.exports = async ({ inputs, projectApplication, pulumi }) => { } } }); - - const result = await pulumi.run({ - command: ["stack", "output"], - execa: { - env: { - PULUMI_CONFIG_PASSPHRASE - } - } - }); - - console.log(JSON.stringify(result)); }; diff --git a/packages/cli-plugin-deploy-pulumi/commands/destroy.js b/packages/cli-plugin-deploy-pulumi/commands/destroy.js index dce078d75c..c24932d222 100644 --- a/packages/cli-plugin-deploy-pulumi/commands/destroy.js +++ b/packages/cli-plugin-deploy-pulumi/commands/destroy.js @@ -1,4 +1,5 @@ const { createPulumiCommand, processHooks } = require("../utils"); +const { getStackName } = require("../utils/getStackName"); module.exports = createPulumiCommand({ name: "destroy", @@ -6,7 +7,12 @@ module.exports = createPulumiCommand({ // without the deployment happening initially (e.g. CI/CD scaffold's `pullRequestClosed.yml` workflow). createProjectApplicationWorkspace: true, command: async ({ inputs, context, projectApplication, pulumi, getDuration }) => { - const { env, folder } = inputs; + const { env, variant, folder } = inputs; + + const stackName = getStackName({ + env, + variant + }); let stackExists = true; try { @@ -14,7 +20,7 @@ module.exports = createPulumiCommand({ const PULUMI_CONFIG_PASSPHRASE = process.env.PULUMI_CONFIG_PASSPHRASE; await pulumi.run({ - command: ["stack", "select", env], + command: ["stack", "select", stackName], args: { secretsProvider: PULUMI_SECRETS_PROVIDER }, @@ -29,11 +35,15 @@ module.exports = createPulumiCommand({ } if (!stackExists) { - context.error(`Project application %s (%s} environment) does not exist.`, folder, env); + context.error( + `Project application %s (%s} environment) does not exist.`, + folder, + stackName + ); return; } - const hooksParams = { context, env, projectApplication }; + const hooksParams = { context, env, variant, projectApplication }; await processHooks("hook-before-destroy", hooksParams); @@ -47,6 +57,7 @@ module.exports = createPulumiCommand({ stdio: "inherit", env: { WEBINY_ENV: env, + WEBINY_VARIANT: variant || "", WEBINY_PROJECT_NAME: context.project.name } } diff --git a/packages/cli-plugin-deploy-pulumi/commands/output.js b/packages/cli-plugin-deploy-pulumi/commands/output.js index 7a734cd54f..924970d267 100644 --- a/packages/cli-plugin-deploy-pulumi/commands/output.js +++ b/packages/cli-plugin-deploy-pulumi/commands/output.js @@ -1,10 +1,16 @@ const { createPulumiCommand } = require("../utils"); +const { getStackName } = require("../utils/getStackName"); module.exports = createPulumiCommand({ name: "output", createProjectApplicationWorkspace: false, command: async ({ inputs, context, pulumi }) => { - const { env, folder, json } = inputs; + const { env, variant, folder, json } = inputs; + + const stackName = getStackName({ + env, + variant + }); let stackExists = true; try { @@ -12,7 +18,7 @@ module.exports = createPulumiCommand({ const PULUMI_CONFIG_PASSPHRASE = process.env.PULUMI_CONFIG_PASSPHRASE; await pulumi.run({ - command: ["stack", "select", env], + command: ["stack", "select", `${stackName}`], args: { secretsProvider: PULUMI_SECRETS_PROVIDER }, @@ -27,12 +33,14 @@ module.exports = createPulumiCommand({ } if (stackExists) { - return pulumi.run({ + return await pulumi.run({ command: ["stack", "output"], args: { json }, - execa: { stdio: "inherit" } + execa: { + stdio: "inherit" + } }); } diff --git a/packages/cli-plugin-deploy-pulumi/commands/pulumiRun.js b/packages/cli-plugin-deploy-pulumi/commands/pulumiRun.js index cadd9714b6..551c318b33 100644 --- a/packages/cli-plugin-deploy-pulumi/commands/pulumiRun.js +++ b/packages/cli-plugin-deploy-pulumi/commands/pulumiRun.js @@ -1,14 +1,20 @@ const { createPulumiCommand } = require("../utils"); +const { getStackName } = require("../utils/getStackName"); module.exports = createPulumiCommand({ name: "pulumi", createProjectApplicationWorkspace: false, command: async ({ inputs, context, pulumi }) => { const [, ...command] = inputs._; - const { env, folder, debug, variant } = inputs; + const { env, variant, folder, debug } = inputs; + + const stackName = getStackName({ + env, + variant + }); if (env) { - debug && context.debug(`Environment provided - selecting %s Pulumi stack.`, env); + debug && context.debug(`Environment provided - selecting %s Pulumi stack.`, stackName); let stackExists = true; try { @@ -16,7 +22,7 @@ module.exports = createPulumiCommand({ const PULUMI_CONFIG_PASSPHRASE = process.env.PULUMI_CONFIG_PASSPHRASE; await pulumi.run({ - command: ["stack", "select", env], + command: ["stack", "select", stackName], args: { secretsProvider: PULUMI_SECRETS_PROVIDER }, @@ -33,7 +39,7 @@ module.exports = createPulumiCommand({ if (!stackExists) { throw new Error( `Project application ${context.error.hl(folder)} (${context.error.hl( - env + stackName )} environment) does not exist.` ); } diff --git a/packages/cli-plugin-deploy-pulumi/commands/watch.js b/packages/cli-plugin-deploy-pulumi/commands/watch.js index 08e9ec43fc..b118ec8988 100644 --- a/packages/cli-plugin-deploy-pulumi/commands/watch.js +++ b/packages/cli-plugin-deploy-pulumi/commands/watch.js @@ -21,6 +21,7 @@ const { loadEnvVariables, runHook } = require("../utils"); +const { getStackName } = require("../utils/getStackName"); // Do not allow watching "prod" and "production" environments. On the Pulumi CLI side, the command // is still in preview mode, so it's definitely not wise to use it on production environments. @@ -101,7 +102,13 @@ module.exports = async (inputs, context) => { } } - const hookArgs = { context, env: inputs.env, inputs, projectApplication }; + const hookArgs = { + context, + env: inputs.env, + variant: inputs.variant, + inputs, + projectApplication + }; await runHook({ hook: "hook-before-watch", @@ -125,16 +132,21 @@ module.exports = async (inputs, context) => { let PULUMI_CONFIG_PASSPHRASE = process.env.PULUMI_CONFIG_PASSPHRASE; if (inputs.deploy && projectApplication) { - const { env } = inputs; + const { env, variant } = inputs; await login(projectApplication); const pulumi = await getPulumi({ projectApplication }); + const stackName = getStackName({ + env, + variant + }); + let stackExists = true; try { await pulumi.run({ - command: ["stack", "select", env], + command: ["stack", "select", stackName], args: { secretsProvider: PULUMI_SECRETS_PROVIDER }, @@ -324,6 +336,7 @@ module.exports = async (inputs, context) => { execa: { env: { WEBINY_ENV: inputs.env, + WEBINY_VARIANT: inputs.variant || "", WEBINY_PROJECT_NAME: context.project.name, WEBINY_LOGS_FORWARD_URL: logging.url } diff --git a/packages/cli-plugin-deploy-pulumi/utils/createProjectApplicationWorkspace.js b/packages/cli-plugin-deploy-pulumi/utils/createProjectApplicationWorkspace.js index 0a754acad7..7be91e422d 100644 --- a/packages/cli-plugin-deploy-pulumi/utils/createProjectApplicationWorkspace.js +++ b/packages/cli-plugin-deploy-pulumi/utils/createProjectApplicationWorkspace.js @@ -14,10 +14,12 @@ module.exports = async ({ projectApplication, inputs }) => { // Wait a bit and make sure the files are ready to have its content replaced. await new Promise(resolve => setTimeout(resolve, 10)); + const variant = !inputs.variant || inputs.variant === "undefined" ? "" : inputs.variant; + replaceInPath(path.join(projectApplication.paths.workspace, "/**/*.{ts,js,yaml}"), [ { find: "{PROJECT_ID}", replaceWith: projectApplication.id }, { find: "{PROJECT_DESCRIPTION}", replaceWith: projectApplication.description }, { find: "{DEPLOY_ENV}", replaceWith: inputs.env }, - { find: "{DEPLOY_VARIANT}", replaceWith: inputs.variant } + { find: "{DEPLOY_VARIANT}", replaceWith: variant } ]); }; diff --git a/packages/cli-plugin-deploy-pulumi/utils/createPulumiCommand.js b/packages/cli-plugin-deploy-pulumi/utils/createPulumiCommand.js index 09d495f881..90bbbf7463 100644 --- a/packages/cli-plugin-deploy-pulumi/utils/createPulumiCommand.js +++ b/packages/cli-plugin-deploy-pulumi/utils/createPulumiCommand.js @@ -57,6 +57,7 @@ const createPulumiCommand = ({ const getTelemetryEventName = stage => `cli-pulumi-command-${name}-${stage}`; const telemetryProperties = { env: params.env || "unknown", + variant: params.variant || "unknown", commandParams: JSON.stringify(params) }; diff --git a/packages/cli-plugin-deploy-pulumi/utils/getStackExport.js b/packages/cli-plugin-deploy-pulumi/utils/getStackExport.js index 21674e6abd..d8414ccd2f 100644 --- a/packages/cli-plugin-deploy-pulumi/utils/getStackExport.js +++ b/packages/cli-plugin-deploy-pulumi/utils/getStackExport.js @@ -2,15 +2,20 @@ const execa = require("execa"); const { getProject } = require("@webiny/cli/utils"); const cache = {}; -const getOutputJson = ({ folder, env, cwd }) => { +const getOutputJson = ({ folder, env, variant, cwd }) => { const project = getProject(); - if (cache[folder + env]) { - return cache[folder + env]; + const cacheKey = [folder, env, variant].filter(Boolean).join("_"); + + if (cache[cacheKey]) { + return cache[cacheKey]; } try { const command = ["webiny", "pulumi", folder, "--env", env, "--", "stack", "export"]; + if (variant) { + command.push("--variant", variant); + } const { stdout } = execa.sync("yarn", command.filter(Boolean), { cwd: cwd || project.root diff --git a/packages/cli-plugin-deploy-pulumi/utils/getStackName.js b/packages/cli-plugin-deploy-pulumi/utils/getStackName.js new file mode 100644 index 0000000000..6db9495809 --- /dev/null +++ b/packages/cli-plugin-deploy-pulumi/utils/getStackName.js @@ -0,0 +1,11 @@ +/** + * We want to have stack name as env-variant. + * If there is no variant sent, just env will be used - this is to maintain backward compatibility. + */ +const getStackName = ({ env, variant }) => { + return [env, variant].filter(Boolean).join("-"); +}; + +module.exports = { + getStackName +}; diff --git a/packages/cwp-template-aws/cli/deploy/deploy.js b/packages/cwp-template-aws/cli/deploy/deploy.js index 04d164605c..53fdff4aeb 100644 --- a/packages/cwp-template-aws/cli/deploy/deploy.js +++ b/packages/cwp-template-aws/cli/deploy/deploy.js @@ -48,7 +48,13 @@ module.exports = async (inputs, context) => { installed && console.log(); // 2. Check if first deployment. - const isFirstDeployment = !isCI && !getStackOutput({ folder: "apps/core", env, variant }); + const isFirstDeployment = + !isCI && + !getStackOutput({ + folder: "apps/core", + env, + variant + }); if (isFirstDeployment) { context.info(`Looks like this is your first time deploying the project.`); context.info( diff --git a/packages/pulumi-aws/src/components/tenantRouter/WebsiteTenantRouter.ts b/packages/pulumi-aws/src/components/tenantRouter/WebsiteTenantRouter.ts index 7a048b5949..58409a1064 100644 --- a/packages/pulumi-aws/src/components/tenantRouter/WebsiteTenantRouter.ts +++ b/packages/pulumi-aws/src/components/tenantRouter/WebsiteTenantRouter.ts @@ -36,8 +36,8 @@ export class WebsiteTenantRouter extends pulumi.ComponentResource { const { region, dynamoDbTable } = getStackOutput<{ region: string; dynamoDbTable: string }>( { folder: config?.apiFolder || "api", - env: config?.apiEnv || String(process.env.WEBINY_ENV), - variant: config?.apiVariant || String(process.env.WEBINY_VARIANT) + env: config?.apiEnv || process.env.WEBINY_ENV || "", + variant: config?.apiVariant || process.env.WEBINY_VARIANT || "" } ); diff --git a/packages/serverless-cms-aws/src/api/plugins/ensureCoreDeployed.ts b/packages/serverless-cms-aws/src/api/plugins/ensureCoreDeployed.ts index ffebc6249a..8534d74768 100644 --- a/packages/serverless-cms-aws/src/api/plugins/ensureCoreDeployed.ts +++ b/packages/serverless-cms-aws/src/api/plugins/ensureCoreDeployed.ts @@ -1,6 +1,5 @@ -import { getStackOutput } from "@webiny/cli-plugin-deploy-pulumi/utils"; +import { getStackOutput, GracefulError } from "@webiny/cli-plugin-deploy-pulumi/utils"; import { BeforeDeployPlugin } from "@webiny/cli-plugin-deploy-pulumi/plugins"; -import { GracefulError } from "@webiny/cli-plugin-deploy-pulumi/utils"; export const ensureCoreDeployed = new BeforeDeployPlugin(({ env, variant }, ctx) => { const output = getStackOutput({ @@ -12,10 +11,14 @@ export const ensureCoreDeployed = new BeforeDeployPlugin(({ env, variant }, ctx) if (coreDeployed) { return; } + let variantCmd = ""; + if (variant) { + variantCmd = ` --variant ${variant}`; + } const coreAppName = ctx.error.hl("Core"); const apiAppName = ctx.error.hl("API"); - const cmd = ctx.error.hl(`yarn webiny deploy core --env ${env}`); + const cmd = ctx.error.hl(`yarn webiny deploy core --env ${env}${variantCmd}`); ctx.error(`Cannot deploy ${apiAppName} project application before deploying ${coreAppName}.`); throw new GracefulError(