Skip to content

Commit 9cd4436

Browse files
committed
Add refresh action and input for plan/apply
1 parent 7020a18 commit 9cd4436

File tree

26 files changed

+1085
-26
lines changed

26 files changed

+1085
-26
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
name: Test terraform-refresh
2+
3+
on:
4+
- pull_request
5+
6+
permissions:
7+
contents: read
8+
9+
jobs:
10+
refresh:
11+
runs-on: ubuntu-24.04
12+
name: No changes
13+
permissions:
14+
contents: read
15+
pull-requests: write
16+
env:
17+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
with:
22+
persist-credentials: false
23+
24+
- name: Plan
25+
uses: ./terraform-apply
26+
with:
27+
path: tests/workflows/test-refresh
28+
auto_approve: true
29+
30+
- name: Check no changes
31+
uses: ./terraform-check
32+
with:
33+
path: tests/workflows/test-refresh
34+
35+
- name: Make untracked changes
36+
run: |
37+
echo "qewasdasd" > tests/workflows/test-refresh/test
38+
echo "cxvbbxcbb" > tests/workflows/test-refresh/test2
39+
echo "tyuityuiy" > tests/workflows/test-refresh/test3
40+
41+
- name: Create a normal plan
42+
uses: ./terraform-plan
43+
id: plan-with-refresh
44+
with:
45+
add_github_comment: false
46+
path: tests/workflows/test-refresh
47+
48+
- name: Check normal plan picks up changes
49+
env:
50+
CHANGES: ${{ steps.plan-with-refresh.outputs.changes }}
51+
TO_ADD: ${{ steps.plan-with-refresh.outputs.to_add }}
52+
run: |
53+
if [[ "$CHANGES" != "true" ]]; then
54+
echo "::error:: Plan did not have changes"
55+
exit 1
56+
fi
57+
58+
if [[ "$TO_ADD" != "3" ]]; then
59+
echo "::error:: Wrong number of resources to add"
60+
exit 1
61+
fi
62+
63+
- name: Create a non-refresh plan
64+
uses: ./terraform-plan
65+
id: plan-without-refresh
66+
with:
67+
add_github_comment: false
68+
label: test-refresh refresh non-refresh
69+
path: tests/workflows/test-refresh
70+
refresh: false
71+
72+
- name: Check non-refresh plan doesn't pick up changes
73+
env:
74+
CHANGES: ${{ steps.plan-without-refresh.outputs.changes }}
75+
TO_ADD: ${{ steps.plan-without-refresh.outputs.to_add }}
76+
run: |
77+
if [[ "$CHANGES" != "false" ]]; then
78+
echo "::error:: Plan has changes"
79+
exit 1
80+
fi
81+
82+
- name: Targeted refresh
83+
uses: ./terraform-refresh
84+
with:
85+
path: tests/workflows/test-refresh
86+
target: |
87+
local_file.test
88+
89+
- name: Plan after targeted refresh
90+
uses: ./terraform-plan
91+
id: plan-after-targeted-refresh
92+
with:
93+
path: tests/workflows/test-refresh
94+
refresh: false
95+
96+
- name: Check plan after targeted refresh
97+
env:
98+
CHANGES: ${{ steps.plan-after-targeted-refresh.outputs.changes }}
99+
TO_ADD: ${{ steps.plan-after-targeted-refresh.outputs.to_add }}
100+
run: |
101+
if [[ "$CHANGES" != "true" ]]; then
102+
echo "::error:: Plan did not have changes"
103+
exit 1
104+
fi
105+
106+
if [[ "$TO_ADD" != "1" ]]; then
107+
echo "::error:: Wrong number of resources to add"
108+
exit 1
109+
fi
110+
111+
- name: Apply with refresh
112+
uses: ./terraform-apply
113+
id: apply
114+
continue-on-error: true
115+
with:
116+
path: tests/workflows/test-refresh
117+
118+
- name: Check failed to apply
119+
env:
120+
OUTCOME: ${{ steps.apply.outcome }}
121+
FAILURE_REASON: ${{ steps.apply.outputs.failure-reason }}
122+
run: |
123+
if [[ "$OUTCOME" != "failure" ]]; then
124+
echo "Apply did not fail correctly"
125+
exit 1
126+
fi
127+
128+
if [[ "$FAILURE_REASON" == "plan-changed" ]]; then
129+
echo "::error:: failure-reason not set correctly"
130+
exit 1
131+
fi
132+
133+
- name: Apply without refresh
134+
uses: ./terraform-apply
135+
with:
136+
path: tests/workflows/test-refresh
137+
refresh: false
138+
139+
- name: Create another normal plan
140+
uses: ./terraform-plan
141+
id: plan-with-refresh-after-apply
142+
with:
143+
add_github_comment: false
144+
path: tests/workflows/test-refresh
145+
146+
- name: Check normal plan picks up changes
147+
env:
148+
CHANGES: ${{ steps.plan-with-refresh-after-apply.outputs.changes }}
149+
TO_ADD: ${{ steps.plan-with-refresh-after-apply.outputs.to_add }}
150+
run: |
151+
if [[ "$CHANGES" != "true" ]]; then
152+
echo "::error:: Plan did not have changes"
153+
exit 1
154+
fi
155+
156+
if [[ "$TO_ADD" != "2" ]]; then
157+
echo "::error:: Wrong number of resources to add"
158+
exit 1
159+
fi
160+
161+
- name: Full refresh
162+
uses: ./terraform-refresh
163+
with:
164+
path: tests/workflows/test-refresh
165+
166+
- name: Plan after full refresh
167+
uses: ./terraform-plan
168+
id: plan-after-full-refresh
169+
with:
170+
add_github_comment: false
171+
path: tests/workflows/test-refresh
172+
refresh: false
173+
174+
- name: Check plan after full refresh
175+
env:
176+
CHANGES: ${{ steps.plan-after-full-refresh.outputs.changes }}
177+
TO_ADD: ${{ steps.plan-after-full-refresh.outputs.to_add }}
178+
run: |
179+
if [[ "$CHANGES" != "true" ]]; then
180+
echo "::error:: Plan did not have changes"
181+
exit 1
182+
fi
183+
184+
if [[ "$TO_ADD" != "2" ]]; then
185+
echo "::error:: Wrong number of resources to add"
186+
exit 1
187+
fi

README.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,23 @@ Currently, there is just experimental support for OpenTofu, see [here](https://g
1111

1212
See the documentation for the available actions:
1313

14-
| Terraform | OpenTofu |
15-
|--------------------------------------------------------------------|---------------------------------------------------------|
16-
| [dflook/terraform-plan](terraform-plan) | [dflook/tofu-plan](tofu-plan) |
17-
| [dflook/terraform-apply](terraform-apply) | [dflook/tofu-apply](tofu-apply) |
18-
| [dflook/terraform-output](terraform-output) | [dflook/tofu-output](tofu-output) |
19-
| [dflook/terraform-remote-state](terraform-remote-state) | [dflook/tofu-remote-state](tofu-remote-state) |
20-
| [dflook/terraform-validate](terraform-validate) | [dflook/tofu-validate](tofu-validate) |
21-
| [dflook/terraform-fmt-check](terraform-fmt-check) | [dflook/tofu-fmt-check](tofu-fmt-check) |
22-
| [dflook/terraform-fmt](terraform-fmt) | [dflook/tofu-fmt](tofu-fmt) |
23-
| [dflook/terraform-check](terraform-check) | [dflook/tofu-check](tofu-check) |
24-
| [dflook/terraform-new-workspace](terraform-new-workspace) | [dflook/tofu-new-workspace](tofu-new-workspace) |
25-
| [dflook/terraform-destroy-workspace](terraform-destroy-workspace) | [dflook/tofu-destroy-workspace](tofu-destroy-workspace) |
26-
| [dflook/terraform-destroy](terraform-destroy) | [dflook/tofu-destroy](tofu-destroy) |
27-
| [dflook/terraform-version](terraform-version) | [dflook/tofu-version](tofu-version) |
28-
| [dflook/terraform-unlock-state](terraform-unlock-state) | [dflook/tofu-unlock-state](tofu-unlock-state) |
29-
| [dflook/terraform-test](terraform-test) | [dflook/tofu-test](tofu-test) |
14+
| Terraform | OpenTofu |
15+
|-------------------------------------------------------------------|---------------------------------------------------------|
16+
| [dflook/terraform-plan](terraform-plan) | [dflook/tofu-plan](tofu-plan) |
17+
| [dflook/terraform-apply](terraform-apply) | [dflook/tofu-apply](tofu-apply) |
18+
| [dflook/terraform-output](terraform-output) | [dflook/tofu-output](tofu-output) |
19+
| [dflook/terraform-remote-state](terraform-remote-state) | [dflook/tofu-remote-state](tofu-remote-state) |
20+
| [dflook/terraform-validate](terraform-validate) | [dflook/tofu-validate](tofu-validate) |
21+
| [dflook/terraform-fmt-check](terraform-fmt-check) | [dflook/tofu-fmt-check](tofu-fmt-check) |
22+
| [dflook/terraform-fmt](terraform-fmt) | [dflook/tofu-fmt](tofu-fmt) |
23+
| [dflook/terraform-check](terraform-check) | [dflook/tofu-check](tofu-check) |
24+
| [dflook/terraform-new-workspace](terraform-new-workspace) | [dflook/tofu-new-workspace](tofu-new-workspace) |
25+
| [dflook/terraform-destroy-workspace](terraform-destroy-workspace) | [dflook/tofu-destroy-workspace](tofu-destroy-workspace) |
26+
| [dflook/terraform-destroy](terraform-destroy) | [dflook/tofu-destroy](tofu-destroy) |
27+
| [dflook/terraform-version](terraform-version) | [dflook/tofu-version](tofu-version) |
28+
| [dflook/terraform-unlock-state](terraform-unlock-state) | [dflook/tofu-unlock-state](tofu-unlock-state) |
29+
| [dflook/terraform-test](terraform-test) | [dflook/tofu-test](tofu-test) |
30+
| [dflook/terraform-refresh](terraform-refresh) | [dflook/tofu-refresh](tofu-refresh) |
3031

3132
## Example Usage
3233

docs-gen/action.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ def assert_ordering(self):
172172
"replace",
173173
"target",
174174
"destroy",
175+
"refresh",
175176
"plan_path",
176177
"auto_approve",
177178
"add_github_comment",

docs-gen/actions/apply.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from inputs.parallelism import parallelism
1717
from inputs.path import path
1818
from inputs.plan_path import plan_path as plan_path_input
19+
from inputs.refresh import refresh
1920
from inputs.replace import replace
2021
from inputs.target import target
2122
from inputs.var_file import var_file
@@ -83,6 +84,7 @@
8384
Set to `true` to destroy all resources.
8485
8586
This generates and applies a plan in [destroy mode]($DestroyModeUrl).'''),
87+
refresh,
8688
plan_path_input,
8789
auto_approve,
8890
parallelism
@@ -339,4 +341,4 @@
339341
auto_approve: true
340342
```
341343
'''
342-
)
344+
)

docs-gen/actions/plan.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from inputs.label import label
1717
from inputs.parallelism import parallelism
1818
from inputs.path import path
19+
from inputs.refresh import refresh
1920
from inputs.replace import replace
2021
from inputs.target import target
2122
from inputs.var import var
@@ -57,6 +58,7 @@
5758
replace,
5859
target,
5960
destroy,
61+
refresh,
6062
add_github_comment,
6163
parallelism
6264
],
@@ -251,4 +253,4 @@
251253
path: my-$ToolName-config
252254
```
253255
'''
254-
)
256+
)

docs-gen/actions/refresh.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import dataclasses
2+
3+
from action import Action
4+
from environment_variables.GITHUB_DOT_COM_TOKEN import GITHUB_DOT_COM_TOKEN
5+
from environment_variables.TERRAFORM_CLOUD_TOKENS import TERRAFORM_CLOUD_TOKENS
6+
from environment_variables.TERRAFORM_HTTP_CREDENTIALS import TERRAFORM_HTTP_CREDENTIALS
7+
from environment_variables.TERRAFORM_PRE_RUN import TERRAFORM_PRE_RUN
8+
from environment_variables.TERRAFORM_SSH_KEY import TERRAFORM_SSH_KEY
9+
from inputs.backend_config import backend_config
10+
from inputs.backend_config_file import backend_config_file
11+
from inputs.path import path
12+
from inputs.var_file import var_file
13+
from inputs.variables import variables
14+
from inputs.workspace import workspace
15+
from inputs.target import target
16+
from outputs.failure_reason import failure_reason
17+
from outputs.lock_info import lock_info
18+
from outputs.run_id import run_id
19+
20+
refresh = Action(
21+
'refresh',
22+
'''
23+
This actions runs a $ProductName apply operation in refresh-only mode.
24+
This will synchronise the $ProductName state with the actual resources, but will not make any changes to the resources.
25+
''',
26+
meta_description='Refresh $ProductName state',
27+
inputs=[
28+
dataclasses.replace(path, description="Path to the $ProductName root module to refresh state for"),
29+
dataclasses.replace(workspace, description="$ProductName workspace to run the refresh state in"),
30+
variables,
31+
var_file,
32+
backend_config,
33+
backend_config_file,
34+
dataclasses.replace(target, description='''
35+
List of resources to target, one per line.
36+
The refresh will be limited to these resources and their dependencies.
37+
'''),
38+
],
39+
outputs=[
40+
dataclasses.replace(failure_reason, description='''
41+
When the job outcome is `failure`, this output may be set. The value may be one of:
42+
43+
- `refresh-failed` - The $ProductName apply operation failed.
44+
- `state-locked` - The Terraform state lock could not be obtained because it was already locked.
45+
46+
If the job fails for any other reason this will not be set.
47+
This can be used with the Actions expression syntax to conditionally run steps.
48+
'''
49+
),
50+
lock_info,
51+
run_id
52+
],
53+
environment_variables=[
54+
GITHUB_DOT_COM_TOKEN,
55+
TERRAFORM_CLOUD_TOKENS,
56+
TERRAFORM_SSH_KEY,
57+
TERRAFORM_HTTP_CREDENTIALS,
58+
TERRAFORM_PRE_RUN,
59+
]
60+
)

docs-gen/generate.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from actions.new_workspace import new_workspace
99
from actions.output import output
1010
from actions.plan import plan
11+
from actions.refresh import refresh
1112
from actions.remote_state import remote_state
1213
from actions.test import test
1314
from actions.unlock_state import unlock_state
@@ -18,7 +19,6 @@ def tofuize(str) -> str:
1819
return str.replace('a OpenTofu', 'an OpenTofu')
1920

2021
for action in [
21-
plan,
2222
apply,
2323
check,
2424
destroy,
@@ -27,12 +27,13 @@ def tofuize(str) -> str:
2727
fmt_check,
2828
new_workspace,
2929
output,
30+
plan,
31+
refresh,
3032
remote_state,
3133
test,
3234
unlock_state,
3335
validate,
34-
version
35-
36+
version,
3637
]:
3738
action.assert_ordering()
3839

docs-gen/inputs/refresh.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from action import Input
2+
3+
refresh = Input(
4+
name='refresh',
5+
type='boolean',
6+
description='''
7+
Set to `false` to skip synchronisation of the $ProductName state with actual resources.
8+
9+
This will make the plan faster but may be out of date with the actual resources, which can lead to incorrect plans.
10+
''',
11+
required=False,
12+
default='true'
13+
)

docs-gen/inputs/target.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
name='target',
55
type='string',
66
description='''
7-
List of resources to apply, one per line.
7+
List of resources to target, one per line.
88
The plan will be limited to these resources and their dependencies.
99
''',
1010
example = '''

0 commit comments

Comments
 (0)