Skip to content

Commit 1f1f002

Browse files
ystrosjpalermo
authored andcommitted
Pass AWS assume role ops files and variables
If the AWS assume role ARN is set, the scripts to create both the BOSH Director and jumpbox need to pass additional ops files and variables. [#184999423] Add AssumeRole support to bbl
1 parent 014d4f1 commit 1f1f002

File tree

7 files changed

+186
-76
lines changed

7 files changed

+186
-76
lines changed

bosh/executor.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ func (e Executor) getSetupFiles(sourcePath, destPath string) []setupFile {
101101
}
102102

103103
func (e Executor) PlanJumpbox(input DirInput, deploymentDir, iaas string) error {
104+
return e.PlanJumpboxWithState(input, deploymentDir, iaas, storage.State{})
105+
}
106+
107+
func (e Executor) PlanJumpboxWithState(input DirInput, deploymentDir, iaas string, state storage.State) error {
104108
setupFiles := e.getSetupFiles(jumpboxDeploymentRepo, deploymentDir)
105109

106110
for _, f := range setupFiles {
@@ -128,6 +132,12 @@ func (e Executor) PlanJumpbox(input DirInput, deploymentDir, iaas string) error
128132
}
129133
}
130134

135+
if iaas == "aws" {
136+
if state.AWS.AssumeRoleArn != "" {
137+
sharedArgs = append(sharedArgs, "-o", filepath.Join(deploymentDir, "aws", "cpi-assume-role-credentials.yml"))
138+
}
139+
}
140+
131141
jumpboxState := filepath.Join(input.VarsDir, "jumpbox-state.json")
132142

133143
boshArgs := append([]string{filepath.Join(deploymentDir, "jumpbox.yml"), "--state", jumpboxState}, sharedArgs...)
@@ -138,6 +148,11 @@ func (e Executor) PlanJumpbox(input DirInput, deploymentDir, iaas string) error
138148
"-v", `access_key_id="${BBL_AWS_ACCESS_KEY_ID}"`,
139149
"-v", `secret_access_key="${BBL_AWS_SECRET_ACCESS_KEY}"`,
140150
)
151+
if state.AWS.AssumeRoleArn != "" {
152+
boshArgs = append(boshArgs,
153+
"-v", `role_arn="${BBL_AWS_ASSUME_ROLE}"`,
154+
)
155+
}
141156
case "azure":
142157
boshArgs = append(boshArgs,
143158
"-v", `subscription_id="${BBL_AZURE_SUBSCRIPTION_ID}"`,
@@ -210,7 +225,7 @@ func (e Executor) getDirectorSetupFiles(stateDir, deploymentDir, iaas string) []
210225
return files
211226
}
212227

213-
func (e Executor) getDirectorOpsFiles(stateDir, deploymentDir, iaas string) []string {
228+
func (e Executor) getDirectorOpsFiles(stateDir, deploymentDir, iaas string, state storage.State) []string {
214229
files := []string{
215230
filepath.Join(deploymentDir, iaas, "cpi.yml"),
216231
filepath.Join(deploymentDir, "jumpbox-user.yml"),
@@ -223,13 +238,20 @@ func (e Executor) getDirectorOpsFiles(stateDir, deploymentDir, iaas string) []st
223238
files = append(files, filepath.Join(stateDir, "bbl-ops-files", iaas, "bosh-director-ephemeral-ip-ops.yml"))
224239
files = append(files, filepath.Join(deploymentDir, iaas, "iam-instance-profile.yml"))
225240
files = append(files, filepath.Join(deploymentDir, iaas, "encrypted-disk.yml"))
241+
if state.AWS.AssumeRoleArn != "" {
242+
files = append(files, filepath.Join(deploymentDir, iaas, "cpi-assume-role-credentials.yml"))
243+
}
226244
} else if iaas == "vsphere" {
227245
files = append(files, filepath.Join(deploymentDir, "vsphere", "resource-pool.yml"))
228246
}
229247
return files
230248
}
231249

232250
func (e Executor) PlanDirector(input DirInput, deploymentDir, iaas string) error {
251+
return e.PlanDirectorWithState(input, deploymentDir, iaas, storage.State{})
252+
}
253+
254+
func (e Executor) PlanDirectorWithState(input DirInput, deploymentDir, iaas string, state storage.State) error {
233255
setupFiles := e.getDirectorSetupFiles(input.StateDir, deploymentDir, iaas)
234256

235257
for _, f := range setupFiles {
@@ -246,7 +268,7 @@ func (e Executor) PlanDirector(input DirInput, deploymentDir, iaas string) error
246268
"--vars-file", filepath.Join(input.VarsDir, "director-vars-file.yml"),
247269
}
248270

249-
for _, f := range e.getDirectorOpsFiles(input.StateDir, deploymentDir, iaas) {
271+
for _, f := range e.getDirectorOpsFiles(input.StateDir, deploymentDir, iaas, state) {
250272
sharedArgs = append(sharedArgs, "-o", f)
251273
}
252274

@@ -260,6 +282,11 @@ func (e Executor) PlanDirector(input DirInput, deploymentDir, iaas string) error
260282
"-v", `access_key_id="${BBL_AWS_ACCESS_KEY_ID}"`,
261283
"-v", `secret_access_key="${BBL_AWS_SECRET_ACCESS_KEY}"`,
262284
)
285+
if state.AWS.AssumeRoleArn != "" {
286+
boshArgs = append(boshArgs,
287+
"-v", `role_arn="${BBL_AWS_ASSUME_ROLE}"`,
288+
)
289+
}
263290
case "azure":
264291
boshArgs = append(boshArgs,
265292
"-v", `subscription_id="${BBL_AZURE_SUBSCRIPTION_ID}"`,

bosh/executor_test.go

Lines changed: 122 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -75,55 +75,102 @@ var _ = Describe("Executor", func() {
7575
})
7676

7777
Describe("PlanJumpbox", func() {
78-
It("writes bosh-deployment assets to the deployment dir", func() {
79-
err := executor.PlanJumpbox(dirInput, deploymentDir, "aws")
80-
Expect(err).NotTo(HaveOccurred())
78+
Context("on aws", func() {
79+
It("writes bosh-deployment assets to the deployment dir", func() {
80+
err := executor.PlanJumpbox(dirInput, deploymentDir, "aws")
81+
Expect(err).NotTo(HaveOccurred())
8182

82-
By("writing bosh-deployment assets to the deployment dir", func() {
83-
simplePath := filepath.Join(deploymentDir, "no-external-ip.yml")
83+
By("writing bosh-deployment assets to the deployment dir", func() {
84+
simplePath := filepath.Join(deploymentDir, "no-external-ip.yml")
8485

85-
contents, err := fs.ReadFile(simplePath)
86-
Expect(err).NotTo(HaveOccurred())
87-
Expect(string(contents)).To(Equal("no-ip"))
86+
contents, err := fs.ReadFile(simplePath)
87+
Expect(err).NotTo(HaveOccurred())
88+
Expect(string(contents)).To(Equal("no-ip"))
8889

89-
nestedPath := filepath.Join(deploymentDir, "aws", "cpi.yml")
90+
nestedPath := filepath.Join(deploymentDir, "aws", "cpi.yml")
9091

91-
contents, err = fs.ReadFile(nestedPath)
92-
Expect(err).NotTo(HaveOccurred())
93-
Expect(string(contents)).To(Equal("aws-cpi"))
92+
contents, err = fs.ReadFile(nestedPath)
93+
Expect(err).NotTo(HaveOccurred())
94+
Expect(string(contents)).To(Equal("aws-cpi"))
95+
})
96+
97+
By("writing create-env and delete-env scripts", func() {
98+
expectedArgs := []string{
99+
fmt.Sprintf("%s/jumpbox.yml", relativeDeploymentDir),
100+
"--state", fmt.Sprintf("%s/jumpbox-state.json", relativeVarsDir),
101+
"--vars-store", fmt.Sprintf("%s/jumpbox-vars-store.yml", relativeVarsDir),
102+
"--vars-file", fmt.Sprintf("%s/jumpbox-vars-file.yml", relativeVarsDir),
103+
"-o", fmt.Sprintf("%s/aws/cpi.yml", relativeDeploymentDir),
104+
"-v", `access_key_id="${BBL_AWS_ACCESS_KEY_ID}"`,
105+
"-v", `secret_access_key="${BBL_AWS_SECRET_ACCESS_KEY}"`,
106+
}
107+
108+
expectedScript := formatScript("create-env", stateDir, expectedArgs)
109+
scriptPath := fmt.Sprintf("%s/create-jumpbox.sh", stateDir)
110+
shellScript, err := fs.ReadFile(scriptPath)
111+
Expect(err).NotTo(HaveOccurred())
112+
113+
fileinfo, err := fs.Stat(scriptPath)
114+
Expect(err).NotTo(HaveOccurred())
115+
Expect(fileinfo.Mode().String()).To(Equal("-rwxr-x---"))
116+
Expect(string(shellScript)).To(Equal(expectedScript))
117+
118+
expectedScript = formatScript("delete-env", stateDir, expectedArgs)
119+
scriptPath = fmt.Sprintf("%s/delete-jumpbox.sh", stateDir)
120+
shellScript, err = fs.ReadFile(scriptPath)
121+
Expect(err).NotTo(HaveOccurred())
122+
123+
fileinfo, err = fs.Stat(scriptPath)
124+
Expect(err).NotTo(HaveOccurred())
125+
Expect(fileinfo.Mode().String()).To(Equal("-rwxr-x---"))
126+
Expect(err).NotTo(HaveOccurred())
127+
Expect(string(shellScript)).To(Equal(expectedScript))
128+
})
94129
})
95130

96-
By("writing create-env and delete-env scripts", func() {
97-
expectedArgs := []string{
98-
fmt.Sprintf("%s/jumpbox.yml", relativeDeploymentDir),
99-
"--state", fmt.Sprintf("%s/jumpbox-state.json", relativeVarsDir),
100-
"--vars-store", fmt.Sprintf("%s/jumpbox-vars-store.yml", relativeVarsDir),
101-
"--vars-file", fmt.Sprintf("%s/jumpbox-vars-file.yml", relativeVarsDir),
102-
"-o", fmt.Sprintf("%s/aws/cpi.yml", relativeDeploymentDir),
103-
"-v", `access_key_id="${BBL_AWS_ACCESS_KEY_ID}"`,
104-
"-v", `secret_access_key="${BBL_AWS_SECRET_ACCESS_KEY}"`,
105-
}
131+
Context("when assume role is set", func() {
132+
It("writes create-env and delete-env scripts with the assume role ops files and variables", func() {
133+
state := storage.State{
134+
AWS: storage.AWS{
135+
AssumeRoleArn: "some-aws-assume-role",
136+
},
137+
}
138+
err := executor.PlanJumpboxWithState(dirInput, deploymentDir, "aws", state)
139+
Expect(err).NotTo(HaveOccurred())
106140

107-
expectedScript := formatScript("create-env", stateDir, expectedArgs)
108-
scriptPath := fmt.Sprintf("%s/create-jumpbox.sh", stateDir)
109-
shellScript, err := fs.ReadFile(scriptPath)
110-
Expect(err).NotTo(HaveOccurred())
141+
expectedArgs := []string{
142+
fmt.Sprintf("%s/jumpbox.yml", relativeDeploymentDir),
143+
"--state", fmt.Sprintf("%s/jumpbox-state.json", relativeVarsDir),
144+
"--vars-store", fmt.Sprintf("%s/jumpbox-vars-store.yml", relativeVarsDir),
145+
"--vars-file", fmt.Sprintf("%s/jumpbox-vars-file.yml", relativeVarsDir),
146+
"-o", fmt.Sprintf("%s/aws/cpi.yml", relativeDeploymentDir),
147+
"-o", fmt.Sprintf("%s/aws/cpi-assume-role-credentials.yml", relativeDeploymentDir),
148+
"-v", `access_key_id="${BBL_AWS_ACCESS_KEY_ID}"`,
149+
"-v", `secret_access_key="${BBL_AWS_SECRET_ACCESS_KEY}"`,
150+
"-v", `role_arn="${BBL_AWS_ASSUME_ROLE}"`,
151+
}
111152

112-
fileinfo, err := fs.Stat(scriptPath)
113-
Expect(err).NotTo(HaveOccurred())
114-
Expect(fileinfo.Mode().String()).To(Equal("-rwxr-x---"))
115-
Expect(string(shellScript)).To(Equal(expectedScript))
153+
expectedScript := formatScript("create-env", stateDir, expectedArgs)
154+
scriptPath := fmt.Sprintf("%s/create-jumpbox.sh", stateDir)
155+
shellScript, err := fs.ReadFile(scriptPath)
156+
Expect(err).NotTo(HaveOccurred())
116157

117-
expectedScript = formatScript("delete-env", stateDir, expectedArgs)
118-
scriptPath = fmt.Sprintf("%s/delete-jumpbox.sh", stateDir)
119-
shellScript, err = fs.ReadFile(scriptPath)
120-
Expect(err).NotTo(HaveOccurred())
158+
fileinfo, err := fs.Stat(scriptPath)
159+
Expect(err).NotTo(HaveOccurred())
160+
Expect(fileinfo.Mode().String()).To(Equal("-rwxr-x---"))
161+
Expect(string(shellScript)).To(Equal(expectedScript))
121162

122-
fileinfo, err = fs.Stat(scriptPath)
123-
Expect(err).NotTo(HaveOccurred())
124-
Expect(fileinfo.Mode().String()).To(Equal("-rwxr-x---"))
125-
Expect(err).NotTo(HaveOccurred())
126-
Expect(string(shellScript)).To(Equal(expectedScript))
163+
expectedScript = formatScript("delete-env", stateDir, expectedArgs)
164+
scriptPath = fmt.Sprintf("%s/delete-jumpbox.sh", stateDir)
165+
shellScript, err = fs.ReadFile(scriptPath)
166+
Expect(err).NotTo(HaveOccurred())
167+
168+
fileinfo, err = fs.Stat(scriptPath)
169+
Expect(err).NotTo(HaveOccurred())
170+
Expect(fileinfo.Mode().String()).To(Equal("-rwxr-x---"))
171+
Expect(err).NotTo(HaveOccurred())
172+
Expect(string(shellScript)).To(Equal(expectedScript))
173+
})
127174
})
128175
})
129176

@@ -347,7 +394,7 @@ var _ = Describe("Executor", func() {
347394
"-v", `secret_access_key="${BBL_AWS_SECRET_ACCESS_KEY}"`,
348395
}
349396

350-
behavesLikePlan(expectedArgs, cli, fs, executor, dirInput, deploymentDir, "aws", stateDir)
397+
behavesLikePlan(expectedArgs, cli, fs, executor, dirInput, deploymentDir, "aws", stateDir, storage.State{})
351398
})
352399

353400
It("writes aws-specific ops files", func() {
@@ -364,6 +411,35 @@ var _ = Describe("Executor", func() {
364411
value: true
365412
`))
366413
})
414+
415+
Context("when assume role is set", func() {
416+
It("writes create-director.sh and delete-director.sh including the assume role ops files and variables", func() {
417+
expectedArgs := []string{
418+
filepath.Join(relativeDeploymentDir, "bosh.yml"),
419+
"--state", filepath.Join(relativeVarsDir, "bosh-state.json"),
420+
"--vars-store", filepath.Join(relativeVarsDir, "director-vars-store.yml"),
421+
"--vars-file", filepath.Join(relativeVarsDir, "director-vars-file.yml"),
422+
"-o", filepath.Join(relativeDeploymentDir, "aws", "cpi.yml"),
423+
"-o", filepath.Join(relativeDeploymentDir, "jumpbox-user.yml"),
424+
"-o", filepath.Join(relativeDeploymentDir, "uaa.yml"),
425+
"-o", filepath.Join(relativeDeploymentDir, "credhub.yml"),
426+
"-o", filepath.Join(relativeStateDir, "bbl-ops-files", "aws", "bosh-director-ephemeral-ip-ops.yml"),
427+
"-o", filepath.Join(relativeDeploymentDir, "aws", "iam-instance-profile.yml"),
428+
"-o", filepath.Join(relativeDeploymentDir, "aws", "encrypted-disk.yml"),
429+
"-o", filepath.Join(relativeDeploymentDir, "aws", "cpi-assume-role-credentials.yml"),
430+
"-v", `access_key_id="${BBL_AWS_ACCESS_KEY_ID}"`,
431+
"-v", `secret_access_key="${BBL_AWS_SECRET_ACCESS_KEY}"`,
432+
"-v", `role_arn="${BBL_AWS_ASSUME_ROLE}"`,
433+
}
434+
435+
state := storage.State{
436+
AWS: storage.AWS{
437+
AssumeRoleArn: "some-aws-assume-role",
438+
},
439+
}
440+
behavesLikePlan(expectedArgs, cli, fs, executor, dirInput, deploymentDir, "aws", stateDir, state)
441+
})
442+
})
367443
})
368444

369445
Context("gcp", func() {
@@ -383,7 +459,7 @@ var _ = Describe("Executor", func() {
383459
"-v", `zone="${BBL_GCP_ZONE}"`,
384460
}
385461

386-
behavesLikePlan(expectedArgs, cli, fs, executor, dirInput, deploymentDir, "gcp", stateDir)
462+
behavesLikePlan(expectedArgs, cli, fs, executor, dirInput, deploymentDir, "gcp", stateDir, storage.State{})
387463
})
388464

389465
It("writes gcp-specific ops files", func() {
@@ -419,7 +495,7 @@ var _ = Describe("Executor", func() {
419495
"-v", `tenant_id="${BBL_AZURE_TENANT_ID}"`,
420496
}
421497

422-
behavesLikePlan(expectedArgs, cli, fs, executor, dirInput, deploymentDir, "azure", stateDir)
498+
behavesLikePlan(expectedArgs, cli, fs, executor, dirInput, deploymentDir, "azure", stateDir, storage.State{})
423499
})
424500
})
425501

@@ -439,7 +515,7 @@ var _ = Describe("Executor", func() {
439515
"-v", `vcenter_password="${BBL_VSPHERE_VCENTER_PASSWORD}"`,
440516
}
441517

442-
behavesLikePlan(expectedArgs, cli, fs, executor, dirInput, deploymentDir, "vsphere", stateDir)
518+
behavesLikePlan(expectedArgs, cli, fs, executor, dirInput, deploymentDir, "vsphere", stateDir, storage.State{})
443519
})
444520
})
445521

@@ -458,7 +534,7 @@ var _ = Describe("Executor", func() {
458534
"-v", `openstack_password="${BBL_OPENSTACK_PASSWORD}"`,
459535
}
460536

461-
behavesLikePlan(expectedArgs, cli, fs, executor, dirInput, deploymentDir, "openstack", stateDir)
537+
behavesLikePlan(expectedArgs, cli, fs, executor, dirInput, deploymentDir, "openstack", stateDir, storage.State{})
462538
})
463539
})
464540
Context("cloudstack", func() {
@@ -1028,13 +1104,13 @@ type behavesLikePlanFs interface {
10281104
fileio.Stater
10291105
}
10301106

1031-
func behavesLikePlan(expectedArgs []string, cli *fakes.BOSHCLI, fs behavesLikePlanFs, executor bosh.Executor, input bosh.DirInput, deploymentDir, iaas, stateDir string) {
1107+
func behavesLikePlan(expectedArgs []string, cli *fakes.BOSHCLI, fs behavesLikePlanFs, executor bosh.Executor, input bosh.DirInput, deploymentDir, iaas, stateDir string, state storage.State) {
10321108
cli.RunStub = func(stdout io.Writer, workingDirectory string, args []string) error {
10331109
stdout.Write([]byte("some-manifest")) //nolint:errcheck
10341110
return nil
10351111
}
10361112

1037-
err := executor.PlanDirector(input, deploymentDir, iaas)
1113+
err := executor.PlanDirectorWithState(input, deploymentDir, iaas, state)
10381114
Expect(err).NotTo(HaveOccurred())
10391115
Expect(cli.RunCallCount()).To(Equal(0))
10401116

bosh/manager.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ type directorVars struct {
4040
}
4141

4242
type executor interface {
43-
PlanDirector(DirInput, string, string) error
44-
PlanJumpbox(DirInput, string, string) error
43+
PlanDirectorWithState(DirInput, string, string, storage.State) error
44+
PlanJumpboxWithState(DirInput, string, string, storage.State) error
4545
CreateEnv(DirInput, storage.State) (string, error)
4646
DeleteEnv(DirInput, storage.State) error
4747
WriteDeploymentVars(DirInput, string) error
@@ -107,7 +107,7 @@ func (m *Manager) InitializeJumpbox(state storage.State) error {
107107
VarsDir: varsDir,
108108
}
109109

110-
err = m.executor.PlanJumpbox(iaasInputs, deploymentDir, state.IAAS)
110+
err = m.executor.PlanJumpboxWithState(iaasInputs, deploymentDir, state.IAAS, state)
111111
if err != nil {
112112
return fmt.Errorf("Jumpbox interpolate: %s", err)
113113
}
@@ -186,7 +186,7 @@ func (m *Manager) InitializeDirector(state storage.State) error {
186186
VarsDir: varsDir,
187187
}
188188

189-
err = m.executor.PlanDirector(iaasInputs, directorDeploymentDir, state.IAAS)
189+
err = m.executor.PlanDirectorWithState(iaasInputs, directorDeploymentDir, state.IAAS, state)
190190
if err != nil {
191191
return err
192192
}

bosh/manager_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,17 @@ director_ssl:
102102
It("Calls PlanDirector", func() {
103103
err := boshManager.InitializeDirector(state)
104104
Expect(err).NotTo(HaveOccurred())
105-
Expect(boshExecutor.PlanDirectorCall.Receives.DirInput.VarsDir).To(Equal("some-bbl-vars-dir"))
106-
Expect(boshExecutor.PlanDirectorCall.Receives.DirInput.StateDir).To(Equal("some-state-dir"))
107-
Expect(boshExecutor.PlanDirectorCall.Receives.DeploymentDir).To(Equal("some-director-deployment-dir"))
108-
Expect(boshExecutor.PlanJumpboxCall.CallCount).To(Equal(0))
105+
Expect(boshExecutor.PlanDirectorWithStateCall.Receives.DirInput.VarsDir).To(Equal("some-bbl-vars-dir"))
106+
Expect(boshExecutor.PlanDirectorWithStateCall.Receives.DirInput.StateDir).To(Equal("some-state-dir"))
107+
Expect(boshExecutor.PlanDirectorWithStateCall.Receives.DeploymentDir).To(Equal("some-director-deployment-dir"))
108+
Expect(boshExecutor.PlanJumpboxWithStateCall.CallCount).To(Equal(0))
109109

110110
Expect(boshExecutor.CreateEnvCall.CallCount).To(Equal(0))
111111
})
112112

113113
Context("when create env args fails", func() {
114114
BeforeEach(func() {
115-
boshExecutor.PlanDirectorCall.Returns.Error = errors.New("failed to interpolate")
115+
boshExecutor.PlanDirectorWithStateCall.Returns.Error = errors.New("failed to interpolate")
116116
})
117117

118118
It("returns an error", func() {
@@ -238,13 +238,13 @@ director_ssl:
238238
})
239239

240240
Describe("InitializeJumpbox", func() {
241-
It("calls PlanJumpboxCall appropriately", func() {
241+
It("calls PlanJumpboxWithStateCall appropriately", func() {
242242
err := boshManager.InitializeJumpbox(state)
243243
Expect(err).NotTo(HaveOccurred())
244244

245-
Expect(boshExecutor.PlanJumpboxCall.Receives.DeploymentDir).To(Equal("some-jumpbox-deployment-dir"))
246-
Expect(boshExecutor.PlanJumpboxCall.Receives.DirInput.VarsDir).To(Equal("some-bbl-vars-dir"))
247-
Expect(boshExecutor.PlanJumpboxCall.Receives.DirInput.StateDir).To(Equal("some-state-dir"))
245+
Expect(boshExecutor.PlanJumpboxWithStateCall.Receives.DeploymentDir).To(Equal("some-jumpbox-deployment-dir"))
246+
Expect(boshExecutor.PlanJumpboxWithStateCall.Receives.DirInput.VarsDir).To(Equal("some-bbl-vars-dir"))
247+
Expect(boshExecutor.PlanJumpboxWithStateCall.Receives.DirInput.StateDir).To(Equal("some-state-dir"))
248248
})
249249

250250
Context("when an error occurs", func() {

0 commit comments

Comments
 (0)