Best practices for terraform with Nomad provider in CI/CD?

Before getting into terraform & nomad, we have k8s and Jenkins.
Using Jenkins’s pipeline and k8s-CD plugin, it is quite easy to deploy to k8s cluster.

However, we introduced Nomad later.
There is no Nomad-CD plugin for Jenkins,
then we bridged that gap with terraform.

The final CI/CD would be Jenkins => CLI terraform => Nomad.

The only thing I have not figured out is how to handle terraform’s tfstate.

We are doing CI/CD, it is somehow awkward to check tfstate back into gitlab;
and to further my confusion, the tfstate seems to make less sense with Nomad provider,
since Nomad should be quite enough for state management.

So I suppose I could simply forget the tfstate in the CI/CD, just as k8s-CD plugin for Jenkins, any suggestions?

not sure, but you might already know about this; the WIKI page doesn’t seem to be updated, the github releases are updated though.

https://wiki.jenkins.io/display/JENKINS/Nomad+Plugin

I thought that is for “build slave”, not for “deploy” purposes;
Correct me, if I get anything wrong.

Hi @liuzhen,

Nomad does not have any facility to store the Terraform state. The usual answer is to use remote state with one of the backends supported by Terraform, depending on what other infrastructure you have available to use for state storage.

The most straightforward answer is free state storage with Terraform Cloud, which doesn’t require any additional infrastructure on your end as long as the host running Terraform can reach the Terraform Cloud API. However, Terraform also supports remote state directly in Amazon S3, Azure blob storage, in HashiCorp Consul, and various others.

@apparentlymart
That helped.

I am quite new to both Terraform & Nomad.
I was not saying that Nomad has facility to store Terraform state. I was simply referring
to Nomad (and Kubernetes) declarative spec, by which, I assume, they have to
maintain (or load) internal state to produce actions.

The biggest question seems to be do I have to store the terraform state when using Nomad.
I get the idea when Terraform-ing other infrastructures, they have to be taken more seriously.

I do have consul and knew of Terraform Backend;
When in pure CI (CD excluded), I to a degree don’t care about the state rigorously maintained by Terraform (righteously?).

And even in CD for services, we as a small team did not care about the explicit state.

Maybe it is time for us to build up the (mind) state now?

Aside from other uses, Terraform uses its state to keep track of which objects it is already managing vs. which objects either don’t exist yet or are being managed by some other system.

If you don’t retain the state, Terraform will always think it needs to create the resources described in the configuration, because it uses the state to keep track of that fact that it already created them. Keep in mind that Terraform expects to run in a mixed environment where some objects are created by other Terraform configurations or by other software entirely, so Terraform does not assume that something is managed by it just because it exists in the remote system.

It’d be possible in principle for you to write some custom software that can read enough information from the running Nomad cluster to construct a synthetic Terraform state that could trick Terraform into thinking the state was saved in the usual way, but that is not a supported usage pattern and it might be quite difficult to get the details right.

So let Terraform create every time,
as long as the job name is the same, Nomad will figure out what has to be done
to fulfil the request, am I right though?

@apparentlymart


I recently received the HashiCorp white paper of Shifting from Static to Dynamic Infrastructure

Putting into the scene depicted in the white paper, I start to get the idea and what you said “Keep in mind that Terraform expects to run in a mixed environment …”

It is a bigger jump than I thought.