From d63e1751582516a9a91023cb299a0389a68fe139 Mon Sep 17 00:00:00 2001 From: Thorarinn Sigurdsson Date: Thu, 2 Dec 2021 16:15:16 +0100 Subject: [PATCH] feat(core): module varfiles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added support for module varfiles. These are located at or under the module root, and take precedence over module variables (thus having the second-highest precedence behind CLI vars). The path to the module varfile is set via the optional `module.varfile` field. Also fixed an issue where CLI variables were overridden by module variables. CLI variables now correctly have the highest precedence. --- core/src/config/base.ts | 1 + core/src/config/module.ts | 17 +++ core/src/config/project.ts | 40 +++-- core/src/garden.ts | 9 +- core/src/resolve-module.ts | 45 ++++-- .../garden.module-a.default.env | 2 + .../module-varfiles/garden.project.env | 4 + .../test-projects/module-varfiles/garden.yml | 20 +++ .../src/plugins/kubernetes/helm/config.ts | 3 +- core/test/unit/src/config/base.ts | 4 + core/test/unit/src/garden.ts | 22 ++- core/test/unit/src/vcs/vcs.ts | 2 +- docs/reference/commands.md | 55 +++++++ docs/reference/module-template-config.md | 48 ++++++ docs/reference/module-types/configmap.md | 45 ++++++ docs/reference/module-types/conftest.md | 45 ++++++ docs/reference/module-types/container.md | 45 ++++++ docs/reference/module-types/exec.md | 45 ++++++ docs/reference/module-types/hadolint.md | 45 ++++++ docs/reference/module-types/helm.md | 45 ++++++ docs/reference/module-types/jib-container.md | 45 ++++++ docs/reference/module-types/kubernetes.md | 45 ++++++ .../reference/module-types/maven-container.md | 45 ++++++ docs/reference/module-types/openfaas.md | 45 ++++++ .../module-types/persistentvolumeclaim.md | 45 ++++++ docs/reference/module-types/templated.md | 47 +++++- docs/reference/module-types/terraform.md | 45 ++++++ docs/using-garden/variables-and-templating.md | 140 ++++++++++++------ 28 files changed, 922 insertions(+), 77 deletions(-) create mode 100644 core/test/data/test-projects/module-varfiles/garden.module-a.default.env create mode 100644 core/test/data/test-projects/module-varfiles/garden.project.env create mode 100644 core/test/data/test-projects/module-varfiles/garden.yml diff --git a/core/src/config/base.ts b/core/src/config/base.ts index 107f1a8ac8..f37071d17c 100644 --- a/core/src/config/base.ts +++ b/core/src/config/base.ts @@ -187,6 +187,7 @@ export function prepareModuleResource(spec: any, configPath: string, projectRoot type: spec.type, taskConfigs: [], variables: spec.variables, + varfile: spec.varfile, } validateWithPath({ diff --git a/core/src/config/module.ts b/core/src/config/module.ts index d124af5f56..df41b45490 100644 --- a/core/src/config/module.ts +++ b/core/src/config/module.ts @@ -23,6 +23,7 @@ import { TestConfig, testConfigSchema } from "./test" import { TaskConfig, taskConfigSchema } from "./task" import { dedent, stableStringify } from "../util/string" import { templateKind } from "./module-template" +import { varfileDescription } from "./project" export const defaultBuildTimeout = 1200 @@ -91,6 +92,7 @@ interface ModuleSpecCommon { repositoryUrl?: string type: string variables?: DeepPrimitiveMap + varfile?: string } export interface AddModuleSpec extends ModuleSpecCommon { @@ -230,6 +232,21 @@ export const baseModuleSpecKeys = () => ({ variables: joiVariables().default(() => undefined).description(dedent` A map of variables scoped to this particular module. These are resolved before any other parts of the module configuration and take precedence over project-scoped variables. They may reference project-scoped variables, and generally use any template strings normally allowed when resolving modules. `), + varfile: joi + .posixPath() + .description( + dedent` + Specify a path (relative to the module root) to a file containing variables, that we apply on top of the + module-level \`variables\` field. + + ${varfileDescription} + + To use different module-level varfiles in different environments, you can template in the environment name + to the varfile name, e.g. \`varfile: "my-module.\$\{environment.name\}.env\` (this assumes that the corresponding + varfiles exist). + ` + ) + .example("my-module.env"), }) export const baseModuleSpecSchema = () => coreModuleSpecSchema().keys(baseModuleSpecKeys()) diff --git a/core/src/config/project.ts b/core/src/config/project.ts index 94b5acf3df..509297b515 100644 --- a/core/src/config/project.ts +++ b/core/src/config/project.ts @@ -63,7 +63,7 @@ export interface EnvironmentConfig { production?: boolean } -const varfileDescription = ` +export const varfileDescription = ` The format of the files is determined by the configured file's extension: * \`.env\` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). @@ -492,8 +492,12 @@ export function resolveProjectConfig({ * For project variables, we apply the variables specified to the selected environment on the global variables * specified on the top-level `variables` key using a JSON Merge Patch (https://tools.ietf.org/html/rfc7396). * We also attempt to load the configured varfiles, and include those in the merge. The precedence order is as follows: + * * environment.varfile > environment.variables > project.varfile > project.variables * + * Variables passed through the `--var` CLI option have the highest precedence, and are merged in later in the flow + * (see `resolveGardenParams`). + * * For provider configuration, we filter down to the providers that are enabled for all environments (no `environments` * key specified) and those that explicitly list the specified environments. Then we merge any provider configs with * the same provider name, again using JSON Merge Patching, with later entries in the list taking precedence over @@ -543,7 +547,11 @@ export async function pickEnvironment({ }) } - const projectVarfileVars = await loadVarfile(projectConfig.path, projectConfig.varfile, defaultVarfilePath) + const projectVarfileVars = await loadVarfile({ + configRoot: projectConfig.path, + path: projectConfig.varfile, + defaultPath: defaultVarfilePath, + }) const projectVariables: DeepPrimitiveMap = merge(projectConfig.variables, projectVarfileVars) const envProviders = environmentConfig.providers || [] @@ -593,11 +601,11 @@ export async function pickEnvironment({ } } - const envVarfileVars = await loadVarfile( - projectConfig.path, - environmentConfig.varfile, - defaultEnvVarfilePath(environment) - ) + const envVarfileVars = await loadVarfile({ + configRoot: projectConfig.path, + path: environmentConfig.varfile, + defaultPath: defaultEnvVarfilePath(environment), + }) const variables: DeepPrimitiveMap = merge(projectVariables, merge(environmentConfig.variables, envVarfileVars)) @@ -653,8 +661,20 @@ export function parseEnvironment(env: string): ParsedEnvironment { } } -async function loadVarfile(projectRoot: string, path: string | undefined, defaultPath: string): Promise { - const resolvedPath = resolve(projectRoot, path || defaultPath) +export async function loadVarfile({ + configRoot, + path, + defaultPath, +}: { + // project root (when resolving project config) or module root (when resolving module config) + configRoot: string + path: string | undefined + defaultPath: string | undefined +}): Promise { + if (!path && !defaultPath) { + throw new ParameterError(`Neither a path nor a defaultPath was provided.`, { configRoot, path, defaultPath }) + } + const resolvedPath = resolve(configRoot, (path || defaultPath)) const exists = await pathExists(resolvedPath) if (!exists && path && path !== defaultPath) { @@ -670,7 +690,7 @@ async function loadVarfile(projectRoot: string, path: string | undefined, defaul try { const data = await readFile(resolvedPath) - const relPath = relative(projectRoot, resolvedPath) + const relPath = relative(configRoot, resolvedPath) const filename = basename(resolvedPath.toLowerCase()) if (filename.endsWith(".json")) { diff --git a/core/src/garden.ts b/core/src/garden.ts index d3f71a587b..bab51ae98e 100644 --- a/core/src/garden.ts +++ b/core/src/garden.ts @@ -174,6 +174,7 @@ export interface GardenParams { projectSources?: SourceConfig[] providerConfigs: GenericProviderConfig[] variables: DeepPrimitiveMap + cliVariables: DeepPrimitiveMap secrets: StringMap sessionId: string username: string | undefined @@ -215,6 +216,9 @@ export class Garden { public readonly environmentConfigs: EnvironmentConfig[] public readonly namespace: string public readonly variables: DeepPrimitiveMap + // Any variables passed via the `--var` CLI option (maintained here so that they can be used during module resolution + // to override module variables and module varfiles). + public readonly cliVariables: DeepPrimitiveMap public readonly secrets: StringMap private readonly projectSources: SourceConfig[] public readonly buildStaging: BuildStaging @@ -257,6 +261,7 @@ export class Garden { this.projectSources = params.projectSources || [] this.providerConfigs = params.providerConfigs this.variables = params.variables + this.cliVariables = params.cliVariables this.secrets = params.secrets this.workingCopyId = params.workingCopyId this.dotIgnoreFiles = params.dotIgnoreFiles @@ -1321,7 +1326,8 @@ export async function resolveGardenParams(currentDirectory: string, opts: Garden }) // Allow overriding variables - variables = { ...variables, ...(opts.variables || {}) } + const cliVariables = opts.variables || {} + variables = { ...variables, ...cliVariables } // Use the legacy build sync mode if // A) GARDEN_LEGACY_BUILD_STAGE=true is set or @@ -1356,6 +1362,7 @@ export async function resolveGardenParams(currentDirectory: string, opts: Garden environmentConfigs: config.environments, namespace, variables, + cliVariables, secrets, projectSources, buildStaging: buildDir, diff --git a/core/src/resolve-module.ts b/core/src/resolve-module.ts index 6fd9c98a73..c9a4fce0b2 100644 --- a/core/src/resolve-module.ts +++ b/core/src/resolve-module.ts @@ -23,7 +23,7 @@ import { getModuleTypeBases } from "./plugins" import { ModuleConfig, moduleConfigSchema } from "./config/module" import { Profile } from "./util/profiling" import { getLinkedSources } from "./util/ext-source-util" -import { allowUnknown } from "./config/common" +import { allowUnknown, DeepPrimitiveMap } from "./config/common" import { ProviderMap } from "./config/provider" import { RuntimeContext } from "./runtime-context" import chalk from "chalk" @@ -33,6 +33,8 @@ import { readFile, mkdirp, writeFile } from "fs-extra" import { LogEntry } from "./logger/log-entry" import { ModuleConfigContext, ModuleConfigContextParams } from "./config/template-contexts/module" import { pathToCacheContext } from "./cache" +import { loadVarfile } from "./config/project" +import { merge } from "json-merge-patch" // This limit is fairly arbitrary, but we need to have some cap on concurrent processing. export const moduleResolutionConcurrencyLimit = 40 @@ -279,13 +281,8 @@ export class ModuleResolver { config.inputs = inputs } - // Resolve the variables field before resolving everything else - const rawVariables = config.variables - const resolvedVariables = resolveTemplateStrings( - cloneDeep(rawVariables || {}), - new ModuleConfigContext(templateContextParams), - { allowPartial: false } - ) + // Resolve the variables field before resolving everything else (overriding with module varfiles if present) + const resolvedModuleVariables = await this.resolveVariables(config, templateContextParams) // Now resolve just references to inputs on the config config = resolveTemplateStrings(cloneDeep(config), new GenericContext({ inputs }), { @@ -296,14 +293,14 @@ export class ModuleResolver { const configContext = new ModuleConfigContext({ ...templateContextParams, moduleConfig: config, - variables: { ...garden.variables, ...resolvedVariables }, + variables: { ...garden.variables, ...resolvedModuleVariables }, }) config = resolveTemplateStrings({ ...config, inputs: {}, variables: {} }, configContext, { allowPartial: false, }) - config.variables = rawVariables ? resolvedVariables : undefined + config.variables = resolvedModuleVariables config.inputs = inputs const moduleTypeDefinitions = await garden.getModuleTypes() @@ -509,9 +506,35 @@ export class ModuleResolver { }) } } - return module } + + /** + * Resolves module variables with the following precedence order: + * + * garden.cliVariables > module varfile > config.variables + */ + private async resolveVariables( + config: ModuleConfig, + templateContextParams: ModuleConfigContextParams + ): Promise { + const moduleConfigContext = new ModuleConfigContext(templateContextParams) + const resolveOpts = { allowPartial: false } + let varfileVars: DeepPrimitiveMap = {} + if (config.varfile) { + const varfilePath = resolveTemplateString(config.varfile, moduleConfigContext, resolveOpts) + varfileVars = await loadVarfile({ + configRoot: config.path, + path: varfilePath, + defaultPath: undefined, + }) + } + + const rawVariables = config.variables + const moduleVariables = resolveTemplateStrings(cloneDeep(rawVariables || {}), moduleConfigContext, resolveOpts) + const mergedVariables: DeepPrimitiveMap = merge(moduleVariables, merge(varfileVars, this.garden.cliVariables)) + return mergedVariables + } } export interface ModuleConfigResolveOpts extends ContextResolveOpts { diff --git a/core/test/data/test-projects/module-varfiles/garden.module-a.default.env b/core/test/data/test-projects/module-varfiles/garden.module-a.default.env new file mode 100644 index 0000000000..3e9a45ab8b --- /dev/null +++ b/core/test/data/test-projects/module-varfiles/garden.module-a.default.env @@ -0,0 +1,2 @@ +c=from-module-varfile +d=from-module-varfile diff --git a/core/test/data/test-projects/module-varfiles/garden.project.env b/core/test/data/test-projects/module-varfiles/garden.project.env new file mode 100644 index 0000000000..b7ab999488 --- /dev/null +++ b/core/test/data/test-projects/module-varfiles/garden.project.env @@ -0,0 +1,4 @@ +a=from-project-varfile +b=from-project-varfile +c=from-project-varfile +d=from-project-varfile diff --git a/core/test/data/test-projects/module-varfiles/garden.yml b/core/test/data/test-projects/module-varfiles/garden.yml new file mode 100644 index 0000000000..9cc34f92a7 --- /dev/null +++ b/core/test/data/test-projects/module-varfiles/garden.yml @@ -0,0 +1,20 @@ +kind: Project +name: module-varfiles +varfile: garden.project.env +environments: + - name: default +providers: + - name: test-plugin + +--- + +kind: Module +name: module-a +type: test +varfile: "garden.module-a.${environment.name}.env" +variables: + b: from-module-vars + c: from-module-vars # should be overridden by module-level varfile + d: from-module-vars # should be overridden by var passed as a CLI option +build: + command: [echo, A] diff --git a/core/test/integ/src/plugins/kubernetes/helm/config.ts b/core/test/integ/src/plugins/kubernetes/helm/config.ts index e37d79ed34..dc90c8b59e 100644 --- a/core/test/integ/src/plugins/kubernetes/helm/config.ts +++ b/core/test/integ/src/plugins/kubernetes/helm/config.ts @@ -119,7 +119,8 @@ describe("configureHelmModule", () => { testConfigs: [], type: "helm", taskConfigs: [], - variables: undefined, + variables: {}, + varfile: undefined, }) }) diff --git a/core/test/unit/src/config/base.ts b/core/test/unit/src/config/base.ts index 941250dbae..aa3d65c9bd 100644 --- a/core/test/unit/src/config/base.ts +++ b/core/test/unit/src/config/base.ts @@ -133,6 +133,7 @@ describe("loadConfigResources", () => { build: { dependencies: [] }, path: modulePathA, variables: { msg: "OK" }, + varfile: undefined, spec: { build: { @@ -276,6 +277,7 @@ describe("loadConfigResources", () => { testConfigs: [], taskConfigs: [], variables: undefined, + varfile: undefined, }, ]) }) @@ -315,6 +317,7 @@ describe("loadConfigResources", () => { testConfigs: [], taskConfigs: [], variables: undefined, + varfile: undefined, }, { apiVersion: "garden.io/v0", @@ -344,6 +347,7 @@ describe("loadConfigResources", () => { testConfigs: [], taskConfigs: [], variables: undefined, + varfile: undefined, }, ]) }) diff --git a/core/test/unit/src/garden.ts b/core/test/unit/src/garden.ts index 1928771394..f3f4564cf8 100644 --- a/core/test/unit/src/garden.ts +++ b/core/test/unit/src/garden.ts @@ -271,6 +271,22 @@ describe("Garden", () => { }) }) + it("should respect the module variables < module varfile < CLI var precedence order", async () => { + const projectRoot = join(dataDir, "test-projects", "module-varfiles") + + const garden = await makeTestGarden(projectRoot) + // In the normal flow, `garden.cliVariables` is populated with variables passed via the `--var` CLI option. + garden.cliVariables["d"] = "from-cli-var" + const graph = await garden.getConfigGraph({ log: garden.log, emit: false }) + const module = graph.getModule("module-a") + expect({ ...garden.variables, ...module.variables }).to.eql({ + a: "from-project-varfile", + b: "from-module-vars", + c: "from-module-varfile", + d: "from-cli-var", + }) + }) + it("should throw if project root is not in a git repo root", async () => { const dir = await tmp.dir({ unsafeCleanup: true }) @@ -4462,9 +4478,9 @@ describe("Garden", () => { }) context("test against fixed version hashes", async () => { - const moduleAVersionString = "v-f6743d2423" - const moduleBVersionString = "v-97a77e8414" - const moduleCVersionString = "v-afb847fa9a" + const moduleAVersionString = "v-3b072717eb" + const moduleBVersionString = "v-b9e3153900" + const moduleCVersionString = "v-371a6bbdec" it("should return the same module versions between runtimes", async () => { const projectRoot = getDataDir("test-projects", "fixed-version-hashes-1") diff --git a/core/test/unit/src/vcs/vcs.ts b/core/test/unit/src/vcs/vcs.ts index 01654fd68d..b7ceaa94e5 100644 --- a/core/test/unit/src/vcs/vcs.ts +++ b/core/test/unit/src/vcs/vcs.ts @@ -423,7 +423,7 @@ describe("getModuleVersionString", () => { const garden = await makeTestGarden(projectRoot) const module = await garden.resolveModule("module-a") - const fixedVersionString = "v-f6743d2423" + const fixedVersionString = "v-3b072717eb" expect(module.version.versionString).to.eql(fixedVersionString) delete process.env.TEST_ENV_VAR diff --git a/docs/reference/commands.md b/docs/reference/commands.md index 8f242446e3..7e5bd00114 100644 --- a/docs/reference/commands.md +++ b/docs/reference/commands.md @@ -1367,6 +1367,25 @@ providers: variables: : + # Specify a path (relative to the module root) to a file containing variables, that we apply on top of the + # module-level `variables` field. + # + # The format of the files is determined by the configured file's extension: + # + # * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). + # * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys + # may contain any value type. + # * `.json` - JSON. Must contain a single JSON _object_ (not an array). + # + # _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of + # nested objects and arrays._ + # + # To use different module-level varfiles in different environments, you can template in the environment name + # to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the + # corresponding + # varfiles exist). + varfile: + # The filesystem path of the module. path: @@ -1647,6 +1666,24 @@ moduleConfigs: variables: : + # Specify a path (relative to the module root) to a file containing variables, that we apply on top of the + # module-level `variables` field. + # + # The format of the files is determined by the configured file's extension: + # + # * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). + # * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may + # contain any value type. + # * `.json` - JSON. Must contain a single JSON _object_ (not an array). + # + # _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of + # nested objects and arrays._ + # + # To use different module-level varfiles in different environments, you can template in the environment name + # to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding + # varfiles exist). + varfile: + # The filesystem path of the module. path: @@ -2159,6 +2196,24 @@ modules: variables: : + # Specify a path (relative to the module root) to a file containing variables, that we apply on top of the + # module-level `variables` field. + # + # The format of the files is determined by the configured file's extension: + # + # * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). + # * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may + # contain any value type. + # * `.json` - JSON. Must contain a single JSON _object_ (not an array). + # + # _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of + # nested objects and arrays._ + # + # To use different module-level varfiles in different environments, you can template in the environment name + # to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding + # varfiles exist). + varfile: + # The filesystem path of the module. path: diff --git a/docs/reference/module-template-config.md b/docs/reference/module-template-config.md index 999ac3d3f6..47522c99ee 100644 --- a/docs/reference/module-template-config.md +++ b/docs/reference/module-template-config.md @@ -160,6 +160,24 @@ modules: # and generally use any template strings normally allowed when resolving modules. variables: + # Specify a path (relative to the module root) to a file containing variables, that we apply on top of the + # module-level `variables` field. + # + # The format of the files is determined by the configured file's extension: + # + # * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). + # * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may + # contain any value type. + # * `.json` - JSON. Must contain a single JSON _object_ (not an array). + # + # _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of + # nested objects and arrays._ + # + # To use different module-level varfiles in different environments, you can template in the environment name + # to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding + # varfiles exist). + varfile: + # POSIX-style path of a sub-directory to set as the module root. If the directory does not exist, it is # automatically created. path: @@ -505,6 +523,36 @@ A map of variables scoped to this particular module. These are resolved before a | -------- | -------- | | `object` | No | +### `modules[].varfile` + +[modules](#modules) > varfile + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +modules: + - varfile: "my-module.env" +``` + ### `modules[].path` [modules](#modules) > path diff --git a/docs/reference/module-types/configmap.md b/docs/reference/module-types/configmap.md index f563a92741..596d398930 100644 --- a/docs/reference/module-types/configmap.md +++ b/docs/reference/module-types/configmap.md @@ -135,6 +135,24 @@ generateFiles: # generally use any template strings normally allowed when resolving modules. variables: +# Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +# module-level `variables` field. +# +# The format of the files is determined by the configured file's extension: +# +# * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +# * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may +# contain any value type. +# * `.json` - JSON. Must contain a single JSON _object_ (not an array). +# +# _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested +# objects and arrays._ +# +# To use different module-level varfiles in different environments, you can template in the environment name +# to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +# varfiles exist). +varfile: + # List of services and tasks to deploy/run before deploying this ConfigMap. dependencies: [] @@ -411,6 +429,33 @@ A map of variables scoped to this particular module. These are resolved before a | -------- | -------- | | `object` | No | +### `varfile` + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +varfile: "my-module.env" +``` + ### `dependencies[]` List of services and tasks to deploy/run before deploying this ConfigMap. diff --git a/docs/reference/module-types/conftest.md b/docs/reference/module-types/conftest.md index 6aa7b2b646..a83e72f55d 100644 --- a/docs/reference/module-types/conftest.md +++ b/docs/reference/module-types/conftest.md @@ -138,6 +138,24 @@ generateFiles: # generally use any template strings normally allowed when resolving modules. variables: +# Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +# module-level `variables` field. +# +# The format of the files is determined by the configured file's extension: +# +# * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +# * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may +# contain any value type. +# * `.json` - JSON. Must contain a single JSON _object_ (not an array). +# +# _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested +# objects and arrays._ +# +# To use different module-level varfiles in different environments, you can template in the environment name +# to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +# varfiles exist). +varfile: + # Specify a module whose sources we want to test. sourceModule: @@ -422,6 +440,33 @@ A map of variables scoped to this particular module. These are resolved before a | -------- | -------- | | `object` | No | +### `varfile` + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +varfile: "my-module.env" +``` + ### `sourceModule` Specify a module whose sources we want to test. diff --git a/docs/reference/module-types/container.md b/docs/reference/module-types/container.md index ac9c600098..2ef4a64dc2 100644 --- a/docs/reference/module-types/container.md +++ b/docs/reference/module-types/container.md @@ -150,6 +150,24 @@ generateFiles: # generally use any template strings normally allowed when resolving modules. variables: +# Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +# module-level `variables` field. +# +# The format of the files is determined by the configured file's extension: +# +# * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +# * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may +# contain any value type. +# * `.json` - JSON. Must contain a single JSON _object_ (not an array). +# +# _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested +# objects and arrays._ +# +# To use different module-level varfiles in different environments, you can template in the environment name +# to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +# varfiles exist). +varfile: + # Specify build arguments to use when building the container image. # # Note: Garden will always set a `GARDEN_MODULE_VERSION` argument with the module version at build time. @@ -940,6 +958,33 @@ A map of variables scoped to this particular module. These are resolved before a | -------- | -------- | | `object` | No | +### `varfile` + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +varfile: "my-module.env" +``` + ### `buildArgs` Specify build arguments to use when building the container image. diff --git a/docs/reference/module-types/exec.md b/docs/reference/module-types/exec.md index 03e5d90630..7e0574adec 100644 --- a/docs/reference/module-types/exec.md +++ b/docs/reference/module-types/exec.md @@ -148,6 +148,24 @@ generateFiles: # generally use any template strings normally allowed when resolving modules. variables: +# Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +# module-level `variables` field. +# +# The format of the files is determined by the configured file's extension: +# +# * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +# * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may +# contain any value type. +# * `.json` - JSON. Must contain a single JSON _object_ (not an array). +# +# _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested +# objects and arrays._ +# +# To use different module-level varfiles in different environments, you can template in the environment name +# to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +# varfiles exist). +varfile: + # If set to true, Garden will run the build command, services, tests, and tasks in the module source directory, # instead of in the Garden build directory (under .garden/build/). # @@ -581,6 +599,33 @@ A map of variables scoped to this particular module. These are resolved before a | -------- | -------- | | `object` | No | +### `varfile` + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +varfile: "my-module.env" +``` + ### `local` If set to true, Garden will run the build command, services, tests, and tasks in the module source directory, diff --git a/docs/reference/module-types/hadolint.md b/docs/reference/module-types/hadolint.md index 0193460b78..c925ecbbee 100644 --- a/docs/reference/module-types/hadolint.md +++ b/docs/reference/module-types/hadolint.md @@ -141,6 +141,24 @@ generateFiles: # generally use any template strings normally allowed when resolving modules. variables: +# Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +# module-level `variables` field. +# +# The format of the files is determined by the configured file's extension: +# +# * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +# * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may +# contain any value type. +# * `.json` - JSON. Must contain a single JSON _object_ (not an array). +# +# _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested +# objects and arrays._ +# +# To use different module-level varfiles in different environments, you can template in the environment name +# to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +# varfiles exist). +varfile: + # POSIX-style path to a Dockerfile that you want to lint with `hadolint`. dockerfilePath: ``` @@ -410,6 +428,33 @@ A map of variables scoped to this particular module. These are resolved before a | -------- | -------- | | `object` | No | +### `varfile` + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +varfile: "my-module.env" +``` + ### `dockerfilePath` POSIX-style path to a Dockerfile that you want to lint with `hadolint`. diff --git a/docs/reference/module-types/helm.md b/docs/reference/module-types/helm.md index 911716bad0..9825764d1b 100644 --- a/docs/reference/module-types/helm.md +++ b/docs/reference/module-types/helm.md @@ -140,6 +140,24 @@ generateFiles: # generally use any template strings normally allowed when resolving modules. variables: +# Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +# module-level `variables` field. +# +# The format of the files is determined by the configured file's extension: +# +# * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +# * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may +# contain any value type. +# * `.json` - JSON. Must contain a single JSON _object_ (not an array). +# +# _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested +# objects and arrays._ +# +# To use different module-level varfiles in different environments, you can template in the environment name +# to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +# varfiles exist). +varfile: + # Whether to set the --atomic flag during installs and upgrades. Set to false if e.g. you want to see more information # about failures and then manually roll back, instead of having Helm do it automatically on failure. atomicInstall: true @@ -822,6 +840,33 @@ A map of variables scoped to this particular module. These are resolved before a | -------- | -------- | | `object` | No | +### `varfile` + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +varfile: "my-module.env" +``` + ### `atomicInstall` Whether to set the --atomic flag during installs and upgrades. Set to false if e.g. you want to see more information about failures and then manually roll back, instead of having Helm do it automatically on failure. diff --git a/docs/reference/module-types/jib-container.md b/docs/reference/module-types/jib-container.md index 6ec36bac00..3020883723 100644 --- a/docs/reference/module-types/jib-container.md +++ b/docs/reference/module-types/jib-container.md @@ -171,6 +171,24 @@ generateFiles: # generally use any template strings normally allowed when resolving modules. variables: +# Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +# module-level `variables` field. +# +# The format of the files is determined by the configured file's extension: +# +# * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +# * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may +# contain any value type. +# * `.json` - JSON. Must contain a single JSON _object_ (not an array). +# +# _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested +# objects and arrays._ +# +# To use different module-level varfiles in different environments, you can template in the environment name +# to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +# varfiles exist). +varfile: + # Specify build arguments to use when building the container image. # # Note: Garden will always set a `GARDEN_MODULE_VERSION` argument with the module version at build time. @@ -1011,6 +1029,33 @@ A map of variables scoped to this particular module. These are resolved before a | -------- | -------- | | `object` | No | +### `varfile` + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +varfile: "my-module.env" +``` + ### `buildArgs` Specify build arguments to use when building the container image. diff --git a/docs/reference/module-types/kubernetes.md b/docs/reference/module-types/kubernetes.md index c2d5ddc96b..02305c097a 100644 --- a/docs/reference/module-types/kubernetes.md +++ b/docs/reference/module-types/kubernetes.md @@ -144,6 +144,24 @@ generateFiles: # generally use any template strings normally allowed when resolving modules. variables: +# Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +# module-level `variables` field. +# +# The format of the files is determined by the configured file's extension: +# +# * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +# * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may +# contain any value type. +# * `.json` - JSON. Must contain a single JSON _object_ (not an array). +# +# _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested +# objects and arrays._ +# +# To use different module-level varfiles in different environments, you can template in the environment name +# to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +# varfiles exist). +varfile: + # The names of any services that this service depends on at runtime, and the names of any tasks that should be # executed before this service is deployed. dependencies: [] @@ -751,6 +769,33 @@ A map of variables scoped to this particular module. These are resolved before a | -------- | -------- | | `object` | No | +### `varfile` + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +varfile: "my-module.env" +``` + ### `dependencies[]` The names of any services that this service depends on at runtime, and the names of any tasks that should be executed before this service is deployed. diff --git a/docs/reference/module-types/maven-container.md b/docs/reference/module-types/maven-container.md index 31d7544946..928edf36ce 100644 --- a/docs/reference/module-types/maven-container.md +++ b/docs/reference/module-types/maven-container.md @@ -150,6 +150,24 @@ generateFiles: # generally use any template strings normally allowed when resolving modules. variables: +# Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +# module-level `variables` field. +# +# The format of the files is determined by the configured file's extension: +# +# * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +# * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may +# contain any value type. +# * `.json` - JSON. Must contain a single JSON _object_ (not an array). +# +# _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested +# objects and arrays._ +# +# To use different module-level varfiles in different environments, you can template in the environment name +# to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +# varfiles exist). +varfile: + # Specify build arguments to use when building the container image. # # Note: Garden will always set a `GARDEN_MODULE_VERSION` argument with the module version at build time. @@ -950,6 +968,33 @@ A map of variables scoped to this particular module. These are resolved before a | -------- | -------- | | `object` | No | +### `varfile` + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +varfile: "my-module.env" +``` + ### `buildArgs` Specify build arguments to use when building the container image. diff --git a/docs/reference/module-types/openfaas.md b/docs/reference/module-types/openfaas.md index 711f8fb0a7..6cea939bb5 100644 --- a/docs/reference/module-types/openfaas.md +++ b/docs/reference/module-types/openfaas.md @@ -134,6 +134,24 @@ generateFiles: # generally use any template strings normally allowed when resolving modules. variables: +# Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +# module-level `variables` field. +# +# The format of the files is determined by the configured file's extension: +# +# * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +# * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may +# contain any value type. +# * `.json` - JSON. Must contain a single JSON _object_ (not an array). +# +# _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested +# objects and arrays._ +# +# To use different module-level varfiles in different environments, you can template in the environment name +# to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +# varfiles exist). +varfile: + # The names of services/functions that this function depends on at runtime. dependencies: [] @@ -441,6 +459,33 @@ A map of variables scoped to this particular module. These are resolved before a | -------- | -------- | | `object` | No | +### `varfile` + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +varfile: "my-module.env" +``` + ### `dependencies[]` The names of services/functions that this function depends on at runtime. diff --git a/docs/reference/module-types/persistentvolumeclaim.md b/docs/reference/module-types/persistentvolumeclaim.md index 850e654bcc..222d823656 100644 --- a/docs/reference/module-types/persistentvolumeclaim.md +++ b/docs/reference/module-types/persistentvolumeclaim.md @@ -135,6 +135,24 @@ generateFiles: # generally use any template strings normally allowed when resolving modules. variables: +# Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +# module-level `variables` field. +# +# The format of the files is determined by the configured file's extension: +# +# * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +# * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may +# contain any value type. +# * `.json` - JSON. Must contain a single JSON _object_ (not an array). +# +# _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested +# objects and arrays._ +# +# To use different module-level varfiles in different environments, you can template in the environment name +# to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +# varfiles exist). +varfile: + # List of services and tasks to deploy/run before deploying this PVC. dependencies: [] @@ -463,6 +481,33 @@ A map of variables scoped to this particular module. These are resolved before a | -------- | -------- | | `object` | No | +### `varfile` + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +varfile: "my-module.env" +``` + ### `dependencies[]` List of services and tasks to deploy/run before deploying this PVC. diff --git a/docs/reference/module-types/templated.md b/docs/reference/module-types/templated.md index 14c056e859..33629ec3f3 100644 --- a/docs/reference/module-types/templated.md +++ b/docs/reference/module-types/templated.md @@ -12,7 +12,7 @@ A special module type, for rendering [module templates](../../using-garden/modul Specify the name of a ModuleTemplate with the `template` field, and provide any expected inputs using the `inputs` field. The generated modules becomes sub-modules of this module. Note that the following common Module configuration fields are disallowed for this module type: -`build`, `description`, `include`, `exclude`, `repositoryUrl`, `allowPublish`, `generateFiles` and `variables` +`build`, `description`, `include`, `exclude`, `repositoryUrl`, `allowPublish`, `generateFiles`, `variables` and `varfile` Below is the full schema reference. For an introduction to configuring Garden modules, please look at our [Configuration guide](../../using-garden/configuration-overview.md). @@ -138,6 +138,24 @@ generateFiles: # generally use any template strings normally allowed when resolving modules. variables: +# Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +# module-level `variables` field. +# +# The format of the files is determined by the configured file's extension: +# +# * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +# * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may +# contain any value type. +# * `.json` - JSON. Must contain a single JSON _object_ (not an array). +# +# _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested +# objects and arrays._ +# +# To use different module-level varfiles in different environments, you can template in the environment name +# to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +# varfiles exist). +varfile: + # The ModuleTemplate to use to generate the sub-modules of this module. template: @@ -416,6 +434,33 @@ A map of variables scoped to this particular module. These are resolved before a | -------- | -------- | | `object` | No | +### `varfile` + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +varfile: "my-module.env" +``` + ### `template` The ModuleTemplate to use to generate the sub-modules of this module. diff --git a/docs/reference/module-types/terraform.md b/docs/reference/module-types/terraform.md index eb697dc205..80f0c8e9f8 100644 --- a/docs/reference/module-types/terraform.md +++ b/docs/reference/module-types/terraform.md @@ -143,6 +143,24 @@ generateFiles: # specified here take precedence. variables: +# Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +# module-level `variables` field. +# +# The format of the files is determined by the configured file's extension: +# +# * `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +# * `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may +# contain any value type. +# * `.json` - JSON. Must contain a single JSON _object_ (not an array). +# +# _NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested +# objects and arrays._ +# +# To use different module-level varfiles in different environments, you can template in the environment name +# to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +# varfiles exist). +varfile: + # If set to true, Garden will run `terraform destroy` on the stack when calling `garden delete env` or `garden delete # service `. allowDestroy: false @@ -440,6 +458,33 @@ specified here take precedence. | -------- | -------- | | `object` | No | +### `varfile` + +Specify a path (relative to the module root) to a file containing variables, that we apply on top of the +module-level `variables` field. + +The format of the files is determined by the configured file's extension: + +* `.env` - Standard "dotenv" format, as defined by [dotenv](https://github.com/motdotla/dotenv#rules). +* `.yaml`/`.yml` - YAML. The file must consist of a YAML document, which must be a map (dictionary). Keys may contain any value type. +* `.json` - JSON. Must contain a single JSON _object_ (not an array). + +_NOTE: The default varfile format will change to YAML in Garden v0.13, since YAML allows for definition of nested objects and arrays._ + +To use different module-level varfiles in different environments, you can template in the environment name +to the varfile name, e.g. `varfile: "my-module.\$\{environment.name\}.env` (this assumes that the corresponding +varfiles exist). + +| Type | Required | +| ----------- | -------- | +| `posixPath` | No | + +Example: + +```yaml +varfile: "my-module.env" +``` + ### `allowDestroy` If set to true, Garden will run `terraform destroy` on the stack when calling `garden delete env` or `garden delete service `. diff --git a/docs/using-garden/variables-and-templating.md b/docs/using-garden/variables-and-templating.md index f5deb93f94..ad0e3c8fb3 100644 --- a/docs/using-garden/variables-and-templating.md +++ b/docs/using-garden/variables-and-templating.md @@ -446,14 +446,93 @@ services: env: ${var.envVars} # <- resolves to the whole envVars object ``` +## Module variables + +Each Garden module can specify its own set of variables that can be re-used within the module, and referenced by other dependant modules via template strings. + +Simply specify the `variables` field on the module, same as in the project configuration. For example: + +```yaml +# my-service/garden.yml +kind: Module +name: my-service +variables: + # This overrides the project-level hostname variable + hostname: my-service.${var.hostname} + # You can specify maps or lists as variables + envVars: + LOG_LEVEL: debug + DATABASE_PASSWORD: ${var.database-password} +services: + - name: my-service + ... + ingresses: + - path: / + port: http + # This resolves to the hostname variable set above, not the project-level hostname variable + hostname: ${var.hostname} + # Referencing the above envVar module variable + env: ${var.envVars} +tests: + - name: my-test + ... + # Re-using the envVar module variable + env: ${var.envVars} +``` + +Notice that you can override variables defined at the project-level, and even reference project-scoped variables when defining the module variables. + +Also notice the generally handy use-case of re-using a common value (in this case a map of environment variables) in multiple spots in the module configuration. + +### Referencing module variables + +On top of that, you can reference the resolved module variables in other modules. With the above example, another module might for example reference `${modules.my-service.var.hostname}`. For larger projects this can be much cleaner than, say, hoisting a lot of variables up to the project level. + ### Variable files (varfiles) -You can also provide variables using "variable files" or _varfiles_. These work mostly like "dotenv" files or envfiles. However, they don't implicitly affect the environment of the Garden process and the configured services, but rather are added on top of the `variables` you define in your project configuration. +You can also provide variables using "variable files" or _varfiles_. These work mostly like "dotenv" files or envfiles. However, they don't implicitly affect the environment of the Garden process and the configured services, but rather are added on top of the `variables` you define in your project configuration (or module variables defined in the `variables` of your individual module configurations). This can be very useful when you need to provide secrets and other contextual values to your stack. You could add your varfiles to your `.gitignore` file to keep them out of your repository, or use e.g. [git-crypt](https://github.com/AGWA/git-crypt), [BlackBox](https://github.com/StackExchange/blackbox) or [git-secret](https://git-secret.io/) to securely store the files in your Git repo. By default, Garden will look for a `garden.env` file in your project root for project-wide variables, and a `garden..env` file for environment-specific variables. You can override the filename for each as well. +To use a module-level varfile, simply configure the `module.varfile` field to be the relative path (from module root) to the varfile you want to use for that module. For example: +```yaml +# my-service/garden.yml +kind: Module +name: my-service +# Here, we use per-environment module varfiles as an optional override for variables (these have a higher precedence +# than those in the `variables` field below). +# +# If no varfile exists, no error is thrown (we simply don't override any variables). +varfile: my-service.${environment.name}.yaml +variables: + # This overrides the project-level hostname variable + hostname: my-service.${var.hostname} + # You can specify maps or lists as variables + envVars: + LOG_LEVEL: debug + DATABASE_PASSWORD: ${var.database-password} +services: + - name: my-service + ... + ingresses: + - path: / + port: http + # This resolves to the hostname variable set above, not the project-level hostname variable + hostname: ${var.hostname} + # Referencing the above envVar module variable + env: ${var.envVars} +tests: + - name: my-test + ... + # Re-using the envVar module variable + env: ${var.envVars} +``` +Module varfiles must be located inside the module root directory. That is, they must be in the same directory as the module configuration, or in a subdirectory of that directory. + +Note that variables defined in module varfiles override variables defined in project-level variables and varfiles (see the section on variable precedence order below). + The format of the files is determined by the configured file extension: * `.env` - Standard "dotenv" format, as supported by [dotenv](https://github.com/motdotla/dotenv#rules). @@ -475,13 +554,18 @@ garden run task my-task --var my-task-arg=foo,some-numeric-var=123 Multiple variables are separated with a comma, and each part is parsed using [dotenv](https://github.com/motdotla/dotenv#rules) syntax. -The order of precedence across the varfiles and project config fields is as follows (from highest to lowest): -1. Individual variables set with `--var` flags. -2. The environment-specific varfile (defaults to `garden..env`). -3. The environment-specific variables set in `environment[].variables`. -4. Configured project-wide varfile (defaults to `garden.env`). -5. The project-wide `variables` field. +## Variable precedence order + +The order of precedence is as follows (from highest to lowest): + +1. Individual variables set with `--var` CLI flags. +2. The module-level varfile (if configured). +3. Module variables set in `module.variables`. +4. The environment-specific varfile (defaults to `garden..env`). +5. The environment-specific variables set in `environment[].variables`. +6. Configured project-wide varfile (defaults to `garden.env`). +7. The project-wide `variables` field. {% hint style="warning" %} Note that [Module variables](#module-variables) always take precedence over any of the above, in the context of the module being resolved. @@ -522,48 +606,6 @@ services: DATABASE_PASSWORD: ${var.database-password} ``` -## Module variables - -Each Garden module can specify its own set of variables that can be re-used within the module, and referenced by other dependant modules via template strings. - -Simply specify the `variables` field on the module, same as in the project configuration. For example: - -```yaml -# my-service/garden.yml -kind: Module -name: my-service -variables: - # This overrides the project-level hostname variable - hostname: my-service.${var.hostname} - # You can specify maps or lists as variables - envVars: - LOG_LEVEL: debug - DATABASE_PASSWORD: ${var.database-password} -services: - - name: my-service - ... - ingresses: - - path: / - port: http - # This resolves to the hostname variable set above, not the project-level hostname variable - hostname: ${var.hostname} - # Referencing the above envVar module variable - env: ${var.envVars} -tests: - - name: my-test - ... - # Re-using the envVar module variable - env: ${var.envVars} -``` - -Notice that you can override variables defined at the project-level, and even reference project-scoped variables when defining the module variables. - -Also notice the generally handy use-case of re-using a common value (in this case a map of environment variables) in multiple spots in the module configuration. - -### Referencing module variables - -On top of that, you can reference the resolved module variables in other modules. With the above example, another module might for example reference `${modules.my-service.var.hostname}`. For larger projects this can be much cleaner than, say, hoisting a lot of variables up to the project level. - ## Provider outputs Providers often expose useful variables that other provider configs and modules can reference, under `${providers..outputs.}`. Each provider exposes different outputs, and some providers have dynamic output keys depending on their configuration.