Skip to content

Commit

Permalink
download_upload
Browse files Browse the repository at this point in the history
  • Loading branch information
sturlabragason committed May 15, 2022
1 parent aed4c48 commit 0a84363
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 75 deletions.
46 changes: 10 additions & 36 deletions .github/workflows/terraform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,21 @@ on:


jobs:
terraform_default_job:
terraform_download_job:
runs-on: ubuntu-latest
name: Using terraform_state_artifact action
name: Downloading terraform_state_artifact
steps:
- id: terrafrom_state_artifact
uses: sturlabragason/terraform_state_artifact@v1
- id: terrafrom_artifact_download
uses: sturlabragason/terraform_state_artifact@v2
with:
encryptionkey: ${{ secrets.pat }}
env:
TF_VAR_run_id: ${{ github.run_id }}
terraform_apply_false_job:
download_upload: download
terraform_upload_job:
runs-on: ubuntu-latest
name: Using terraform_state_artifact action without apply
name: Uploading terraform_state_artifact
steps:
- id: terraform_apply_false
uses: sturlabragason/terraform_state_artifact@v1
- id: terrafrom_artifact_upload
uses: sturlabragason/terraform_state_artifact@v2
with:
encryptionkey: ${{ secrets.pat }}
apply: false
env:
TF_VAR_run_id: ${{ github.run_id }}
terraform_plan_custom_job:
runs-on: ubuntu-latest
name: Using terraform_state_artifact with custom plan flag
steps:
- id: terraform_plan_custom
uses: sturlabragason/terraform_state_artifact@v1
with:
encryptionkey: ${{ secrets.pat }}
apply: false
custom_plan_flags: '-refresh-only'
env:
TF_VAR_run_id: ${{ github.run_id }}
terraform_apply_custom_job:
runs-on: ubuntu-latest
name: Using terraform_state_artifact with custom apply flag
steps:
- id: terraform_apply_custom
uses: sturlabragason/terraform_state_artifact@v1
with:
encryptionkey: ${{ secrets.pat }}
custom_apply_flags: '-no-color'
env:
TF_VAR_run_id: ${{ github.run_id }}
download_upload: upload
16 changes: 7 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
[![Terraform State Artifact](https://github.com/sturlabragason/terraform_state_artifact/actions/workflows/terraform.yml/badge.svg)](https://github.com/sturlabragason/terraform_state_artifact/actions/workflows/terraform.yml)
`#actionshackathon21`

The [`sturlabragason/terraform_state_artifact`](https://github.com/sturlabragason/terraform_state_artifact) action is a composite action that stores your Terraform state file as an encrypted Github workflow artifact and downloads and decrypts the state on subsequent runs. Built-in are the actions: [`actions/checkout@v2`](https://github.com/actions/checkout), [`hashicorp/setup-terraform@v1`](https://github.com/hashicorp/setup-terraform) and [`actions/upload-artifact@v2`](https://github.com/actions/upload-artifact).
The [`sturlabragason/terraform_state_artifact`](https://github.com/sturlabragason/terraform_state_artifact) action is a composite action that stores your Terraform state file as an encrypted Github workflow artifact and downloads and decrypts the state on subsequent runs. Built-in are the actions: [`actions/checkout@v2`](https://github.com/actions/checkout), [`hashicorp/setup-terraform@v2`](https://github.com/hashicorp/setup-terraform) and [`actions/upload-artifact@v2`](https://github.com/actions/upload-artifact).

Be aware that [Github delets artifacts older then 90 days](https://docs.github.com/en/organizations/managing-organization-settings/configuring-the-retention-period-for-github-actions-artifacts-and-logs-in-your-organization) by default. You can [run your pipeline on a schedule](https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows#scheduled-events) to create a new artifact at least once every 90 days.

## [:rocket: What this action does: :rocket:](https://dev.to/sturlabragason/terraformstateartifact-github-action-keeping-the-statefile-with-to-your-code-4d3b)

- 🛠️ First off, it downloads your repository with [`actions/checkout@v2`](https://github.com/actions/checkout) and then installs terraform using [`hashicorp/setup-terraform@v1`](https://github.com/hashicorp/setup-terraform).
- 🛠️ First off, it downloads your repository with [`actions/checkout@v2`](https://github.com/actions/checkout) and then installs terraform using [`hashicorp/setup-terraform@v2`](https://github.com/hashicorp/setup-terraform).
- :inbox_tray: Using [environment variables](https://docs.github.com/en/actions/learn-github-actions/environment-variables) it downloads the most recent [workflow artifact](https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts) called `terraformstatefile` and decrypts using the user input variable `encryptionkey`.
- If no artifact with that name is found (maybe it's your first run) then it proceeds with the following.
- :building_construction: It then proceeds to run `terraform plan` with any flags from the optional variable `custom_plan_flags`
Expand All @@ -24,7 +24,7 @@ Be aware that [Github delets artifacts older then 90 days](https://docs.github.c

```yaml
steps:
- uses: sturlabragason/terraform_state_artifact@v1
- uses: sturlabragason/terraform_state_artifact@v2
with:
encryptionkey: ${{ secrets.encryptionkey }}
```
Expand All @@ -33,7 +33,7 @@ You can choose to skip `terraform apply`:

```yaml
steps:
- uses: sturlabragason/terraform_state_artifact@v1
- uses: sturlabragason/terraform_state_artifact@v2
with:
encryptionkey: ${{ secrets.encryptionkey }}
apply: false
Expand All @@ -43,7 +43,7 @@ You can choose to add custom flags to `terraform plan`:

```yaml
steps:
- uses: sturlabragason/terraform_state_artifact@v1
- uses: sturlabragason/terraform_state_artifact@v2
with:
encryptionkey: ${{ secrets.encryptionkey }}
apply: false
Expand All @@ -54,7 +54,7 @@ You can choose to add custom flags to `terraform apply`:

```yaml
steps:
- uses: sturlabragason/terraform_state_artifact@v1
- uses: sturlabragason/terraform_state_artifact@v2
with:
encryptionkey: ${{ secrets.encryptionkey }}
custom_apply_flags: '-no-color'
Expand All @@ -67,9 +67,7 @@ The action supports the following inputs:
| Variable | Description | Default |
|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------|---------|
| `encryptionkey` | An encryption key to use when encrypting the statefile. Recommended to use a secret value. | N/A |
| `apply` | (optional) Whether to run the `terraform apply` command. | `true` |
| `custom_plan_flags` | (optional) Add a custom flag to the `terraform plan` command. | `''` |
| `custom_apply_flags` | (optional) Add a custom flag to the `terraform apply` command. | `''` |
| `statefile_location` | (optional) Add a custom flag to the `terraform plan` command. | `''` |

## License

Expand Down
50 changes: 20 additions & 30 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,63 +1,53 @@
name: 'terraform_state_artifact'
description: 'Sets up and runs Terraform, and creates an encrypted Terraform artifact'
description: 'Downloads and uploads your Terraform statefile as an encrypted Github Artifact'
author: 'Sturla Bragason'
inputs:
encryptionkey:
description: 'Used to read artifact and as a key to encrypt and decrypt the state file artifact'
description: 'Used as a key to encrypt and decrypt the statefile artifact'
required: true
apply:
description: 'terraform apply'
required: false
default: true
custom_plan_flags:
description: 'Add custom flags to the terraform plan command'
statefile_location:
description: 'Specify the location of your Terraform statefile.'
required: false
default: ''
custom_apply_flags:
description: 'Add custom flags to the terraform apply command'
required: false
download_upload:
description: 'Specify whether to download and decrypt or upload and encrypt.'
required: true
default: ''
runs:
using: "composite"
steps:
- uses: actions/checkout@v2
- uses: hashicorp/setup-terraform@v1
- id: terraform
- id: terraform_state_artifact_download
if: ${{ github.event.inputs.download_upload == 'download' }}
run: |
$ArtifactName = "${{ github.ref_name }}" + "${{ inputs.statefile_location }}"
$Repo = "${{ github.repository }}"
$BaseUri = "https://api.github.com"
$ArtifactUri = "$BaseUri/repos/$Repo/actions/artifacts"
$Token = "${{ github.token }}" | ConvertTo-SecureString -AsPlainText
$RestResponse = Invoke-RestMethod -Authentication Bearer -Uri $ArtifactUri -Token $Token | Select-Object -ExpandProperty artifacts
if ($RestResponse){
$MostRecentArtifactURI = $RestResponse | Sort-Object -Property created_at -Descending | where name -eq "terraformstatefile" | Select-Object -First 1 | Select-Object -ExpandProperty archive_download_url
$MostRecentArtifactURI = $RestResponse | Sort-Object -Property created_at -Descending | where name -eq $ArtifactName | Select-Object -First 1 | Select-Object -ExpandProperty archive_download_url
Write-Host "Most recent artifact URI = $MostRecentArtifactURI"
if ($MostRecentArtifactURI){
Invoke-RestMethod -uri $MostRecentArtifactURI -Token $Token -Authentication bearer -outfile ./state.zip
Expand-Archive ./state.zip
openssl enc -d -in ./state/terraform.tfstate.enc -aes-256-cbc -pbkdf2 -pass pass:"${{ inputs.encryptionkey }}" -out ./terraform.tfstate
openssl enc -d -in ./state/terraform.tfstate.enc -aes-256-cbc -pbkdf2 -pass pass:"${{ inputs.encryptionkey }}" -out ."${{ inputs.statefile_location }}"/terraform.tfstate
}
}
terraform init
$terraformapply = "${{ inputs.apply }}"
$custom_plan_flags = "${{ inputs.custom_plan_flags }}"
$custom_apply_flags = "${{ inputs.custom_apply_flags }}"
if ($terraformapply -eq "false"){
$terraformapply = $false
}
terraform plan $custom_plan_flags
if ($terraformapply){
terraform apply -auto-approve $custom_apply_flags
}
$StateExists = Test-Path -Path ./terraform.tfstate -PathType Leaf
shell: pwsh
- id: terraform_state_artifact_upload
if: ${{ github.event.inputs.download_upload == 'upload' }}
run: |
$ArtifactName = "${{ github.ref_name }}" + "${{ inputs.statefile_location }}"
$StateExists = Test-Path -Path ."${{ inputs.statefile_location }}"/terraform.tfstate -PathType Leaf
if ($StateExists){
openssl enc -in ./terraform.tfstate -aes-256-cbc -pbkdf2 -pass pass:"${{ inputs.encryptionkey }}" -out ./terraform.tfstate.enc
openssl enc -in ."${{ inputs.statefile_location }}"/terraform.tfstate -aes-256-cbc -pbkdf2 -pass pass:"${{ inputs.encryptionkey }}" -out ."${{ inputs.statefile_location }}"/terraform.tfstate.enc
}
shell: pwsh
- uses: actions/upload-artifact@v2
with:
name: terraformstatefile
path: ./terraform.tfstate.enc
path: ."${{ inputs.statefile_location }}"/terraform.tfstate.enc
branding:
icon: 'cloud'
color: 'gray-dark'

0 comments on commit 0a84363

Please sign in to comment.