Skip to content

Commit

Permalink
feat: state rm
Browse files Browse the repository at this point in the history
  • Loading branch information
krrrr38 committed Dec 26, 2022
1 parent de953fe commit 91f4995
Show file tree
Hide file tree
Showing 62 changed files with 1,634 additions and 201 deletions.
32 changes: 21 additions & 11 deletions runatlantis.io/docs/custom-workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ workflows:
- init
- import:
extra_args: ["-var-file", "production.tfvars"]
state_rm:
steps:
- init
- state_rm:
extra_args: ["-lock=false"]
```
Then in your repo-level `atlantis.yaml` file, you would reference the workflows:
```yaml
Expand Down Expand Up @@ -374,13 +379,15 @@ projects:
plan:
apply:
import:
state_rm:
```

| Key | Type | Default | Required | Description |
|--------|-----------------|-------------------------|----------|----------------------------------|
| plan | [Stage](#stage) | `steps: [init, plan]` | no | How to plan for this project. |
| apply | [Stage](#stage) | `steps: [apply]` | no | How to apply for this project. |
| import | [Stage](#stage) | `steps: [init, import]` | no | How to import for this project. |
| Key | Type | Default | Required | Description |
|----------|-----------------|---------------------------|----------|----------------------------------|
| plan | [Stage](#stage) | `steps: [init, plan]` | no | How to plan for this project. |
| apply | [Stage](#stage) | `steps: [apply]` | no | How to apply for this project. |
| import | [Stage](#stage) | `steps: [init, import]` | no | How to import for this project. |
| state_rm | [Stage](#stage) | `steps: [init, state_rm]` | no | How to import for this project. |

### Stage
```yaml
Expand All @@ -403,10 +410,11 @@ Steps can be a single string for a built-in command.
- plan
- apply
- import
- state_rm
```
| Key | Type | Default | Required | Description |
|------------------------|--------|---------|----------|------------------------------------------------------------------------------------------------------------------|
| init/plan/apply/import | string | none | no | Use a built-in command without additional configuration. Only `init`, `plan`, `apply` and `import` are supported |
| Key | Type | Default | Required | Description |
|---------------------------------|--------|---------|----------|------------------------------------------------------------------------------------------------------------------------------|
| init/plan/apply/import/state_rm | string | none | no | Use a built-in command without additional configuration. Only `init`, `plan`, `apply`, `import` and `state_rm` are supported |

#### Built-In Command With Extra Args
A map from string to `extra_args` for a built-in command with extra arguments.
Expand All @@ -419,10 +427,12 @@ A map from string to `extra_args` for a built-in command with extra arguments.
extra_args: [arg1, arg2]
- import:
extra_args: [arg1, arg2]
- state_rm:
extra_args: [arg1, arg2]
```
| Key | Type | Default | Required | Description |
|------------------------|------------------------------------|---------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| init/plan/apply/import | map[`extra_args` -> array[string]] | none | no | Use a built-in command and append `extra_args`. Only `init`, `plan`, `apply` and `import` are supported as keys and only `extra_args` is supported as a value |
| Key | Type | Default | Required | Description |
|---------------------------------|------------------------------------|---------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| init/plan/apply/import/state_rm | map[`extra_args` -> array[string]] | none | no | Use a built-in command and append `extra_args`. Only `init`, `plan`, `apply`, `import` and `state_rm` are supported as keys and only `extra_args` is supported as a value |

#### Custom `run` Command
Or a custom command
Expand Down
43 changes: 43 additions & 0 deletions runatlantis.io/docs/using-atlantis.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,49 @@ atlantis import -d dir 'aws_instance.example["foo"]' i-1234567890abcdef0 -- -var
```
If a flag is needed to be always appended, see [Custom Workflow Use Cases](custom-workflows.html#adding-extra-arguments-to-terraform-commands).

---
## atlantis state rm
```bash
atlantis state [options] rm ADDRESS... -- [terraform import flags]
```
### Explanation
Runs `terraform state rm` that matches the directory/project/workspace.
This command discards the terraform plan result. After an import and before an apply, another `atlantis plan` must be run again.

### Examples
```bash
# Runs state rm
atlantis state rm ADDRESS1 ADDRESS2

# Runs state rm in the root directory of the repo with workspace `default`
atlantis state -d . rm ADDRESS

# Runs state rm in the `project1` directory of the repo with workspace `default`
atlantis state -d project1 rm ADDRESS

# Runs state rm in the root directory of the repo with workspace `staging`
atlantis state -w staging rm ADDRESS
```

::: tip
* If import for_each resources, it requires a single quoted address.
* ex. `atlantis state rm 'aws_instance.example["foo"]'`
:::

### Options
* `-d directory` Run state rm a resource for this directory, relative to root of repo. Use `.` for root.
* `-p project` Run state rm a resource for this project. Refers to the name of the project configured in the repo's [`atlantis.yaml`](repo-level-atlantis-yaml.html) repo configuration file. This cannot be used at the same time as `-d` or `-w`.
* `-w workspace` Run state rm a resource for a specific [Terraform workspace](https://developer.hashicorp.com/terraform/language/state/workspaces). Ignore this if Terraform workspaces are unused.

### Additional Terraform flags

If `terraform state rm` requires additional arguments, like `-lock=false'`
append them to the end of the comment after `--`, e.g.
```
atlantis state -d dir rm 'aws_instance.example["foo"]' -- -lock=false
```
If a flag is needed to be always appended, see [Custom Workflow Use Cases](custom-workflows.html#adding-extra-arguments-to-terraform-commands).

---
## atlantis unlock
```bash
Expand Down
63 changes: 63 additions & 0 deletions server/controllers/events/events_controller_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,58 @@ func TestGitHubWorkflow(t *testing.T) {
{"exp-output-merge.txt"},
},
},
{
Description: "state rm single project",
RepoDir: "state-rm-single-project",
ModifiedFiles: []string{"main.tf"},
ExpAutoplan: true,
Comments: []string{
"atlantis import random_id.simple AA",
"atlantis import 'random_id.for_each[\"overridden\"]' BB -- -var var=overridden",
"atlantis import random_id.count[0] BB",
"atlantis plan -- -var var=overridden",
"atlantis state rm 'random_id.for_each[\"overridden\"]' -- -lock=false",
"atlantis state rm random_id.count[0] random_id.simple",
"atlantis plan -- -var var=overridden",
},
ExpReplies: [][]string{
{"exp-output-autoplan.txt"},
{"exp-output-import-simple.txt"},
{"exp-output-import-foreach.txt"},
{"exp-output-import-count.txt"},
{"exp-output-plan.txt"},
{"exp-output-state-rm-foreach.txt"},
{"exp-output-state-rm-multiple.txt"},
{"exp-output-plan-again.txt"},
{"exp-output-merged.txt"},
},
},
{
Description: "state rm multiple project",
RepoDir: "state-rm-multiple-project",
ModifiedFiles: []string{"dir1/main.tf", "dir2/main.tf"},
ExpAutoplan: true,
Comments: []string{
"atlantis import -d dir1 random_id.dummy1 AA",
"atlantis import -d dir2 random_id.dummy2 BB",
"atlantis plan",
"atlantis state rm random_id.dummy1 AA",
"atlantis state rm -d dir1 random_id.dummy1",
"atlantis state -d dir2 rm random_id.dummy2",
"atlantis plan",
},
ExpReplies: [][]string{
{"exp-output-autoplan.txt"},
{"exp-output-import-dummy1.txt"},
{"exp-output-import-dummy2.txt"},
{"exp-output-plan.txt"},
{"exp-output-state-rm-multiple-projects.txt"},
{"exp-output-state-rm-dummy1.txt"},
{"exp-output-state-rm-dummy2.txt"},
{"exp-output-plan-again.txt"},
{"exp-output-merged.txt"},
},
},
}
for _, c := range cases {
t.Run(c.Description, func(t *testing.T) {
Expand Down Expand Up @@ -1101,6 +1153,10 @@ func setupE2E(t *testing.T, repoDir, repoConfigFile string) (events_controllers.
TerraformExecutor: terraformClient,
DefaultTFVersion: defaultTFVersion,
},
StateRmStepRunner: &runtime.StateRmStepRunner{
TerraformExecutor: terraformClient,
DefaultTFVersion: defaultTFVersion,
},
RunStepRunner: &runtime.RunStepRunner{
TerraformExecutor: terraformClient,
DefaultTFVersion: defaultTFVersion,
Expand Down Expand Up @@ -1208,13 +1264,20 @@ func setupE2E(t *testing.T, repoDir, repoConfigFile string) (events_controllers.
projectCommandRunner,
)

stateCommandRunner := events.NewStateCommandRunner(
pullUpdater,
projectCommandBuilder,
projectCommandRunner,
)

commentCommandRunnerByCmd := map[command.Name]events.CommentCommandRunner{
command.Plan: planCommandRunner,
command.Apply: applyCommandRunner,
command.ApprovePolicies: approvePoliciesCommandRunner,
command.Unlock: unlockCommandRunner,
command.Version: versionCommandRunner,
command.Import: importCommandRunner,
command.State: stateCommandRunner,
}

commandRunner := &events.DefaultCommandRunner{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version: 3
projects:
- dir: dir1
- dir: dir2
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
resource "random_id" "dummy1" {
keepers = {}
byte_length = 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
resource "random_id" "dummy2" {
keepers = {}
byte_length = 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
Ran Plan for 2 projects:

1. dir: `dir1` workspace: `default`
1. dir: `dir2` workspace: `default`

### 1. dir: `dir1` workspace: `default`
<details><summary>Show Output</summary>

```diff

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create

Terraform will perform the following actions:

# random_id.dummy1 will be created
+ resource "random_id" "dummy1" {
+ b64_std = (known after apply)
+ b64_url = (known after apply)
+ byte_length = 1
+ dec = (known after apply)
+ hex = (known after apply)
+ id = (known after apply)
+ keepers = {}
}

Plan: 1 to add, 0 to change, 0 to destroy.


```

* :arrow_forward: To **apply** this plan, comment:
* `atlantis apply -d dir1`
* :put_litter_in_its_place: To **delete** this plan click [here](lock-url)
* :repeat: To **plan** this project again, comment:
* `atlantis plan -d dir1`
</details>
Plan: 1 to add, 0 to change, 0 to destroy.

---
### 2. dir: `dir2` workspace: `default`
<details><summary>Show Output</summary>

```diff

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create

Terraform will perform the following actions:

# random_id.dummy2 will be created
+ resource "random_id" "dummy2" {
+ b64_std = (known after apply)
+ b64_url = (known after apply)
+ byte_length = 1
+ dec = (known after apply)
+ hex = (known after apply)
+ id = (known after apply)
+ keepers = {}
}

Plan: 1 to add, 0 to change, 0 to destroy.


```

* :arrow_forward: To **apply** this plan, comment:
* `atlantis apply -d dir2`
* :put_litter_in_its_place: To **delete** this plan click [here](lock-url)
* :repeat: To **plan** this project again, comment:
* `atlantis plan -d dir2`
</details>
Plan: 1 to add, 0 to change, 0 to destroy.

---
* :fast_forward: To **apply** all unapplied plans from this pull request, comment:
* `atlantis apply`
* :put_litter_in_its_place: To delete all plans and locks for the PR, comment:
* `atlantis unlock`
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Ran Import for dir: `dir1` workspace: `default`

```diff
random_id.dummy1: Importing from ID "AA"...
random_id.dummy1: Import prepared!
Prepared random_id for import
random_id.dummy1: Refreshing state... [id=AA]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.


```

* :repeat: To **plan** this project again, comment:
* `atlantis plan -d dir1`


Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Ran Import for dir: `dir2` workspace: `default`

```diff
random_id.dummy2: Importing from ID "BB"...
random_id.dummy2: Import prepared!
Prepared random_id for import
random_id.dummy2: Refreshing state... [id=BB]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.


```

* :repeat: To **plan** this project again, comment:
* `atlantis plan -d dir2`


Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Locks and plans deleted for the projects and workspaces modified in this pull request:

- dir: `dir1` workspace: `default`
- dir: `dir2` workspace: `default`
Loading

0 comments on commit 91f4995

Please sign in to comment.