Skip to content
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
187 changes: 187 additions & 0 deletions .github/workflows/test-refresh.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
name: Test terraform-refresh

on:
- pull_request

permissions:
contents: read

jobs:
refresh:
runs-on: ubuntu-24.04
name: Refresh
permissions:
contents: read
pull-requests: write
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Apply
uses: ./terraform-apply
with:
path: tests/workflows/test-refresh
auto_approve: true

- name: Check no changes
uses: ./terraform-check
with:
path: tests/workflows/test-refresh

- name: Make untracked changes
run: |
echo "qewasdasd" > tests/workflows/test-refresh/test
echo "cxvbbxcbb" > tests/workflows/test-refresh/test2
echo "tyuityuiy" > tests/workflows/test-refresh/test3

- name: Create a normal plan
uses: ./terraform-plan
id: plan-with-refresh
with:
add_github_comment: false
path: tests/workflows/test-refresh

- name: Check normal plan picks up changes
env:
CHANGES: ${{ steps.plan-with-refresh.outputs.changes }}
TO_ADD: ${{ steps.plan-with-refresh.outputs.to_add }}
run: |
if [[ "$CHANGES" != "true" ]]; then
echo "::error:: Plan did not have changes"
exit 1
fi

if [[ "$TO_ADD" != "3" ]]; then
echo "::error:: Wrong number of resources to add"
exit 1
fi

- name: Create a non-refresh plan
uses: ./terraform-plan
id: plan-without-refresh
with:
add_github_comment: false
label: test-refresh refresh non-refresh
path: tests/workflows/test-refresh
refresh: false

- name: Check non-refresh plan doesn't pick up changes
env:
CHANGES: ${{ steps.plan-without-refresh.outputs.changes }}
TO_ADD: ${{ steps.plan-without-refresh.outputs.to_add }}
run: |
if [[ "$CHANGES" != "false" ]]; then
echo "::error:: Plan has changes"
exit 1
fi

- name: Targeted refresh
uses: ./terraform-refresh
with:
path: tests/workflows/test-refresh
target: |
local_file.one

- name: Plan after targeted refresh
uses: ./terraform-plan
id: plan-after-targeted-refresh
with:
path: tests/workflows/test-refresh
refresh: false

- name: Check plan after targeted refresh
env:
CHANGES: ${{ steps.plan-after-targeted-refresh.outputs.changes }}
TO_ADD: ${{ steps.plan-after-targeted-refresh.outputs.to_add }}
run: |
if [[ "$CHANGES" != "true" ]]; then
echo "::error:: Plan did not have changes"
exit 1
fi

if [[ "$TO_ADD" != "1" ]]; then
echo "::error:: Wrong number of resources to add"
exit 1
fi

- name: Apply plan after targeted refresh
uses: ./terraform-apply
id: apply
continue-on-error: true
with:
path: tests/workflows/test-refresh

- name: Check failed to apply
env:
OUTCOME: ${{ steps.apply.outcome }}
FAILURE_REASON: ${{ steps.apply.outputs.failure-reason }}
run: |
if [[ "$OUTCOME" != "failure" ]]; then
echo "Apply did not fail correctly"
exit 1
fi

if [[ "$FAILURE_REASON" != "plan-changed" ]]; then
echo "::error:: failure-reason not set correctly"
exit 1
fi

- name: Apply without refresh
uses: ./terraform-apply
with:
path: tests/workflows/test-refresh
refresh: false

- name: Create another normal plan
uses: ./terraform-plan
id: plan-with-refresh-after-apply
with:
add_github_comment: false
path: tests/workflows/test-refresh

- name: Check normal plan picks up changes
env:
CHANGES: ${{ steps.plan-with-refresh-after-apply.outputs.changes }}
TO_ADD: ${{ steps.plan-with-refresh-after-apply.outputs.to_add }}
run: |
if [[ "$CHANGES" != "true" ]]; then
echo "::error:: Plan did not have changes"
exit 1
fi

if [[ "$TO_ADD" != "2" ]]; then
echo "::error:: Wrong number of resources to add"
exit 1
fi

- name: Full refresh
uses: ./terraform-refresh
with:
path: tests/workflows/test-refresh

- name: Plan after full refresh
uses: ./terraform-plan
id: plan-after-full-refresh
with:
add_github_comment: false
path: tests/workflows/test-refresh
refresh: false

- name: Check plan after full refresh
env:
CHANGES: ${{ steps.plan-after-full-refresh.outputs.changes }}
TO_ADD: ${{ steps.plan-after-full-refresh.outputs.to_add }}
run: |
if [[ "$CHANGES" != "true" ]]; then
echo "::error:: Plan did not have changes"
exit 1
fi

if [[ "$TO_ADD" != "2" ]]; then
echo "::error:: Wrong number of resources to add"
exit 1
fi
17 changes: 15 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,22 @@ The actions are versioned as a suite. Some actions may have no change in behavio

When using an action you can specify the version as:

- `@v1.47.0` to use an exact release
- `@v1.47` to use the latest patch release for the specific minor version
- `@v1.48.0` to use an exact release
- `@v1.48` to use the latest patch release for the specific minor version
- `@v1` to use the latest patch release for the specific major version

## [1.48.0] - 2025-03-24

### Added
- A `refresh` input for [dflook/terraform-plan](https://github.com/dflook/terraform-github-actions/tree/main/terraform-plan)/[tofu-plan](https://github.com/dflook/terraform-github-actions/tree/main/tofu-plan)
and [dflook/terraform-apply](https://github.com/dflook/terraform-github-actions/tree/main/terraform-apply)/[tofu-apply](https://github.com/dflook/terraform-github-actions/tree/main/tofu-apply)

This defaults to `true` with the current behaviour of refreshing the state before planning or applying.
When set to `false` the state will not be refreshed, which can be a lot faster but may result in an outdated plan.

- New [dflook/terraform-refresh](https://github.com/dflook/terraform-github-actions/tree/main/terraform-refresh)/[tofu-refresh](https://github.com/dflook/terraform-github-actions/tree/main/tofu-refresh)
actions to update the state file to match the current state of the infrastructure, but doesn't make any changes to the infrastructure.

## [1.47.0] - 2025-02-28

### Added
Expand Down Expand Up @@ -724,6 +736,7 @@ First release of the GitHub Actions:
- [dflook/terraform-new-workspace](terraform-new-workspace)
- [dflook/terraform-destroy-workspace](terraform-destroy-workspace)

[1.48.0]: https://github.com/dflook/terraform-github-actions/compare/v1.47.0...v1.48.0
[1.47.0]: https://github.com/dflook/terraform-github-actions/compare/v1.46.1...v1.47.0
[1.46.1]: https://github.com/dflook/terraform-github-actions/compare/v1.46.0...v1.46.1
[1.46.0]: https://github.com/dflook/terraform-github-actions/compare/v1.45.0...v1.46.0
Expand Down
33 changes: 17 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,23 @@ Currently, there is just experimental support for OpenTofu, see [here](https://g

See the documentation for the available actions:

| Terraform | OpenTofu |
|--------------------------------------------------------------------|---------------------------------------------------------|
| [dflook/terraform-plan](terraform-plan) | [dflook/tofu-plan](tofu-plan) |
| [dflook/terraform-apply](terraform-apply) | [dflook/tofu-apply](tofu-apply) |
| [dflook/terraform-output](terraform-output) | [dflook/tofu-output](tofu-output) |
| [dflook/terraform-remote-state](terraform-remote-state) | [dflook/tofu-remote-state](tofu-remote-state) |
| [dflook/terraform-validate](terraform-validate) | [dflook/tofu-validate](tofu-validate) |
| [dflook/terraform-fmt-check](terraform-fmt-check) | [dflook/tofu-fmt-check](tofu-fmt-check) |
| [dflook/terraform-fmt](terraform-fmt) | [dflook/tofu-fmt](tofu-fmt) |
| [dflook/terraform-check](terraform-check) | [dflook/tofu-check](tofu-check) |
| [dflook/terraform-new-workspace](terraform-new-workspace) | [dflook/tofu-new-workspace](tofu-new-workspace) |
| [dflook/terraform-destroy-workspace](terraform-destroy-workspace) | [dflook/tofu-destroy-workspace](tofu-destroy-workspace) |
| [dflook/terraform-destroy](terraform-destroy) | [dflook/tofu-destroy](tofu-destroy) |
| [dflook/terraform-version](terraform-version) | [dflook/tofu-version](tofu-version) |
| [dflook/terraform-unlock-state](terraform-unlock-state) | [dflook/tofu-unlock-state](tofu-unlock-state) |
| [dflook/terraform-test](terraform-test) | [dflook/tofu-test](tofu-test) |
| Terraform | OpenTofu |
|-------------------------------------------------------------------|---------------------------------------------------------|
| [dflook/terraform-plan](terraform-plan) | [dflook/tofu-plan](tofu-plan) |
| [dflook/terraform-apply](terraform-apply) | [dflook/tofu-apply](tofu-apply) |
| [dflook/terraform-output](terraform-output) | [dflook/tofu-output](tofu-output) |
| [dflook/terraform-remote-state](terraform-remote-state) | [dflook/tofu-remote-state](tofu-remote-state) |
| [dflook/terraform-validate](terraform-validate) | [dflook/tofu-validate](tofu-validate) |
| [dflook/terraform-fmt-check](terraform-fmt-check) | [dflook/tofu-fmt-check](tofu-fmt-check) |
| [dflook/terraform-fmt](terraform-fmt) | [dflook/tofu-fmt](tofu-fmt) |
| [dflook/terraform-check](terraform-check) | [dflook/tofu-check](tofu-check) |
| [dflook/terraform-new-workspace](terraform-new-workspace) | [dflook/tofu-new-workspace](tofu-new-workspace) |
| [dflook/terraform-destroy-workspace](terraform-destroy-workspace) | [dflook/tofu-destroy-workspace](tofu-destroy-workspace) |
| [dflook/terraform-destroy](terraform-destroy) | [dflook/tofu-destroy](tofu-destroy) |
| [dflook/terraform-version](terraform-version) | [dflook/tofu-version](tofu-version) |
| [dflook/terraform-unlock-state](terraform-unlock-state) | [dflook/tofu-unlock-state](tofu-unlock-state) |
| [dflook/terraform-test](terraform-test) | [dflook/tofu-test](tofu-test) |
| [dflook/terraform-refresh](terraform-refresh) | [dflook/tofu-refresh](tofu-refresh) |

## Example Usage

Expand Down
1 change: 1 addition & 0 deletions docs-gen/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ def assert_ordering(self):
"replace",
"target",
"destroy",
"refresh",
"plan_path",
"auto_approve",
"add_github_comment",
Expand Down
4 changes: 3 additions & 1 deletion docs-gen/actions/apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from inputs.parallelism import parallelism
from inputs.path import path
from inputs.plan_path import plan_path as plan_path_input
from inputs.refresh import refresh
from inputs.replace import replace
from inputs.target import target
from inputs.var_file import var_file
Expand Down Expand Up @@ -83,6 +84,7 @@
Set to `true` to destroy all resources.

This generates and applies a plan in [destroy mode]($DestroyModeUrl).'''),
refresh,
plan_path_input,
auto_approve,
parallelism
Expand Down Expand Up @@ -339,4 +341,4 @@
auto_approve: true
```
'''
)
)
4 changes: 3 additions & 1 deletion docs-gen/actions/plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from inputs.label import label
from inputs.parallelism import parallelism
from inputs.path import path
from inputs.refresh import refresh
from inputs.replace import replace
from inputs.target import target
from inputs.var import var
Expand Down Expand Up @@ -57,6 +58,7 @@
replace,
target,
destroy,
refresh,
add_github_comment,
parallelism
],
Expand Down Expand Up @@ -251,4 +253,4 @@
path: my-$ToolName-config
```
'''
)
)
62 changes: 62 additions & 0 deletions docs-gen/actions/refresh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import dataclasses

from action import Action
from environment_variables.GITHUB_DOT_COM_TOKEN import GITHUB_DOT_COM_TOKEN
from environment_variables.TERRAFORM_CLOUD_TOKENS import TERRAFORM_CLOUD_TOKENS
from environment_variables.TERRAFORM_HTTP_CREDENTIALS import TERRAFORM_HTTP_CREDENTIALS
from environment_variables.TERRAFORM_PRE_RUN import TERRAFORM_PRE_RUN
from environment_variables.TERRAFORM_SSH_KEY import TERRAFORM_SSH_KEY
from inputs.backend_config import backend_config
from inputs.backend_config_file import backend_config_file
from inputs.parallelism import parallelism
from inputs.path import path
from inputs.var_file import var_file
from inputs.variables import variables
from inputs.workspace import workspace
from inputs.target import target
from outputs.failure_reason import failure_reason
from outputs.lock_info import lock_info
from outputs.run_id import run_id

refresh = Action(
'refresh',
'''
This actions runs a $ProductName apply operation in refresh-only mode.
This will synchronise the $ProductName state with the actual resources, but will not make any changes to the resources.
''',
meta_description='Refresh $ProductName state',
inputs=[
dataclasses.replace(path, description="Path to the $ProductName root module to refresh state for"),
dataclasses.replace(workspace, description="$ProductName workspace to run the refresh state in"),
variables,
var_file,
backend_config,
backend_config_file,
dataclasses.replace(target, description='''
List of resources to target, one per line.
The refresh will be limited to these resources and their dependencies.
'''),
parallelism
],
outputs=[
dataclasses.replace(failure_reason, description='''
When the job outcome is `failure`, this output may be set. The value may be one of:

- `refresh-failed` - The $ProductName apply operation failed.
- `state-locked` - The Terraform state lock could not be obtained because it was already locked.

If the job fails for any other reason this will not be set.
This can be used with the Actions expression syntax to conditionally run steps.
'''
),
lock_info,
run_id
],
environment_variables=[
GITHUB_DOT_COM_TOKEN,
TERRAFORM_CLOUD_TOKENS,
TERRAFORM_SSH_KEY,
TERRAFORM_HTTP_CREDENTIALS,
TERRAFORM_PRE_RUN,
]
)
Loading
Loading