Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DAT-16244

DevOps :: Spacelift replacement of Terraform Cloud #107

Merged
merged 63 commits into from
Jan 16, 2024

Conversation

jandroav
Copy link
Contributor

@jandroav jandroav commented Jan 5, 2024

Hey @mcred this PR is part of the https://datical.atlassian.net/browse/DAT-16244 effort to migrate from Terraform Cloud to Spacelift because of their pricing policy changes.

I was struggling for several days on how to keep executing regular terraform commands to make this workflow work almost without any changes but I found that Spacelift locks the remote state and there is no way to apply local changes to the remote backend: https://spacelift.io/blog/terraform-remote-state-with-spacelift

Unfortunately, since the state is locked by Spacelift, you cannot run the Terraform Console against the remote state unless you pull it locally. I say “unfortunately” because you may wish to use it, but just remember that running commands that could possibly modify your remote state from the CLI is actually extremely disadvised. Hence, it’s probably best that this lock stays in place.

After checking with the Spacelift support team they suggested we use their spacectl CLI to do what we need.

With spacectl stack local-preview we can perform a plan in the current build directory but spacectl can't deploy changes from a feature branch (spacectl stack deploy). The deploy command only runs stuff for the remote tracking branch (main) so changes must be merged in the main branch.

The last limitation they have is that the remote deployment will only take into account the files pushed to the repo. This means commands.json must be in the repo.

With all of the above, I was able to make some changes and successfully tested it. I reverted all changes from the main branch and recreated this PR so you @mcred can review them:

  • Setup Terraform step is not needed anymore
  • .terraform.lock.hcl not needed anymore
  • Terraform backend config not needed anymore
  • Added a step to commit and push commands.json changes
  • Added a check to deploy infra if the build is from the main branch

jandroav and others added 30 commits January 3, 2024 14:00
…to create-action-repo job

chore(generate.yml): remove TF_VAR_BOT_TOKEN environment variable from plan and apply steps
chore(main.tf): update terraform backend configuration to use remote backend on spacelift.io for the liquibase organization and workspace "liquibase-github-actions"
… Spacelift.io as the backend

feat(main.tf): configure Terraform to use the "liquibase-github-actions" workspace in the "liquibase" organization on Spacelift.io as the backend
The Terraform setup step was removed because it is not needed for the current workflow.
…API key

fix(generate.yml): add -lock=false flag to terraform plan and terraform apply commands to prevent locking the state file during execution
…vide the admin token for the generator action repository

chore(generate.yml): add environment variable TF_TOKEN_spacelift_io to provide the Spacelift API key for the generator action repository
DAT-16244
DevOps :: Spacelift replacement of Terraform Cloud
… Spacelift.io as the backend

feat(main.tf): configure Terraform to use the "liquibase-github-actions" workspace in the "liquibase" organization on Spacelift.io as the backend
… apply command

The -lock=false flag is not necessary for the terraform apply command. Removing it improves the readability of the command and avoids confusion.
… prevent locking the state file during apply

feat(generate.yml): add Terraform State Push step to push errored.tfstate file to remote state backend, even if previous steps failed
…te before pushing state to Terraform backend

The `generate.yml` workflow file was modified to add a `cat` command before pushing the state to the Terraform backend. This change was made to print the contents of the `errored.tfstate` file for debugging purposes.
…on in errored.tfstate file

The `generate.yml` workflow file was updated to fix an issue with the `Terraform State Push` step. The following changes were made:

- Added a command to display the contents of the `errored.tfstate` file.
- Added variables `STATE_FILE`, `current_serial`, and `new_serial` to store the current and new serial numbers.
- Incremented the current serial number by 1 and stored it in `new_serial`.
- Updated the `errored.tfstate` file by using `jq` to add the new serial number and update the terraform version.
- Added a command to display the contents of the updated `errored.tfstate` file.
- Updated the `terraform state push` command to use the updated `errored.tfstate` file with the lock disabled and force enabled.
…specific version of Terraform (1.5.7)

chore(main.tf): update backend hostname and organization to match new spacelift.io configuration
downgrade terraform version for spacelift
The unused steps in the generate.yml workflow file have been commented out to improve readability and prevent unnecessary execution of those steps.
…on 3 to ensure compatibility with the latest features and improvements

chore(generate.yml): remove unused cli_config_credentials_token parameter from hashicorp/setup-terraform action
…management

chore(main.tf): remove unnecessary workspace configuration for remote state management
…management to store state in spacelift.io organization and workspace "liquibase-github-actions"

feat(main.tf): update github_repository resource to use for_each to create multiple repositories based on local.commands, and improve resource configuration formatting for better readability
…erraform configuration

fix(main.tf): update the owner of the GitHub provider to "liquibase" to match the correct organization
refactor(main.tf): remove unused resource "github_repository" to clean up the Terraform configuration
…github-actions" for better clarity and accuracy

feat(main.tf): add resource block to create GitHub repositories based on commands defined in commands.json file, with appropriate naming and descriptions
…ked by git

feat(commands.json): add 'commands.json' file containing a list of available commands for the application
…le commands

The commands list in locals was updated to include all available commands for the Liquibase GitHub Actions. This ensures that all commands are accounted for and can be used in the Terraform configuration.
jandroav and others added 13 commits January 5, 2024 09:27
…eployment of infrastructure

chore(generate.yml): uncomment generate-action and output-action steps to enable generation and output of action
…loading it to Spacelift

fix(generate.yml): update spacectl commands to include necessary flags for local preview and deployment
…e action jobs to only run on the main branch
…tting current commit before deployment

The previous command only deployed the stack without setting the current commit. This caused issues with tracking the deployed version. The updated command now sets the current commit to the latest commit SHA before deploying the stack.
* chore(generate.yml): add environment variables for Spacelift API key to create-action-repo job
chore(generate.yml): remove TF_VAR_BOT_TOKEN environment variable from plan and apply steps
chore(main.tf): update terraform backend configuration to use remote backend on spacelift.io for the liquibase organization and workspace "liquibase-github-actions"

* chore(main.tf): remove unused backend configuration in terraform block

* chore(main.tf): add remote backend configuration for Terraform to use Spacelift.io as the backend
feat(main.tf): configure Terraform to use the "liquibase-github-actions" workspace in the "liquibase" organization on Spacelift.io as the backend

* chore(generate.yml): remove unnecessary Terraform setup step

The Terraform setup step was removed because it is not needed for the current workflow.

* chore(generate.yml): update environment variable names for Spacelift API key
fix(generate.yml): add -lock=false flag to terraform plan and terraform apply commands to prevent locking the state file during execution

* chore(generate.yml): add environment variable TF_VAR_BOT_TOKEN to provide the admin token for the generator action repository
chore(generate.yml): add environment variable TF_TOKEN_spacelift_io to provide the Spacelift API key for the generator action repository

* chore(main.tf): remove unused backend configuration in terraform file

* chore(main.tf): add remote backend configuration for Terraform to use Spacelift.io as the backend
feat(main.tf): configure Terraform to use the "liquibase-github-actions" workspace in the "liquibase" organization on Spacelift.io as the backend

* fix(generate.yml): remove unnecessary -lock=false flag from terraform apply command

The -lock=false flag is not necessary for the terraform apply command. Removing it improves the readability of the command and avoids confusion.

* fix(generate.yml): add -lock=false flag to terraform apply command to prevent locking the state file during apply
feat(generate.yml): add Terraform State Push step to push errored.tfstate file to remote state backend, even if previous steps failed

* fix(generate.yml): update Terraform State Push step to disable locking to prevent errors during state push

* fix(generate.yml): add -force flag to terraform state push command to force push the errored.tfstate file

* fix(generate.yml): add cat command to print contents of errored.tfstate before pushing state to Terraform backend

The `generate.yml` workflow file was modified to add a `cat` command before pushing the state to the Terraform backend. This change was made to print the contents of the `errored.tfstate` file for debugging purposes.

* fix(generate.yml): increment serial number and update terraform version in errored.tfstate file

The `generate.yml` workflow file was updated to fix an issue with the `Terraform State Push` step. The following changes were made:

- Added a command to display the contents of the `errored.tfstate` file.
- Added variables `STATE_FILE`, `current_serial`, and `new_serial` to store the current and new serial numbers.
- Incremented the current serial number by 1 and stored it in `new_serial`.
- Updated the `errored.tfstate` file by using `jq` to add the new serial number and update the terraform version.
- Added a command to display the contents of the updated `errored.tfstate` file.
- Updated the `terraform state push` command to use the updated `errored.tfstate` file with the lock disabled and force enabled.

* chore(main.tf): add required_version to terraform block to enforce a specific version of Terraform (1.5.7)
chore(main.tf): update backend hostname and organization to match new spacelift.io configuration

* downgrade terraform version for spacelift

* chore(generate.yml): comment out unused steps in the workflow file

The unused steps in the generate.yml workflow file have been commented out to improve readability and prevent unnecessary execution of those steps.

* chore(generate.yml): update hashicorp/setup-terraform action to version 3 to ensure compatibility with the latest features and improvements
chore(generate.yml): remove unused cli_config_credentials_token parameter from hashicorp/setup-terraform action

* chore(main.tf): remove unused backend configuration for remote state management
chore(main.tf): remove unnecessary workspace configuration for remote state management

* chore(main.tf): add remote backend configuration for Terraform state management to store state in spacelift.io organization and workspace "liquibase-github-actions"
feat(main.tf): update github_repository resource to use for_each to create multiple repositories based on local.commands, and improve resource configuration formatting for better readability

* chore(main.tf): remove unused backend configuration to simplify the Terraform configuration
fix(main.tf): update the owner of the GitHub provider to "liquibase" to match the correct organization
refactor(main.tf): remove unused resource "github_repository" to clean up the Terraform configuration

* chore(main.tf): update provider owner from "liquibase" to "liquibase-github-actions" for better clarity and accuracy
feat(main.tf): add resource block to create GitHub repositories based on commands defined in commands.json file, with appropriate naming and descriptions

* chore(.gitignore): remove unused 'commands.json' file from being tracked by git

feat(commands.json): add 'commands.json' file containing a list of available commands for the application

* chore(main.tf): update commands list in locals to include all available commands

The commands list in locals was updated to include all available commands for the Liquibase GitHub Actions. This ensures that all commands are accounted for and can be used in the Terraform configuration.

* chore(main.tf): refactor commands variable to use double quotes for consistency and readability

* chore(.gitignore): add commands.json to the list of ignored files
feat(main.tf): add remote backend configuration for Terraform to store state in spacelift.io organization workspace "liquibase-github-actions"
refactor(main.tf): replace hardcoded commands list with reading commands from commands.json file

* fix(generate.yml): add -lock=false flag to the terraform plan command to disable locking and prevent potential issues with concurrent runs

* chore(generate.yml): uncomment Terraform Apply and Terraform State Push steps

chore(generate.yml): uncomment generate-action and output-action steps

The Terraform Apply and Terraform State Push steps were uncommented to enable the execution of Terraform apply and state push commands. This is necessary for the deployment and management of infrastructure resources.

The generate-action and output-action steps were also uncommented to enable the generation of commands and the output of the action edit link. These steps are crucial for the overall workflow and automation process.

* chore(generate.yml): remove Terraform State Push step from the workflow

The Terraform State Push step was removed from the workflow as it was causing errors and is no longer needed.

* chore(generate.yml): remove trailing whitespace to improve code readability

* chore(terraform): add .terraform.lock.hcl file to track provider version and constraints

A new file `.terraform.lock.hcl` has been added to the repository. This file is automatically maintained by `terraform init` command and should not be manually edited. It tracks the version and constraints of the provider `registry.terraform.io/integrations/github`. The current version is `4.31.0` and the constraints are set to `~> 4.0`. The file includes a list of hashes for the provider's artifacts to ensure integrity and security.

* chore(.terraform.lock.hcl): add newline at the end of the file for consistency and to adhere to best practices

* fix(generate.yml): add `-reconfigure` flag to `terraform init` command to ensure proper initialization of the Terraform workspace
feat(generate.yml): add steps to pull and push the current state file to/from the Terraform backend to ensure consistency and synchronization

* fix(generate.yml): add -lock=false flag to the terraform state push command to disable locking when pushing state

* fix(generate.yml): change output file name from current_state.tfstate to current.tfstate in the Terraform Pull state step
fix(generate.yml): add terraform init -force-copy -backend=false command in the Terraform Pull state step to ensure a clean initialization
fix(generate.yml): add terraform init -reconfigure command in the Terraform Push state step to reconfigure the backend before pushing the state
fix(generate.yml): change output file name from current_state.tfstate to current.tfstate in the Terraform Push state step

* chore(generate.yml): update workflow to install spacectl instead of terraform and add support for local preview of infrastructure changes

chore(main.tf): remove backend configuration for remote state as it is no longer needed with the switch to spacectl

* fix(generate.yml): update spacectl command to use 'preview' instead of 'local-preview' for consistency with other commands

* chore(generate.yml): comment out unused workflow steps to improve readability and reduce noise in the file

* fix(generate.yml): change 'spacectl stack preview' command to 'spacectl stack local-preview' to run the stack locally instead of in the cloud

* fix(main.tf): fix file path for commands.json to be relative to the current directory instead of the module directory

* chore(generate.yml): add ls -ltr command before running spacectl stack local-preview to debug the issue
fix(main.tf): fix the path to commands.json file to use the module path for better reliability

* chore(.gitignore): remove unused "commands.json" file from git tracking

* chore(generate.yml): remove commands.json from .gitignore to allow uploading the file to Spacelift
chore(generate.yml): update comment to explain the reason for removing commands.json from .gitignore
chore(gitignore): remove newline at end of file

* chore(generate.yml): uncomment deploy infrastructure step to enable deployment of infrastructure
chore(generate.yml): uncomment generate-action and output-action steps to enable generation and output of action

* chore(generate.yml): remove commands.json from .gitignore to allow uploading it to Spacelift
fix(generate.yml): update spacectl commands to include necessary flags for local preview and deployment

* fix(generate.yml): add condition to deploy infrastructure and generate action jobs to only run on the main branch

* fix(generate.yml): update spacectl stack deploy command to include setting current commit before deployment

The previous command only deployed the stack without setting the current commit. This caused issues with tracking the deployed version. The updated command now sets the current commit to the latest commit SHA before deploying the stack.
…ds.json file

feat(generate.yml): add workflow step to commit and push changes in commands.json file if changes are found
fix(generate.yml): remove unnecessary --commit flag from spacectl stack set-current-commit command
…cefully to the commit

fix(generate.yml): update commit message to indicate changes in commands.json file
…es to prevent it from being tracked by git
…commands.json

fix(generate.yml): allow commit and push step to continue even if there are errors to prevent workflow failure
commands.json Outdated
@@ -0,0 +1 @@
["calculate-checksum","changelog-sync","changelog-sync-sql","changelog-sync-to-tag","changelog-sync-to-tag-sql","checks bulk-set","checks copy","checks create","checks customize","checks delete","checks disable","checks enable","checks reset","checks run","checks show","clear-checksums","connect","db-doc","diff","diff-changelog","drop-all","execute-sql","flow","flow validate","future-rollback-count-sql","future-rollback-from-tag-sql","future-rollback-sql","generate-changelog","history","init copy","init project","init start-h2","list-locks","mark-next-changeset-ran","mark-next-changeset-ran-sql","release-locks","rollback","rollback-count","rollback-count-sql","rollback-one-changeset","rollback-one-changeset-sql","rollback-one-update","rollback-one-update-sql","rollback-sql","rollback-to-date","rollback-to-date-sql","set-contexts","set-labels","snapshot","snapshot-reference","status","tag","tag-exists","unexpected-changesets","update","update-count","update-count-sql","update-one-changeset","update-one-changeset-sql","update-sql","update-testing-rollback","update-to-tag","update-to-tag-sql","validate"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file shouldn't be in version control IMO. It's only used between steps during automation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @mcred I agree with you but Spacelift deploys the stuff which is only in the repository. Spacelift can only "user" local files for previewing. Spacelift can perform some kind of terraform planning using the current working directory, but it will only deploy pushed stuff. We could remove the file from the repo after executing the spacectl stack deploy --id liquibase-github-actions --auto-confirm command.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"will only deploy pushed stuff" seems problematic. Would this mean that during automation we would need to update the file, push it to the repo, and then let spacelift check it out?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are already updating the file with

run: make create-list VERSION=$LIQUIBASE_VERSION

The only change is about pushing the file if there are changes on it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @mcred I think we can do the following to not push the file.

We can run the following spacectl command before deploying stuff:

spacectl stack environment mount [command options] RELATIVE_PATH_TO_MOUNT [FILE_PATH]
spacectl stack environment mount --id liquibase-github-actions commands.json commands.json 

That command will mount the commands.json file in the Spacelift backend ready to be used by Terraform:

SCR-20240111-hezn

I have updated the PR with the change. Please tell me if this works better.

@jandroav jandroav requested a review from mcred January 8, 2024 08:43
… changes step

chore(generate.yml): mount commands.json file to the stack environment instead of committing and pushing changes
chore(commands.json): delete commands.json file as it is no longer needed
@jandroav jandroav requested review from jnewton03, sayaliM0412 and mcred and removed request for mcred January 11, 2024 06:40
@jandroav jandroav merged commit 74dd8d2 into main Jan 16, 2024
2 checks passed
@jandroav jandroav deleted the DAT-16244 branch January 16, 2024 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants