/
plan.ts
116 lines (85 loc) · 3.23 KB
/
plan.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { flags } from "@oclif/command"
import chalk from "chalk"
import ux from "cli-ux"
import execa from "execa"
import BaseInfrastructureCommand from "../BaseInfrastructureCommand"
import InfrastructureFactory from "../lib/infrastructures/InfrastructureFactory"
import environmentsManager from "../lib/environments"
import getNodeEnv from "../lib/environments/getNodeEnv"
/**
* Represents the "scaffold plan {environment}" command used to plan
* the infrastructure modifications for an environment.
*/
class Plan extends BaseInfrastructureCommand {
static args = [{
name: "environment",
required: true,
}]
static description = "plan infrastructure modifications for passed environment"
static flags = {
help: flags.help({
char: "h",
}),
sandbox: flags.boolean({
default: false,
}),
}
static strict = false
async run() {
const { args, flags } = this.parse(Plan)
await this.ensureAllRequirements()
const environment: string = args.environment
const infrastructurePath = await this.infrastructurePath()
if (!infrastructurePath) {
this.error("No infrastructures found.")
}
const infrastructurePackage = await this.infrastructurePackage(infrastructurePath)
if (!infrastructurePackage) {
this.error("Invalid scaffold.json file.")
}
const infrastructure = InfrastructureFactory.infrastructure(infrastructurePackage.type)
if (!infrastructure) {
this.error("Unknown infrastructure.")
}
const environments = await environmentsManager.findAll(infrastructurePath)
if (!environments.all.includes(environment)) {
this.error(`"${chalk.bold(environment)}" environment doesn't exist.`)
}
if (!flags.sandbox) {
if (!environments.configured.includes(environment)) {
this.error(`"${chalk.bold(environment)}" environment not configured. Run "${chalk.bold(chalk.cyan("scaffold") + " env:configure " + environment)}" first.`)
}
} else if (!environments.sandboxed.includes(environment)) {
this.error(`Sandbox for "${chalk.bold(environment)}" environment doesn't exist. Run "${chalk.bold(chalk.cyan("scaffold") + " sandbox:create " + environment)}" first.`)
}
const cdktfPath = this.cdktfPath(infrastructurePath)
const terraformPlanPath = await this.terraformPlanPath(infrastructurePath)
const terraformPath = BaseInfrastructureCommand.terraformBinaryPath()
ux.action.start("Synthesizing")
await execa(cdktfPath, ["synth"], {
cwd: infrastructurePath,
env: {
NODE_ENV: getNodeEnv(environment, flags.sandbox),
},
})
await execa(terraformPath, ["init", "-reconfigure"], {
cwd: terraformPlanPath,
})
ux.action.stop()
this.log("")
// Remove ["node", "{path}", "plan", "{environment}"]
const argsToPassToTF = process.argv.slice(4).filter(arg => !["--sandbox", "-sandbox"].includes(arg))
const terraformPlan = execa(terraformPath, ["plan"].concat(argsToPassToTF), {
cwd: terraformPlanPath,
})
terraformPlan.stderr.pipe(process.stderr)
terraformPlan.stdout.pipe(process.stdout)
process.stdin.pipe(terraformPlan.stdin)
try {
await terraformPlan
} catch (error) {
this.exit(1)
}
}
}
export default Plan