Terraform Provider¶
This proposal suggests how to approach the implementation of a Terraform provider for Tarmak, to make Tarmak <-> Terraform interactions within a Terraform run more straightforward.
Background¶
Right now the Terraform code for the AWS provider (the only one implemented) consists of multiple separate stacks (state, network, tools, vault, kubernetes). The Main reason for having these stacks is to enable Tarmak to do operations in between parts of the resource spin up. Examples for such operations are (list might not be complete):
- Bastion node needs to be up for other instances to check into Wing.
- Vault needs to be up and initialised, before PKI resources are created.
- Vault needs to contain a cluster’s PKI resources, before Kubernetes instances
can be created (
init-tokens
).
The separation of stacks comes with some overhead for preparing Terraform apply (pull state, lock stack, plan run, apply run). Terraform can’t make use of parallel creation of resources that are independent from each other.
Objective¶
An integration of these stacks into a single stack could lead to a substantial reduction of execution time.
As Terraform is running in a container is quite isolated from the Tarmak process:
- Requires some Terraform refactoring
- Should be done before implementing multiple providers
Changes¶
Terraform code base¶
Terraform resources¶
The proposal is to implement a Tarmak provider for Terraform, with at least these three resources.
tarmak_bastion_instance
¶
A bastion instance
Input:
- Bastion IP address or hostname
- Username for SSH
Blocks until Wing API server is running.
tarmak_vault_cluster
¶
A vault cluster
Input:
- List of Vault internal FQDNs or IP addresses
Blocks until Vault is initialised & unsealed.
tarmak_vault_instance_role
¶
This creates (once per role) an init token for such instances in Vault.
Input:
- Name of Vault cluster
- Role name
Output:
- init_token per role
Blocks until init token is setup.
Notable items¶
Communication with the process in the container¶
The main difficulty is communication with the Tarmak process, as Terraform is run within a Docker container with no communication available to the main Tarmak process (stdin/out is used by the Terraform main process).
The proposal suggests that all terraform-provider-tarmak
resources block
until the point when the main Tarmak process connects using another exec to a
so-called tarmak-connector
executable that speaks via a local Unix socket
to the terraform-provider-tarmak
.
This provides a secure and platform-independent channel between Tarmak and
terraform-provider-tarmak
.
<<Tarmak>> -- launches -- <<terraform|container>>
stdIN/OUT -- exec into ---- <<exec terraform apply>>
<<subprocess terraform-provider-tarmak
|
connects
|
unix socket
|
listens
|
stdIN/OUT -- exec into ---- <<exec tarmak-connector>>
The protocol on that channel should be using Golang’s net/rpc.
Initial proof-of-concept¶
An initial proof-of-concept has been explored to test what the Terraform model looks like. Although it’s not really having anything implemented at this point, it might serve as a starting point.
Out of scope¶
This proposal is not suggesting that we migrate features that are currently done by the Tarmak main process. The reason for that is that we don’t want Terraform to become involved in the configuration provisioning of e.g. the Vault cluster. This proposal should only improve the control we have from Tarmak over things that happen in Terraform.