DEV Community

Cover image for βš‘πŸ’Ύβš‘ Storing your Terraform statefile as a Github workflow artifact with the terraform_state_artifact action !
sturlabragason
sturlabragason

Posted on • Updated on

βš‘πŸ’Ύβš‘ Storing your Terraform statefile as a Github workflow artifact with the terraform_state_artifact action !

My Workflow :

When I wanted to start managing my Github with Terraform using the integrations/terraform-provider-github I felt that my terraform statefile should belong with the code, and not as a remote state in Azure/AWS/etc.

I couldn't find a suitable solution so I decided to roll my own:

It took me a while to figure out but I finally settled on keeping my state as a workflow artifact that is de/encrypted on each run. I decided to create my first action out of the whole thing only to find out that there actually was an #ActionsHackathon21 going on!

πŸš€ What this action does: πŸš€

  • πŸ› οΈ First off, it downloads your repository with actions/checkout@v2 and then installs terraform using hashicorp/setup-terraform@v1.
  • πŸ“₯ Using environment variables it downloads the most recent workflow artifact 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.
  • πŸ—οΈ It then proceeds to run terraform plan with any flags from the optional variable custom_plan_flags
  • 🏒 Next it runs terraform apply with any flags from the optional variablecustom_apply_flags.
    • This can be skipped by setting the optional variable apply to false.
  • πŸ—ƒοΈ If all is well then Terraform has now produced a statefile ./terraform.tfstate. This file is encrypted using the provided encryptionkey.
  • πŸ’Ύ Finally the new statefile is uploaded as an artifact!

    - πŸŽ‰ Lather, rinse, repeat! πŸŽ‰

Submission Category:

DIY Deployments

Yaml File or Link to Code :

Here is an example to get you started:

steps:
- uses: sturlabragason/terraform_state_artifact@v1
    with:
        encryptionkey: ${{ secrets.encryptionkey }}
Enter fullscreen mode Exit fullscreen mode

GitHub logo sturlabragason / terraform_state_artifact

The terraform_state_artifact action is a composite action that stores your Terraform state file as an encrypted Github workflow artifact.

terraform_state_artifact

Terraform State Artifact #actionshackathon21

The 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, hashicorp/setup-terraform@v1 and actions/upload-artifact@v2.

Be aware that Github delets artifacts older then 90 days by default. You can run your pipeline on a schedule to create a new artifact at least once every 90 days.

πŸš€ What this action does: πŸš€

  • πŸ› οΈ First off, it downloads your repository with actions/checkout@v2 and then installs terraform using hashicorp/setup-terraform@v1.
  • πŸ“₯ Using environment variables it downloads the most recent workflow artifact 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.
  • πŸ—οΈ It then proceeds to run terraform plan with any flags from the optional variable custom_plan_flags
  • …

Top comments (3)

Collapse
 
bryantson profile image
Bryant Son

Thank you for creating this. After testing few things, one caveat is that GitHub artifact download URL only last for one minute. Thus, this probably worked well for hackathon because your script immediately uploaded to artifact and downloaded within 1 minute. However, most real production scenarios will require Terraform states to last for quite sometime.

Collapse
 
dennislwm profile image
dennislwm

Thanks for the article!

How do you handle the issue that your Terraform state file will be deleted, as "by default, the artifacts and log files generated by workflows are retained for 90 days before they are automatically deleted"?

Collapse
 
sturlabragason profile image
sturlabragason • Edited

That's an excellent point @dennislwm that, truth be told, I hadn't thought of.

Reading the log retention docs tells me I don't have a lot of options so my first thought would be to run whatever pipeline that uses the action on a cron schedule. I'd guess that most pipelines using this could handle that, likely being stateful.

I'll make sure to mention it in the action's footnotes, thanks!πŸ‘

Edit: I've added it to the readme! Thanks πŸ”₯