Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup AWS resources in case of warm up error #315

Merged
merged 2 commits into from
Feb 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions v2/pkg/stratus/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ func (m *Runner) WarmUp() (map[string]string, error) {
log.Println("Warming up " + m.Technique.ID)
outputs, err := m.TerraformManager.TerraformInitAndApply(m.TerraformDir)
if err != nil {
log.Println("Error during warm up. Cleaning up technique prerequisites with terraform destroy")
_ = m.TerraformManager.TerraformDestroy(m.TerraformDir)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might make sense to defer it here? no strong opinions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting thought; could do something like the below (keeping the _ = to avoid 'unhandled error' warnings).
However, I believe it won't make a difference because there's is nothing in the way that could fail and thus prevent the .TerraformDestroy() from being called. Happy to stand corrected though ;)

		defer func() {
			_ = m.TerraformManager.TerraformDestroy(m.TerraformDir)
		}()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of simply defer m.TerraformManager.TerraformDestroy(m.TerraformDir), but it might trigger an IDE warning instead. No strong opinion, let's keep it as is

return nil, errors.New("unable to run terraform apply on prerequisite: " + errorMessageFromTerraformError(err))
}

Expand Down
16 changes: 15 additions & 1 deletion v2/pkg/stratus/runner/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func TestRunnerWarmUp(t *testing.T) {
InitialTechniqueState stratus.AttackTechniqueState
TerraformOutputs map[string]string
PersistedOutputs map[string]string
Error error
// results
CheckExpectations func(t *testing.T, terraform *mocks.TerraformManager, state *statemocks.StateManager, outputs map[string]string, err error)
}
Expand Down Expand Up @@ -91,6 +92,18 @@ func TestRunnerWarmUp(t *testing.T) {
assert.Equal(t, "old", outputs["myoutput"])
},
},
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great, thanks!

Name: "Warming up a COLD technique with error",
Technique: &stratus.AttackTechnique{ID: "foo", PrerequisitesTerraformCode: []byte("bar")},
InitialTechniqueState: stratus.AttackTechniqueStatusCold,
Error: errors.New("error during init and apply"),
CheckExpectations: func(t *testing.T, terraform *mocks.TerraformManager, state *statemocks.StateManager, outputs map[string]string, err error) {
terraform.AssertCalled(t, "TerraformInitAndApply", "/root/foo")
terraform.AssertCalled(t, "TerraformDestroy", "/root/foo")
assert.NotNil(t, err)
assert.Len(t, outputs, 0)
},
},
}

for i := range scenario {
Expand All @@ -101,7 +114,8 @@ func TestRunnerWarmUp(t *testing.T) {
state.On("ExtractTechnique").Return(nil)
state.On("GetTechniqueState", mock.Anything).Return(scenario[i].InitialTechniqueState, nil)
state.On("GetTerraformOutputs").Return(scenario[i].PersistedOutputs, nil)
terraform.On("TerraformInitAndApply", mock.Anything).Return(scenario[i].TerraformOutputs, nil)
terraform.On("TerraformInitAndApply", mock.Anything).Return(scenario[i].TerraformOutputs, scenario[i].Error)
terraform.On("TerraformDestroy", mock.Anything).Return(nil)
state.On("WriteTerraformOutputs", mock.Anything).Return(nil)
state.On("SetTechniqueState", mock.Anything).Return(nil)

Expand Down