diff --git a/References/terraform/index.html b/References/terraform/index.html index 8cafe554..1bafddfb 100644 --- a/References/terraform/index.html +++ b/References/terraform/index.html @@ -543,6 +543,40 @@

BackendConfigs +

BranchPlanner +

+

+(Appears on: +TerraformSpec) +

+
+
+ + + + + + + + + + + + + +
FieldDescription
+enablePathScope
+ +bool + +
+(Optional) +

EnablePathScope specifies if the Branch Planner should or shouldn’t check +if a Pull Request has changes under .spec.path. If enabled extra +resources will be created only if there are any changes in terraform files.

+
+
+

CloudSpec

@@ -2090,6 +2124,19 @@

Terraform and allow interactive shell in case of emergency.

+ + +branchPlanner
+ + +BranchPlanner + + + + +

BarnchPlanner configuration.

+ + @@ -2612,6 +2659,19 @@

TerraformSpec and allow interactive shell in case of emergency.

+ + +branchPlanner
+ + +BranchPlanner + + + + +

BarnchPlanner configuration.

+ + diff --git a/branch_planner/rc.yaml b/branch_planner/rc.yaml index 561a7222..e4723c99 100644 --- a/branch_planner/rc.yaml +++ b/branch_planner/rc.yaml @@ -21,7 +21,7 @@ spec: sourceRef: kind: HelmRepository name: tf-controller - version: '>=0.16.0-rc.2' + version: '>=0.16.0-rc.3' interval: 1h0s releaseName: tf-controller targetNamespace: flux-system @@ -46,13 +46,13 @@ spec: caCertValidityDuration: 24h certRotationCheckFrequency: 30m image: - tag: v0.16.0-rc.2 + tag: v0.16.0-rc.3 runner: image: - tag: v0.16.0-rc.2 + tag: v0.16.0-rc.3 grpc: maxMessageSize: 30 branchPlanner: enabled: true image: - tag: v0.16.0-rc.2 + tag: v0.16.0-rc.3 diff --git a/branch_planner/release.yaml b/branch_planner/release.yaml index 561a7222..e4723c99 100644 --- a/branch_planner/release.yaml +++ b/branch_planner/release.yaml @@ -21,7 +21,7 @@ spec: sourceRef: kind: HelmRepository name: tf-controller - version: '>=0.16.0-rc.2' + version: '>=0.16.0-rc.3' interval: 1h0s releaseName: tf-controller targetNamespace: flux-system @@ -46,13 +46,13 @@ spec: caCertValidityDuration: 24h certRotationCheckFrequency: 30m image: - tag: v0.16.0-rc.2 + tag: v0.16.0-rc.3 runner: image: - tag: v0.16.0-rc.2 + tag: v0.16.0-rc.3 grpc: maxMessageSize: 30 branchPlanner: enabled: true image: - tag: v0.16.0-rc.2 + tag: v0.16.0-rc.3 diff --git a/release.yaml b/release.yaml index 8341d678..a06da03f 100644 --- a/release.yaml +++ b/release.yaml @@ -21,7 +21,7 @@ spec: sourceRef: kind: HelmRepository name: tf-controller - version: '>=0.16.0-rc.2' + version: '>=0.16.0-rc.3' interval: 1h0s releaseName: tf-controller targetNamespace: flux-system @@ -46,9 +46,9 @@ spec: caCertValidityDuration: 24h certRotationCheckFrequency: 30m image: - tag: v0.16.0-rc.2 + tag: v0.16.0-rc.3 runner: image: - tag: v0.16.0-rc.2 + tag: v0.16.0-rc.3 grpc: maxMessageSize: 30 diff --git a/search/search_index.json b/search/search_index.json index a5ddcd7f..0f4b8fe3 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Overview","text":"

~> BREAKING NEWS: The Technology Preview of the Branch Planner is now available! Learn more or Get started with the Branch Planner.

TF-controller is a reliable controller for Flux to reconcile Terraform resources in the GitOps way. With the power of Flux together with Terraform, TF-controller allows you to GitOps-ify infrastructure, and application resources, in the Kubernetes and Terraform universe, at your own pace.

\"At your own pace\" means you don't need to GitOps-ify everything at once.

TF-controller offers many GitOps models:

  1. GitOps Automation Model: GitOps your Terraform resources from the provision steps to the enforcement steps, like a whole EKS cluster.
  2. Hybrid GitOps Automation Model: GitOps parts of your existing infrastructure resources. For example, you have an existing EKS cluster. You can choose to GitOps only its nodegroup, or its security group.
  3. State Enforcement Model: You have a TFSTATE file, and you'd like to use GitOps enforce it, without changing anything else.
  4. Drift Detection Model: You have a TFSTATE file, and you'd like to use GitOps just for drift detection, so you can decide to do things later when a drift occurs.

To get started, follow the getting started guide.

"},{"location":"#features","title":"Features","text":""},{"location":"#support-matrix","title":"Support Matrix","text":"Version Terraform Source Controller Flux v2 v0.15 v1.3.9 v1.0.x v2.0.x v0.14 v1.3.9 v0.31.0 v0.41.x v0.13 v1.3.1 v0.31.0 v0.36.x v0.12 v1.1.9 v0.26.1 v0.32.x"},{"location":"getting_started/","title":"Getting Started","text":""},{"location":"getting_started/#preflight-checks","title":"Preflight Checks","text":"

Here are the requirements you need to set up before you start:

  1. For Terraform Controller v0.15+, it requires Flux v2.0 or later (not only the CLI, but also the controllers on the cluster). If you are not sure about the Flux version on your cluster, please re-bootstrap your cluster.
  2. For Terraform Controller v0.13 and v0.14, Flux 2 v0.32 - v0.41 (of course, not only the CLI, but also the controllers on the cluster).
  3. TF-controller uses the Controller/Runner architecture. The Controller acts as a client, and talks to each Runner's Pod via gRPC. Please make sure
    1. Each Runner's Pod in each Namespace is allowed to open, and serve at port 30000 (the gRPC port of a Runner), and the Controller can connect to it.
    2. The Controller needs to download tar.gz BLOBs from the Source controller via port 80.
    3. The Controller needs to post the events to the Notification controller via port 80.
"},{"location":"getting_started/#installation","title":"Installation","text":"

Before using TF-controller, you have to install Flux by using either flux install or flux bootstrap command. Please note that TF-controller now requires Flux v2.0 or later, so please make sure you have the latest version of Flux. After that you can install TF-controller with Flux HelmRelease by:

kubectl apply -f https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/release.yaml\n

For the most recent release candidate of TF-controller, please use rc.yaml.

kubectl apply -f https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/rc.yaml\n
"},{"location":"getting_started/#with-branch-planner","title":"With Branch Planner","text":"
kubectl apply -f https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/branch_planner/release.yaml\n

For the most recent release candidate of TF-controller with Branch Planner, please use branch_planner/rc.yaml.

kubectl apply -f https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/branch_planner/rc.yaml\n

For more details about the Branch Planner, please visit the Branch Planner documentation.

"},{"location":"getting_started/#manual-installation","title":"Manual installation","text":"

With Helm by:

# Add tf-controller helm repository\nhelm repo add tf-controller https://weaveworks.github.io/tf-controller/\n\n# Install tf-controller\nhelm upgrade -i tf-controller tf-controller/tf-controller \\\n--namespace flux-system\n

For details on configurable parameters of the TF-controller chart, please see chart readme.

Alternatively, you can install TF-controller via kubectl:

export TF_CON_VER=v0.15.1\nkubectl apply -f https://github.com/weaveworks/tf-controller/releases/download/${TF_CON_VER}/tf-controller.crds.yaml\nkubectl apply -f https://github.com/weaveworks/tf-controller/releases/download/${TF_CON_VER}/tf-controller.rbac.yaml\nkubectl apply -f https://github.com/weaveworks/tf-controller/releases/download/${TF_CON_VER}/tf-controller.deployment.yaml\n
"},{"location":"getting_started/#quick-start","title":"Quick start","text":"

Here's a simple example of how to GitOps your Terraform resources with TF-controller and Flux.

"},{"location":"getting_started/#define-source","title":"Define source","text":"

First, we need to define a Source controller's source (GitRepository, Bucket, OCIRepository), for example:

apiVersion: source.toolkit.fluxcd.io/v1\nkind: GitRepository\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\ninterval: 30s\nurl: https://github.com/tf-controller/helloworld\nref:\nbranch: main\n
"},{"location":"getting_started/#the-gitops-automation-mode","title":"The GitOps Automation mode","text":"

The GitOps automation mode could be enabled by setting .spec.approvePlan=auto. In this mode, Terraform resources will be planned, and automatically applied for you.

apiVersion: infra.contrib.fluxcd.io/v1\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\ninterval: 1m\napprovePlan: auto\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n

For a full list of features and how to use them, please follow the Use TF-controller guide.

"},{"location":"getting_started/#other-examples","title":"Other Examples","text":""},{"location":"tfctl/","title":"tfctl","text":"

tfctl is a command-line utility to help with tf-controller operations.

"},{"location":"tfctl/#installation","title":"Installation","text":"

To install tfctl via Homebrew, run the following command:

brew install weaveworks/tap/tfctl\n

You can also download the tfctl binary via the GitHub releases page: https://github.com/weaveworks/tf-controller/releases.

Usage:\n  tfctl [command]\n\nAvailable Commands:\n  completion  Generate the autocompletion script for the specified shell\n  create      Create a Terraform resource\n  delete      Delete a Terraform resource\n  get         Get Terraform resources\n  help        Help about any command\n  install     Install the tf-controller\n  plan        Plan a Terraform configuration\n  reconcile   Trigger a reconcile of the provided resource\n  resume      Resume reconciliation for the provided resource\n  suspend     Suspend reconciliation for the provided resource\n  uninstall   Uninstall the tf-controller\n  version     Prints tf-controller and tfctl version information\n\nFlags:\n  -h, --help                help for tfctl\n      --kubeconfig string   Path to the kubeconfig file to use for CLI requests.\n  -n, --namespace string    The kubernetes namespace to use for CLI requests. (default \"flux-system\")\n      --terraform string    The location of the terraform binary. (default \"/usr/bin/terraform\")\n\nUse \"tfctl [command] --help\" for more information about a command.\n
"},{"location":"References/terraform/","title":"API References","text":"Terraform API reference

Packages:

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2","title":"infra.contrib.fluxcd.io/v1alpha2","text":"

Resource Types:

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.BackendConfigSpec","title":"BackendConfigSpec","text":"

(Appears on: TerraformSpec)

BackendConfigSpec is for specifying configuration for Terraform\u2019s Kubernetes backend

Field Description disable bool (Optional)

Disable is to completely disable the backend configuration.

secretSuffix string (Optional) inClusterConfig bool (Optional) customConfiguration string (Optional) configPath string (Optional) labels map[string]string (Optional)"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.BackendConfigsReference","title":"BackendConfigsReference","text":"

(Appears on: TerraformSpec)

Field Description kind string

Kind of the values referent, valid values are (\u2018Secret\u2019, \u2018ConfigMap\u2019).

name string

Name of the configs referent. Should reside in the same namespace as the referring resource.

keys []string (Optional)

Keys is the data key where a specific value can be found at. Defaults to all keys.

optional bool (Optional)

Optional marks this BackendConfigsReference as optional. When set, a not found error for the values reference is ignored, but any Key or transient error will still result in a reconciliation failure.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.CloudSpec","title":"CloudSpec","text":"

(Appears on: TerraformSpec)

Field Description organization string workspaces CloudWorkspacesSpec hostname string (Optional) token string (Optional)"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.CloudWorkspacesSpec","title":"CloudWorkspacesSpec","text":"

(Appears on: CloudSpec)

Field Description name string (Optional) tags []string (Optional)"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.CrossNamespaceSourceReference","title":"CrossNamespaceSourceReference","text":"

(Appears on: TerraformSpec)

CrossNamespaceSourceReference contains enough information to let you locate the typed Kubernetes resource object at cluster level.

Field Description apiVersion string (Optional)

API version of the referent.

kind string

Kind of the referent.

name string

Name of the referent.

namespace string (Optional)

Namespace of the referent, defaults to the namespace of the Kubernetes resource object that contains the reference.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.FileMapping","title":"FileMapping","text":"

(Appears on: TerraformSpec)

Field Description secretRef github.com/fluxcd/pkg/apis/meta.SecretKeyReference

Reference to a Secret that contains the file content

location string

Location can be either user\u2019s home directory or the Terraform workspace

path string

Path of the file - relative to the \u201clocation\u201d

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.ForceUnlockEnum","title":"ForceUnlockEnum (string alias)","text":"

(Appears on: TFStateSpec)

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.HealthCheck","title":"HealthCheck","text":"

(Appears on: TerraformSpec)

HealthCheck contains configuration needed to perform a health check after terraform is applied.

Field Description name string

Name of the health check.

type string

Type of the health check, valid values are (\u2018tcp\u2019, \u2018http\u2019). If tcp is specified, address is required. If http is specified, url is required.

url string (Optional)

URL to perform http health check on. Required when http type is specified. Go template can be used to reference values from the terraform output (e.g. https://example.org, {{.output_url}}).

address string (Optional)

Address to perform tcp health check on. Required when tcp type is specified. Go template can be used to reference values from the terraform output (e.g. 127.0.0.1:8080, {{.address}}:{{.port}}).

timeout Kubernetes meta/v1.Duration (Optional)

The timeout period at which the connection should timeout if unable to complete the request. When not specified, default 20s timeout is used.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.LockStatus","title":"LockStatus","text":"

(Appears on: TerraformStatus)

LockStatus defines the observed state of a Terraform State Lock

Field Description lastApplied string (Optional) pending string (Optional)

Pending holds the identifier of the Lock Holder to be used with Force Unlock

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.PlanStatus","title":"PlanStatus","text":"

(Appears on: TerraformStatus)

Field Description lastApplied string (Optional) pending string (Optional) isDestroyPlan bool (Optional) isDriftDetectionPlan bool (Optional)"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.ReadInputsFromSecretSpec","title":"ReadInputsFromSecretSpec","text":"

(Appears on: TerraformSpec)

Field Description name string as string"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.ResourceInventory","title":"ResourceInventory","text":"

(Appears on: TerraformStatus)

ResourceInventory contains a list of Kubernetes resource object references that have been applied by a Kustomization.

Field Description entries []ResourceRef

Entries of Kubernetes resource object references.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.ResourceRef","title":"ResourceRef","text":"

(Appears on: ResourceInventory)

ResourceRef contains the information necessary to locate a resource within a cluster.

Field Description n string

Terraform resource\u2019s name.

t string

Type is Terraform resource\u2019s type

id string

ID is the resource identifier. This is cloud-specific. For example, ARN is an ID on AWS.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.RunnerPodMetadata","title":"RunnerPodMetadata","text":"

(Appears on: RunnerPodTemplate)

Field Description labels map[string]string (Optional)

Labels to add to the runner pod

annotations map[string]string (Optional)

Annotations to add to the runner pod

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.RunnerPodSpec","title":"RunnerPodSpec","text":"

(Appears on: RunnerPodTemplate)

Field Description image string (Optional)

Runner pod image to use other than default

envFrom []Kubernetes core/v1.EnvFromSource (Optional)

List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.

env []Kubernetes core/v1.EnvVar (Optional)

List of environment variables to set in the container. Cannot be updated.

nodeSelector map[string]string (Optional)

Set the NodeSelector for the Runner Pod

affinity Kubernetes core/v1.Affinity (Optional)

Set the Affinity for the Runner Pod

tolerations []Kubernetes core/v1.Toleration (Optional)

Set the Tolerations for the Runner Pod

volumeMounts []Kubernetes core/v1.VolumeMount (Optional)

Set Volume Mounts for the Runner Pod

volumes []Kubernetes core/v1.Volume (Optional)

Set Volumes for the Runner Pod

initContainers []Kubernetes core/v1.Container (Optional)

Set up Init Containers for the Runner

hostAliases []Kubernetes core/v1.HostAlias (Optional)

Set host aliases for the Runner Pod

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.RunnerPodTemplate","title":"RunnerPodTemplate","text":"

(Appears on: TerraformSpec)

Field Description metadata RunnerPodMetadata (Optional) spec RunnerPodSpec (Optional) image string (Optional)

Runner pod image to use other than default

envFrom []Kubernetes core/v1.EnvFromSource (Optional)

List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.

env []Kubernetes core/v1.EnvVar (Optional)

List of environment variables to set in the container. Cannot be updated.

nodeSelector map[string]string (Optional)

Set the NodeSelector for the Runner Pod

affinity Kubernetes core/v1.Affinity (Optional)

Set the Affinity for the Runner Pod

tolerations []Kubernetes core/v1.Toleration (Optional)

Set the Tolerations for the Runner Pod

volumeMounts []Kubernetes core/v1.VolumeMount (Optional)

Set Volume Mounts for the Runner Pod

volumes []Kubernetes core/v1.Volume (Optional)

Set Volumes for the Runner Pod

initContainers []Kubernetes core/v1.Container (Optional)

Set up Init Containers for the Runner

hostAliases []Kubernetes core/v1.HostAlias (Optional)

Set host aliases for the Runner Pod

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.TFStateSpec","title":"TFStateSpec","text":"

(Appears on: TerraformSpec)

TFStateSpec allows the user to set ForceUnlock

Field Description forceUnlock ForceUnlockEnum (Optional)

ForceUnlock a Terraform state if it has become locked for any reason. Defaults to no.

This is an Enum and has the expected values of:

WARNING: Only use auto in the cases where you are absolutely certain that no other system is using this state, you could otherwise end up in a bad place See https://www.terraform.io/language/state/locking#force-unlock for more information on the terraform state lock and force unlock.

lockIdentifier string (Optional)

LockIdentifier holds the Identifier required by Terraform to unlock the state if it ever gets into a locked state.

You\u2019ll need to put the Lock Identifier in here while setting ForceUnlock to either yes or auto.

Leave this empty to do nothing, set this to the value of the Lock Info: ID: [value], e.g. f2ab685b-f84d-ac0b-a125-378a22877e8d, to force unlock the state.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.Terraform","title":"Terraform","text":"

Terraform is the Schema for the terraforms API

Field Description metadata Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata field. spec TerraformSpec approvePlan string (Optional)

ApprovePlan specifies name of a plan wanted to approve. If its value is \u201cauto\u201d, the controller will automatically approve every plan.

destroy bool (Optional)

Destroy produces a destroy plan. Applying the plan will destroy all resources.

backendConfig BackendConfigSpec (Optional) backendConfigsFrom []BackendConfigsReference (Optional) cloud CloudSpec (Optional) workspace string (Optional) vars []Variable (Optional)

List of input variables to set for the Terraform program.

varsFrom []VarsReference (Optional)

List of references to a Secret or a ConfigMap to generate variables for Terraform resources based on its data, selectively by varsKey. Values of the later Secret / ConfigMap with the same keys will override those of the former.

values Kubernetes pkg/apis/apiextensions/v1.JSON (Optional)

Values map to the Terraform variable \u201cvalues\u201d, which is an object of arbitrary values. It is a convenient way to pass values to Terraform resources without having to define a variable for each value. To use this feature, your Terraform file must define the variable \u201cvalues\u201d.

fileMappings []FileMapping (Optional)

List of all configuration files to be created in initialization.

interval Kubernetes meta/v1.Duration

The interval at which to reconcile the Terraform.

retryInterval Kubernetes meta/v1.Duration (Optional)

The interval at which to retry a previously failed reconciliation. The default value is 15 when not specified.

path string (Optional)

Path to the directory containing Terraform (.tf) files. Defaults to \u2018None\u2019, which translates to the root path of the SourceRef.

sourceRef CrossNamespaceSourceReference

SourceRef is the reference of the source where the Terraform files are stored.

suspend bool (Optional)

Suspend is to tell the controller to suspend subsequent TF executions, it does not apply to already started executions. Defaults to false.

force bool (Optional)

Force instructs the controller to unconditionally re-plan and re-apply TF resources. Defaults to false.

readInputsFromSecrets []ReadInputsFromSecretSpec (Optional) writeOutputsToSecret WriteOutputsToSecretSpec (Optional)

A list of target secrets for the outputs to be written as.

disableDriftDetection bool (Optional)

Disable automatic drift detection. Drift detection may be resource intensive in the context of a large cluster or complex Terraform statefile. Defaults to false.

cliConfigSecretRef Kubernetes core/v1.SecretReference (Optional) healthChecks []HealthCheck (Optional)

List of health checks to be performed.

destroyResourcesOnDeletion bool (Optional)

Create destroy plan and apply it to destroy terraform resources upon deletion of this object. Defaults to false.

serviceAccountName string (Optional)

Name of a ServiceAccount for the runner Pod to provision Terraform resources. Default to tf-runner.

alwaysCleanupRunnerPod bool (Optional)

Clean the runner pod up after each reconciliation cycle

runnerTerminationGracePeriodSeconds int64 (Optional)

Configure the termination grace period for the runner pod. Use this parameter to allow the Terraform process to gracefully shutdown. Consider increasing for large, complex or slow-moving Terraform managed resources.

refreshBeforeApply bool (Optional)

RefreshBeforeApply forces refreshing of the state before the apply step.

runnerPodTemplate RunnerPodTemplate (Optional) enableInventory bool (Optional)

EnableInventory enables the object to store resource entries as the inventory for external use.

tfstate TFStateSpec (Optional) targets []string (Optional)

Targets specify the resource, module or collection of resources to target.

parallelism int32 (Optional)

Parallelism limits the number of concurrent operations of Terraform apply step. Zero (0) means using the default value.

storeReadablePlan string (Optional)

StoreReadablePlan enables storing the plan in a readable format.

webhooks []Webhook (Optional) dependsOn []github.com/fluxcd/pkg/apis/meta.NamespacedObjectReference (Optional) enterprise Kubernetes pkg/apis/apiextensions/v1.JSON (Optional)

Enterprise is the enterprise configuration placeholder.

planOnly bool (Optional)

PlanOnly specifies if the reconciliation should or should not stop at plan phase.

breakTheGlass bool (Optional)

BreakTheGlass specifies if the reconciliation should stop and allow interactive shell in case of emergency.

status TerraformStatus"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.TerraformSpec","title":"TerraformSpec","text":"

(Appears on: Terraform)

TerraformSpec defines the desired state of Terraform

Field Description approvePlan string (Optional)

ApprovePlan specifies name of a plan wanted to approve. If its value is \u201cauto\u201d, the controller will automatically approve every plan.

destroy bool (Optional)

Destroy produces a destroy plan. Applying the plan will destroy all resources.

backendConfig BackendConfigSpec (Optional) backendConfigsFrom []BackendConfigsReference (Optional) cloud CloudSpec (Optional) workspace string (Optional) vars []Variable (Optional)

List of input variables to set for the Terraform program.

varsFrom []VarsReference (Optional)

List of references to a Secret or a ConfigMap to generate variables for Terraform resources based on its data, selectively by varsKey. Values of the later Secret / ConfigMap with the same keys will override those of the former.

values Kubernetes pkg/apis/apiextensions/v1.JSON (Optional)

Values map to the Terraform variable \u201cvalues\u201d, which is an object of arbitrary values. It is a convenient way to pass values to Terraform resources without having to define a variable for each value. To use this feature, your Terraform file must define the variable \u201cvalues\u201d.

fileMappings []FileMapping (Optional)

List of all configuration files to be created in initialization.

interval Kubernetes meta/v1.Duration

The interval at which to reconcile the Terraform.

retryInterval Kubernetes meta/v1.Duration (Optional)

The interval at which to retry a previously failed reconciliation. The default value is 15 when not specified.

path string (Optional)

Path to the directory containing Terraform (.tf) files. Defaults to \u2018None\u2019, which translates to the root path of the SourceRef.

sourceRef CrossNamespaceSourceReference

SourceRef is the reference of the source where the Terraform files are stored.

suspend bool (Optional)

Suspend is to tell the controller to suspend subsequent TF executions, it does not apply to already started executions. Defaults to false.

force bool (Optional)

Force instructs the controller to unconditionally re-plan and re-apply TF resources. Defaults to false.

readInputsFromSecrets []ReadInputsFromSecretSpec (Optional) writeOutputsToSecret WriteOutputsToSecretSpec (Optional)

A list of target secrets for the outputs to be written as.

disableDriftDetection bool (Optional)

Disable automatic drift detection. Drift detection may be resource intensive in the context of a large cluster or complex Terraform statefile. Defaults to false.

cliConfigSecretRef Kubernetes core/v1.SecretReference (Optional) healthChecks []HealthCheck (Optional)

List of health checks to be performed.

destroyResourcesOnDeletion bool (Optional)

Create destroy plan and apply it to destroy terraform resources upon deletion of this object. Defaults to false.

serviceAccountName string (Optional)

Name of a ServiceAccount for the runner Pod to provision Terraform resources. Default to tf-runner.

alwaysCleanupRunnerPod bool (Optional)

Clean the runner pod up after each reconciliation cycle

runnerTerminationGracePeriodSeconds int64 (Optional)

Configure the termination grace period for the runner pod. Use this parameter to allow the Terraform process to gracefully shutdown. Consider increasing for large, complex or slow-moving Terraform managed resources.

refreshBeforeApply bool (Optional)

RefreshBeforeApply forces refreshing of the state before the apply step.

runnerPodTemplate RunnerPodTemplate (Optional) enableInventory bool (Optional)

EnableInventory enables the object to store resource entries as the inventory for external use.

tfstate TFStateSpec (Optional) targets []string (Optional)

Targets specify the resource, module or collection of resources to target.

parallelism int32 (Optional)

Parallelism limits the number of concurrent operations of Terraform apply step. Zero (0) means using the default value.

storeReadablePlan string (Optional)

StoreReadablePlan enables storing the plan in a readable format.

webhooks []Webhook (Optional) dependsOn []github.com/fluxcd/pkg/apis/meta.NamespacedObjectReference (Optional) enterprise Kubernetes pkg/apis/apiextensions/v1.JSON (Optional)

Enterprise is the enterprise configuration placeholder.

planOnly bool (Optional)

PlanOnly specifies if the reconciliation should or should not stop at plan phase.

breakTheGlass bool (Optional)

BreakTheGlass specifies if the reconciliation should stop and allow interactive shell in case of emergency.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.TerraformStatus","title":"TerraformStatus","text":"

(Appears on: Terraform)

TerraformStatus defines the observed state of Terraform

Field Description ReconcileRequestStatus github.com/fluxcd/pkg/apis/meta.ReconcileRequestStatus

(Members of ReconcileRequestStatus are embedded into this type.)

observedGeneration int64 (Optional)

ObservedGeneration is the last reconciled generation.

conditions []Kubernetes meta/v1.Condition (Optional) lastAppliedRevision string (Optional)

The last successfully applied revision. The revision format for Git sources is /. lastAttemptedRevision string (Optional)

LastAttemptedRevision is the revision of the last reconciliation attempt.

lastPlannedRevision string (Optional)

LastPlannedRevision is the revision used by the last planning process. The result could be either no plan change or a new plan generated.

lastPlanAt Kubernetes meta/v1.Time (Optional)

LastPlanAt is the time when the last terraform plan was performed

lastDriftDetectedAt Kubernetes meta/v1.Time (Optional)

LastDriftDetectedAt is the time when the last drift was detected

lastAppliedByDriftDetectionAt Kubernetes meta/v1.Time (Optional)

LastAppliedByDriftDetectionAt is the time when the last drift was detected and terraform apply was performed as a result

availableOutputs []string (Optional) plan PlanStatus (Optional) inventory ResourceInventory (Optional)

Inventory contains the list of Terraform resource object references that have been successfully applied.

lock LockStatus (Optional)"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.Variable","title":"Variable","text":"

(Appears on: TerraformSpec)

Field Description name string

Name is the name of the variable

value Kubernetes pkg/apis/apiextensions/v1.JSON (Optional) valueFrom Kubernetes core/v1.EnvVarSource (Optional)"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.VarsReference","title":"VarsReference","text":"

(Appears on: TerraformSpec)

VarsReference contain a reference of a Secret or a ConfigMap to generate variables for Terraform resources based on its data, selectively by varsKey.

Field Description kind string

Kind of the values referent, valid values are (\u2018Secret\u2019, \u2018ConfigMap\u2019).

name string

Name of the values referent. Should reside in the same namespace as the referring resource.

varsKeys []string (Optional)

VarsKeys is the data key at which a specific value can be found. Defaults to all keys.

optional bool (Optional)

Optional marks this VarsReference as optional. When set, a not found error for the values reference is ignored, but any VarsKey or transient error will still result in a reconciliation failure.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.Webhook","title":"Webhook","text":"

(Appears on: TerraformSpec)

Field Description stage string enabled bool (Optional) url string payloadType string (Optional) errorMessageTemplate string (Optional) testExpression string"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.WriteOutputsToSecretSpec","title":"WriteOutputsToSecretSpec","text":"

(Appears on: TerraformSpec)

WriteOutputsToSecretSpec defines where to store outputs, and which outputs to be stored.

Field Description name string

Name is the name of the Secret to be written

labels map[string]string (Optional)

Labels to add to the outputted secret

annotations map[string]string (Optional)

Annotations to add to the outputted secret

outputs []string (Optional)

Outputs contain the selected names of outputs to be written to the secret. Empty array means writing all outputs, which is default.

This page was automatically generated with gen-crd-api-reference-docs

"},{"location":"adr/0000-template/","title":"0. Title","text":""},{"location":"adr/0000-template/#context","title":"Context","text":""},{"location":"adr/0000-template/#decision","title":"Decision","text":""},{"location":"adr/0000-template/#consequences","title":"Consequences","text":""},{"location":"adr/0000-use-adrs-for-decisions/","title":"1. Use ADRs to record decisions","text":""},{"location":"adr/0000-use-adrs-for-decisions/#context","title":"Context","text":"

Decisions that affect the development of Terraform Controller that are not captured via a proposal need to be captured in some way. We need a method that is lightweight and easy to discover the decision that have been made. The record of decisions will help future contributors to the project to understand why something has been implemented or is done a certain way.

"},{"location":"adr/0000-use-adrs-for-decisions/#decision","title":"Decision","text":"

The project will use Architectural Decision Records (ADR) to record decisions that are made outside of a proposal.

A template has been created based on prior work:

"},{"location":"adr/0000-use-adrs-for-decisions/#consequences","title":"Consequences","text":"

When decisions are made that affect the entire project then a new ADR needs to be created. Likewise, if a decision has been superseded then we need to capture this as a new ADR and mark the previous ADR as superseded. Maintainers and contributors will need to decide when an ADR is to be created.

"},{"location":"adr/0001-pr-polling-workflow/","title":"1. Pull Request Polling","text":""},{"location":"adr/0001-pr-polling-workflow/#context","title":"Context","text":"

To detect pull request changes, we can use webhooks or polling using GitHub's API.

"},{"location":"adr/0001-pr-polling-workflow/#decision","title":"Decision","text":"

We decided to start with polling for security reasons. Using webhooks would require users to open an ingress to the cluster. Because of this requirement, we think security conscious folks may refuse to roll this out on production clusters especially in an air-gapped environment. This does not mean that we will never consider using webhooks for this, but that initially, polling is what we have chosen to implement.

The Branch-Based Planner has two components:

  1. Polling Server: Detect Pull Request changes and manage Teraform resource state.
  2. Informer: Make a comment when new plan output is available.
"},{"location":"adr/0001-pr-polling-workflow/#consequences","title":"Consequences","text":"

The list Pull Requests endpoint returns all required fields to detect new and closed pull requests. It's one request per repository, but listing comments has to use an API request per pull request. So we have to add a mechanism to avoid hitting API rate limits.

"},{"location":"adr/0002-deny-cross-ns-by-default/","title":"2. Deny cross-namespace refs by default","text":""},{"location":"adr/0002-deny-cross-ns-by-default/#context","title":"Context","text":"

Like Flux, the tf-controller API has a handful of places where it accepts cross-namespace references.

In general in Kubernetes, references to objects in other namespaces are frowned upon, because

Both of these effects make a system less secure.

However: removing cross-namespace refs entirely would break some installations in a way that would be difficult to fix, because Flux deployments often rely on defining sources away from objects that use them.

"},{"location":"adr/0002-deny-cross-ns-by-default/#decision","title":"Decision","text":"

Deny cross-namespace references by default, but allow them to be enabled with a flag.

So that the default value means the right thing, the flag name must be enable-cross-namespace-refs, and the default false. To avoid confusion when people try to use the Flux version of this flag --disable-cross-namespace-refs, it should be supported too, but only respected if supplied.

"},{"location":"adr/0002-deny-cross-ns-by-default/#consequences","title":"Consequences","text":"

The changed default will break deployments that rely on cross-namespace refs, but they are easily fixed with the flag.

New deployments will be more secure, by default.

"},{"location":"branch_planner/","title":"Branch Planner User Guide","text":""},{"location":"branch_planner/#overview","title":"Overview","text":"

The Branch Planner, a new component of the Terraform Controller, is specifically designed to enhance the flexibility and robustness of Terraform Controller planning operations. This feature, currently in its technology preview phase, facilitates Terraform planning across branches, creating a streamlined and familiar PR-based workflow for users.

"},{"location":"branch_planner/#how-does-it-work","title":"How does it work?","text":"

When the Branch Planner starts, it polls repositories that contain Terraform resources at regular intervals, in order to detect Pull Requests (PR) that change those resources. Upon detecting that a PR exists, the Branch Planner initialises a Terraform object in Plan Only mode for the corresponding branch. In this mode, Terraform Controller generates Terraform plans but does not apply them. Once the plan is generated, Branch Planner posts the plan under the PR as a comment enabling users to review the plan. When the Terraform files of the corresponding branch get updated, Branch Planner posts the updated plan under the PR as new comment, keeping the PR up-to-date with the latest Terraform plan.

"},{"location":"branch_planner/#replan-commands","title":"Replan commands","text":"

The Branch Planner also allows users to manually trigger the replan process. By simply commenting !replan under the PR, the Branch Planner will be instructed to generate a new plan and post it under the PR as a new comment.

Now that you know what Branch Planner can do for you, follow the guide to get started.

"},{"location":"branch_planner/getting-started/","title":"Getting Started With Branch Planner","text":"

When the Branch Planner is enabled through Helm values, it will watch all configured Terraform resources, check their referenced Source, and poll for Pull Requests using GitHub's API plus the provided token.

When the Branch Planner detects an open Pull Request, it either creates a new Terraform object or updates an existing one, applying Plan Only mode based on the original Terraform object.

When a Plan Output becomes available, the Branch Planner creates a new comment under the Pull Request with the content of the Plan Output included.

"},{"location":"branch_planner/getting-started/#prerequisites","title":"Prerequisites","text":"
  1. Flux is installed on the cluster.
  2. A GitHub API token.
  3. Knowledge about GitOps Terraform Controller (see docs).
"},{"location":"branch_planner/getting-started/#quick-start-guide","title":"Quick Start Guide","text":"

This section describe how to install Branch Planner using HelmRelease object in the flux-system namespace with minimum configuration on a KinD cluster.

  1. Create a KinD cluster.

    kind create cluster\n

  2. Install Flux. Please make sure you have the latest version of Flux (v2 GA).

    flux install\n

  3. Create a Secret that contains GitHub API token. If you do not use gh cli, please feel free to copy and paste the token from GitHub's website.

    export GITHUB_TOKEN=$(gh auth token)\n\nkubectl create secret generic branch-planner-token \\\n    --namespace=flux-system \\\n    --from-literal=\"token=${GITHUB_TOKEN}\"\n

  4. Install Branch Planner from a HelmRelease provided by the TF-controller repository. Please make sure that you use TF Controller v0.16.0-rc.2 or later.

    kubectl apply -f https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/branch_planner/release.yaml\n

  5. Create a Terraform object with a Source pointing to a repository. You repository must contain a Terraform file, for example main.tf. Please take a look at https://github.com/tf-controller/branch-planner-demo for an example.

    export GITHUB_USER=<your user>\nexport GITHUB_REPO=<your repo>\n\ncat <<EOF | kubectl apply -f -\n---\napiVersion: source.toolkit.fluxcd.io/v1\nkind: GitRepository\nmetadata:\n  name: branch-planner-demo\n  namespace: flux-system\nspec:\n  interval: 30s\n  url: https://github.com/${GITHUB_USER}/${GITHUB_REPO}\n  ref:\n    branch: main\n---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\n  name: branch-planner-demo\n  namespace: flux-system\nspec:\n  approvePlan: auto\n  path: ./\n  interval: 1m\n  sourceRef:\n    kind: GitRepository\n    name: branch-planner-demo\n    namespace: flux-system\nEOF\n

  6. Now you can go to your GitHub repo and create a Pull Request. The Branch Planner will create a new Terraform object with Plan Only mode enabled, and generate a new plan for you.
"},{"location":"branch_planner/getting-started/#configure-branch-planner","title":"Configure Branch Planner","text":"

Branch Planner uses a ConfigMap as configuration. That ConfigMap is optional to use but useful for fine-tuning Branch Planner.

"},{"location":"branch_planner/getting-started/#custom-configuration","title":"Custom Configuration","text":"

By default Branch Planner will look for a branch-planner ConfigMap in the same namespace as where the tf-controller is installed. That ConfigMap allows users to precisely specify which Terraform resources in a cluster should be monitored by Branch Planner.

The ConfigMap has two fields:

  1. secretName, which contains the API token to access GitHub.
  2. resources, which defines a list of resources to watch.
---\napiVersion: v1\nkind: ConfigMap\nmetadata:\nnamespace: flux-system\nname: branch-planner\ndata:\nsecretName: branch-planner-token\nresources: |-\n- namespace: terraform\n
"},{"location":"branch_planner/getting-started/#secret","title":"Secret","text":"

Branch Planner uses the referenced Secret with a token field that acquires the API token to fetch Pull Request information.

kubectl create secret generic branch-planner-token \\\n--namespace=flux-system \\\n--from-literal=\"token=${GITHUB_TOKEN}\"\n
"},{"location":"branch_planner/getting-started/#resources","title":"Resources","text":"

If the resources list is empty, nothing will be watched. The resource definition can be exact or namespace-wide.

With the following configuration file, the Branch Planner will watch all Terraform objects in the terraform namespace, and the exact-terraform-object Terraform object in default namespace.

data:\nresources:\n- namespace: default\nname: exact-terraform-object\n- namespace: terraform\n
"},{"location":"branch_planner/getting-started/#default-configuration","title":"Default Configuration","text":"

If a ConfigMap is not found, it will watch the flux-system namespace for any Terraform resources and expect to find a GitHub token in a secret named branch-planner-token in the flux-system namespace. Note that supplying a secret with a token is a necessary task, otherwise Branch Planner will not be able to interact with the GitHub API.

"},{"location":"branch_planner/getting-started/#enable-branch-planner","title":"Enable Branch Planner","text":"

To enable branch planner, set the branchPlanner.enabled to true in the Helm values files.

---\nbranchPlanner:\n  enabled: true\n
"},{"location":"branch_planner/least-required-permissions/","title":"Least Required Permissions For Git Providers","text":""},{"location":"branch_planner/least-required-permissions/#github","title":"GitHub","text":""},{"location":"branch_planner/least-required-permissions/#fine-grained-personal-access-token","title":"Fine-Grained Personal Access Token","text":"

For public repositories, it's sufficient to enable Public Repositories, without any additional permissions.

For private repositories the following permissions are required:

"},{"location":"how_to/","title":"How to","text":""},{"location":"how_to/backup_and_restore_a_Terraform_state/","title":"Backup and restore a Terraform state","text":""},{"location":"how_to/backup_and_restore_a_Terraform_state/#backup-the-tfstate","title":"Backup the tfstate","text":"

Assume that we have the my-stack Terraform object with its .spec.workspace set to \"default\".

kubectl get terraform\n\nNAME       READY     STATUS         AGE\nmy-stack   Unknown   Initializing   28s\n

We can backup its tfstate out of the cluster, like this:

WORKSPACE=default\nNAME=my-stack\n\nkubectl get secret tfstate-${WORKSPACE}-${NAME} \\\n-ojsonpath='{.data.tfstate}' \\\n| base64 -d | gzip -d > terraform.tfstate\n
"},{"location":"how_to/backup_and_restore_a_Terraform_state/#restore-the-tfstate","title":"Restore the tfstate","text":"

To restore the tfstate file or import an existing tfstate file to the cluster, we can use the following operation:

gzip terraform.tfstate\n\nWORKSPACE=default\nNAME=my-stack\n\nkubectl create secret \\\ngeneric tfstate-${WORKSPACE}-${NAME} \\\n--from-file=tfstate=terraform.tfstate.gz \\\n--dry-run=client -o=yaml \\\n| yq e '.metadata.annotations[\"encoding\"]=\"gzip\"' - \\\n> tfstate-${WORKSPACE}-${NAME}.yaml\n\nkubectl apply -f tfstate-${WORKSPACE}-${NAME}.yaml\n
"},{"location":"how_to/interval_and_retryInterval/","title":"How does the interval and retryInterval work?","text":""},{"location":"how_to/interval_and_retryInterval/#overview","title":"Overview","text":"

This document describes the requeue behavior of the Reconcile method in the TerraformReconciler struct in the code base. Understanding these behaviors can be crucial for troubleshooting, as well as for future development and refinement of the system.

"},{"location":"how_to/interval_and_retryInterval/#requeue-behaviors","title":"Requeue Behaviors","text":"

The Reconcile method has several requeue behaviors based on different conditions and errors. We will group them into four categories based on their requeue behavior:

"},{"location":"how_to/interval_and_retryInterval/#1-immediate-requeue-not-using-specified-interval-retryinterval","title":"1. Immediate Requeue (Not using specified interval / retryInterval)","text":"

In these scenarios, the Reconcile method returns an error which leads to an immediate requeue orchestrated by the Controller Runtime. The interval is based on the controller's configuration and not specified in the method itself:

"},{"location":"how_to/interval_and_retryInterval/#2-requeue-after-a-specific-interval-specretryinterval","title":"2. Requeue After a Specific Interval (spec.retryInterval)","text":"

In these scenarios, the method specifically asks for a requeue after a certain interval specified by spec.retryInterval (default to 15s).

"},{"location":"how_to/interval_and_retryInterval/#3-requeue-after-a-specific-interval-specinterval","title":"3. Requeue After a Specific Interval (spec.interval)","text":"

In this scenario, the method specifically asks for a requeue after a successful reconciliation:

The interval for the requeue is spec.interval.

"},{"location":"how_to/interval_and_retryInterval/#4-no-requeue-wait-for-manual-intervention","title":"4. No Requeue, wait for manual intervention","text":"

In these scenarios, the method returns without asking for a requeue, and the Controller Runtime will stop the reconciliation process until there is a manual intervention:

"},{"location":"how_to/resource_deletion/","title":"Resource Deletion Dependencies in Terraform Controller","text":"

This document discusses potential difficulties you may encounter when deleting Terraform resources through the Terraform Controller and the necessary components to facilitate a smooth deletion process.

"},{"location":"how_to/resource_deletion/#source-object","title":"Source Object","text":"

The source object (e.g., GitRepository or OCIRepository) is a critical component of the Terraform resource deletion process. This object houses the Terraform source files (.tf files) that describe the configuration of the infrastructure resources.

During the deletion process, the Terraform Controller uses these source files to conduct a re-planning operation. This operation is instrumental to deleting the Terraform Custom Resource (CR).

However, if the source object is unavailable or has been deleted, the re-planning operation fails. As a result, the Terraform Controller cannot locate the resource state, leading to an infinite deletion attempt cycle, commonly known as a looping process.

"},{"location":"how_to/resource_deletion/#role-bindings","title":"Role Bindings","text":"

Role bindings assign permissions to Terraform runners, allowing them to execute operations within the Kubernetes cluster. These bindings define the actions that the Terraform runners are authorized to carry out.

If role bindings are missing or misconfigured, the Terraform runners may lack the necessary permissions to execute the deletion process, causing the process to fail.

"},{"location":"how_to/resource_deletion/#secrets-and-configmaps","title":"Secrets and ConfigMaps","text":"

Before initiating the resource deletion process, the Terraform Controller leverages Secrets and ConfigMaps to generate a complete source before planning. Secrets store confidential data like API keys or passwords, while ConfigMaps hold configuration data in a key-value format.

Should any of these components be missing or misconfigured, the Terraform Controller may fail to generate an accurate deletion plan, which could impede the resource deletion process.

"},{"location":"how_to/resource_deletion/#troubleshooting","title":"Troubleshooting","text":"

To prevent the aforementioned issues, ensure the availability and proper configuration of the source object, role bindings, and Secrets and ConfigMaps during the deletion process.

As of now, we are actively working to address these limitations in the Terraform Controller. We appreciate your patience and welcome any feedback to help enhance the Terraform Controller's performance.

"},{"location":"how_to/troubleshooting_with_break_the_glass_mode/","title":"Break the glass","text":""},{"location":"how_to/troubleshooting_with_break_the_glass_mode/#what-is-break-the-glass","title":"What is break the glass?","text":"

\"Break the glass\" refers to a troubleshooting mode specifically designed to provide a manual solution when the Terraform controller (TF-controller) is not performing as expected. This feature is available in the Terraform controller v0.15.0 and above.

~> WARNING: Please note that you cannot use this feature to fix the Terraform resources with v1alpha1 version of the Terraform CRD. It works only with v1alpha2 version of the Terraform CRD.

~> WARNING: Please also make sure that you have enough privileges to exec pods in your namespaces. Otherwise, you will not be able to use this feature.

There are two primary methods of initiating this mode:

  1. Using the tfctl command-line tool.
  2. Setting the spec.breakTheGlass field to true in the Terraform object.
"},{"location":"how_to/troubleshooting_with_break_the_glass_mode/#using-tfctl-to-break-the-glass","title":"Using tfctl to Break the Glass","text":"

To start a one-time troubleshooting session, you can use the tfctl break-glass command. For instance:

tfctl break-glass hello-world\n

This command initiates a session that allows you to execute any Terraform command to rectify the issues with your Terraform resources. It is noteworthy that this command does not require setting the spec.breakTheGlass field to true in the Terraform object.

After resolving the issues, you can simply exit the shell. GitOps will then continue to reconcile the Terraform object.

"},{"location":"how_to/troubleshooting_with_break_the_glass_mode/#break-the-glass-with-specbreaktheglass-field","title":"Break the glass with spec.breakTheGlass field","text":"

This feature is particularly useful for troubleshooting Terraform objects at their initialization stage or in situations with unexpected errors. It is generally not recommended to use this mode routinely for fixing Terraform resources.

You can enable the 'Break the Glass' feature for every reconciliation by setting the breakTheGlass field to true in the spec of the Terraform object.

Here is a sample example:

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: hello-world\nnamespace: flux-system\nspec:\nbreakTheGlass: true\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n
"},{"location":"use_tf_controller/","title":"Use TF-controller","text":""},{"location":"use_tf_controller/to_detect_drifts_only_without_plan_or_apply/","title":"To detect drifts only without plan or apply","text":""},{"location":"use_tf_controller/to_detect_drifts_only_without_plan_or_apply/#use-tf-controller-to-detect-drifts-only-without-plan-or-apply","title":"Use TF-controller to detect drifts only without plan or apply","text":"

We can set .spec.approvePlan to disable to tell the controller to detect drifts of your Terraform resources only. Doing so will skip the plan and apply stages.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: hello-world\nnamespace: flux-system\nspec:\napprovePlan: disable\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n
"},{"location":"use_tf_controller/to_force_unlock_Terraform_states/","title":"Use TF-controller to force unlock Terraform states","text":"

In some situations, you may need to perform the Terraform force-unlock operation on the tfstate inside the cluster.

There are three possible values of .spec.tfstate.forceUnlock, which are yes, no, and auto. The default value is no, which means that you disable this behaviour.

The auto force-unlock mode will automatically use the lock identifier produced by the associated state file instead of specified lock identifier.

The recommended way is to do manual force unlock. To manually force-unlock, you need to:

  1. set forceUnlock to yes, and
  2. specify a lock identifier to unlock a specific locked state,

as the following example:

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\ntfstate:\nforceUnlock: \"yes\"\nlockIdentifier: f2ab685b-f84d-ac0b-a125-378a22877e8d\n
"},{"location":"use_tf_controller/to_plan_and_manually_apply_Terraform_resources/","title":"Use TF-controller to plan and manually apply Terraform resources","text":"

In this guide, we will walk through the steps of using TF-controller to plan and manually apply Terraform resources.

We will start by creating the Terraform object and specifying the necessary fields, including the approvePlan field.

We will then create the GitRepository object, which points to the Git repository containing the Terraform configuration.

Once these objects are created, we will use kubectl to obtain the approvePlan value and set it in the Terraform object. After making our changes and pushing them to the Git repository, TF-controller will apply the plan and create the real resources.

"},{"location":"use_tf_controller/to_plan_and_manually_apply_Terraform_resources/#define-the-terraform-object","title":"Define the Terraform object","text":"

Assume that you have a GitRepository object named helloworld pointing to a Git repository, and you want to plan and apply the Terraform resources under ./ of that Git repo.

For the plan & manual approval workflow, please start by either setting .spec.approvePlan to be the blank value, or omitting the field. This will tell TF-controller to use the plan & manual approval workflow, rather than the auto-apply workflow. If you want to use the auto-apply workflow, you will need to set the spec.approvePlan field to \"auto\".

In addition to setting the spec.approvePlan field, you will also need to specify the interval, path, and sourceRef fields in the spec field. The interval field determines how often TF-controller will run the Terraform configuration, the path field specifies the location of the configuration files, and the sourceRef field points to the GitRepository object.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: \"\" # or you can omit this field\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n
"},{"location":"use_tf_controller/to_plan_and_manually_apply_Terraform_resources/#view-the-approval-message","title":"View the approval message","text":"

Then after a reconciliation loop, the controller will generate a plan, and tell you how to use field .spec.approvePlan to approve the plan. You can run the following command to obtain that message.

kubectl -n flux-system get tf/helloworld\n

This command will output the message containing the approvePlan value that you will need to use to approve the plan. Once you have this value, you can edit the Terraform object file, and set the spec.approvePlan field to the value obtained from the message.

After making your changes and pushing them to the Git repository, TF-controller will apply the plan and create the real resources. This process is known as the plan & manual approval workflow, as it involves generating a plan and requiring manual approval before the changes are applied.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: hello-world\nnamespace: flux-system\nspec:\napprovePlan: plan-main-b8e362c206 # first 8 digits of a commit hash is enough\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n
"},{"location":"use_tf_controller/to_provision_Terraform_resources_that_are_required_health_checks/","title":"Use TF-controller to provision Terraform resources that are required health checks","text":"

For some Terraform resources, it may be useful to perform health checks on them to verify that they are ready to accept connection before the terraform goes into Ready state:

For example, our Terraform file is provisioned and contains the following outputs.

# main.tf\noutput \"rdsAddress\" {\nvalue = \"mydb.xyz.us-east-1.rds.amazonaws.com\"\n}\noutput \"rdsPort\" {\nvalue = \"3306\"\n}\noutput \"myappURL\" {\nvalue = \"https://example.com/\"\n}\n

We can use standard Go template expressions, like ${{ .rdsAddress }}, to refer to those output values and use them to verify that the resources are up and running.

We support two types of health checks, tcp amd http. The tcp type allows us to verify a TCP connection, while the http type is for verify an HTTP URL. The default timeout of each health check is 20 seconds.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nhealthChecks:\n- name: rds\ntype: tcp\naddress: ${{ .rdsAddress }}:${{ .rdsPort }} timeout: 10s # optional, defaults to 20s\n- name: myapp\ntype: http\nurl: ${{ .myappURL }}\ntimeout: 5s\n- name: url_not_from_output\ntype: http\nurl: \"https://example.org\"\n
"},{"location":"use_tf_controller/to_provision_resources_and_auto_approve/","title":"Use TF-controller to provision resources and auto approve","text":"

To provision resources with TF-controller, you need to create a Terraform object and a Flux source object, such as a GitRepository or OCIRepository object.

"},{"location":"use_tf_controller/to_provision_resources_and_auto_approve/#create-a-terraform-object","title":"Create a Terraform object","text":"

The Terraform object is a Kubernetes custom resource definition (CRD) object. It is the core object of TF-controller and defines the Terraform module, backend configuration, and GitOps automation mode..

It defines the Terraform module, the backend configuration, and the GitOps automation mode.

The Terraform module is a Terraform configuration that can be used to provision resources. It can be placed inside a Git repository, or packaged as an OCI image in an OCI registry.

The backend configuration is the configuration for the Terraform backend to be used to store the Terraform state. It is optional. If not specified, the Kubernetes backend will be used by default.

"},{"location":"use_tf_controller/to_provision_resources_and_auto_approve/#gitops-automation-mode","title":"GitOps automation mode","text":"

The GitOps automation mode is the GitOps automation mode to be used to run the Terraform module. It determines how Terraform runs and manages your infrastructure. It is optional. If not specified, the \"plan-and-manually-apply\" mode will be used by default. In the \"plan-and-manually-apply\" mode, TF-controller will run a Terraform plan and output the proposed changes to a Git repository. A human must then review and manually apply the changes. This is the default GitOps automation mode if none is specified.

In the \"auto-apply\" mode, TF-controller will automatically apply the changes after a Terraform plan is run. This can be useful for environments where changes can be made automatically, but it is important to ensure that the proper controls, like policies, are in place to prevent unintended changes from being applied.

To specify the GitOps automation mode in a Terraform object, you can set the spec.approvePlan field to the desired value. For example, to use the \"auto-apply\" mode, y ou would set it to spec.approvePlan: auto.

It is important to carefully consider which GitOps automation mode is appropriate for your use case to ensure that your infrastructure is properly managed and controlled.

The following is an example of a Terraform object; we use the \"auto-apply\" mode:

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nspec:\npath: ./helloworld\ninterval: 10m\napprovePlan: auto\nsourceRef:\nkind: GitRepository\nname: helloworld\n

This code is defining a Terraform object in Kubernetes. The apiVersion field specifies the version of the Kubernetes API being used, and the kind field specifies that it is a Terraform object. The metadata block contains information about the object, including its name.

The spec field contains the specification for the Terraform object. The path field specifies the path to the Terraform configuration files, in this case a directory named \"helloworld\". The interval field specifies the frequency at which TF-controller should run the Terraform configuration, in this case every 10 minutes. The approvePlan field specifies whether or not to automatically approve the changes proposed by a Terraform plan. In this case, it is set to auto, meaning that changes will be automatically approved.

The sourceRef field specifies the Flux source object to be used. In this case, it is a GitRepository object with the name \"helloworld\". This indicates that the Terraform configuration is stored in a Git repository object with the name helloworld.

"},{"location":"use_tf_controller/to_provision_resources_and_destroy_them_when_the_Terraform_object_gets_deleted/","title":"Use TF-controller to provision resources and destroy them when the Terraform object gets deleted","text":"

The resources provisioned by a Terraform object are not destroyed by default, and the tfstate of that Terraform object still remains in the cluster.

It means that you are safe to delete the Terraform object in the cluster and re-create it. If you re-create a new Terraform object with the same name, namespace and workspace, it will continue to use the tfstate inside the cluster as the starting point to reconcile.

However, you may want to destroy provisioned resources when delete the Terraform object in many scenarios. To enable destroy resources on object deletion, set .spec.destroyResourcesOnDeletion to true.

~> WARNING: This feature will destroy your resources on the cloud if the Terraform object gets deleted. Please use it with cautions.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ndestroyResourcesOnDeletion: true\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n
"},{"location":"use_tf_controller/to_provision_resources_and_obtain_outputs/","title":"Use TF-controller to provision resources and obtain outputs","text":"

Outputs created by Terraform can be written to a secret using .spec.writeOutputsToSecret.

"},{"location":"use_tf_controller/to_provision_resources_and_obtain_outputs/#write-all-outputs","title":"Write all outputs","text":"

We can specify a target secret in .spec.writeOutputsToSecret.name, and the controller will write all outputs to the secret by default.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nwriteOutputsToSecret:\nname: helloworld-output\n
"},{"location":"use_tf_controller/to_provision_resources_and_obtain_outputs/#write-outputs-selectively","title":"Write outputs selectively","text":"

We can choose only a subset of outputs by specify output names we'd like to write in the .spec.writeOutputsToSecret.outputs array.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nwriteOutputsToSecret:\nname: helloworld-output\noutputs:\n- hello_world\n- my_sensitive_data\n
"},{"location":"use_tf_controller/to_provision_resources_and_obtain_outputs/#rename-outputs","title":"Rename outputs","text":"

Some time we'd like to use rename an output, so that it can be consumed by other Kubernetes controllers. For example, we might retrieve a key from a Secret manager, and it's an AGE key, which must be ending with \".agekey\" in the secret. In this case, we need to rename the output.

TF-controller supports mapping output name using the old_name:new_name format.

In the following example, we renamed age_key output as age.agekey entry for the helloworld-output Secret's data, so that other components in the GitOps pipeline could consume it.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nwriteOutputsToSecret:\nname: helloworld-output\noutputs:\n- age_key:age.agekey\n
"},{"location":"use_tf_controller/to_provision_resources_and_obtain_outputs/#customize-metadata-of-the-outputted-secret","title":"Customize metadata of the outputted secret","text":"

In some situations, it is needed to add custom labels and annotations to the outputted secret. As an example, operators such as kubernetes-replicator allow replicating secrets from one namespace to another but use annotations to do so.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nwriteOutputsToSecret:\nname: helloworld-output\nlabels:\nmy-label: true\nannotations:\nmy-annotation: \"very long string\"\n
"},{"location":"use_tf_controller/to_provision_resources_with_customized_Runner_Pods/","title":"Use TF-controller to provision resources with customized Runner Pods","text":""},{"location":"use_tf_controller/to_provision_resources_with_customized_Runner_Pods/#customize-runner-pods-metadata","title":"Customize Runner Pod's metadata","text":"

In some situations, it is needed to add custom labels and annotations to the runner pod used to reconcile Terraform. For example, for Azure AKS to grant pod active directory permissions using Azure Active Directory (AAD) Pod Identity, a label like aadpodidbinding: myIdentity on the pod is required.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nrunnerPodTemplate:\nmetadata:\nlabels:\naadpodidbinding: myIdentity\nannotations:\ncompany.com/abc: xyz\n
"},{"location":"use_tf_controller/to_provision_resources_with_customized_Runner_Pods/#customize-runner-pod-image","title":"Customize Runner Pod Image","text":"

By default, the Terraform controller uses RUNNER_POD_IMAGE environment variable to identify the Runner Pod's image to use. You can customize the image on the global level by updating the value of the environment variable or, you can specify an image to use per Terraform object for its reconciliation.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nrunnerPodTemplate:\nspec:\nimage: registry.io/tf-runner:xyz\n

You can use runner.Dockerfile as a basis of customizing runner pod image.

"},{"location":"use_tf_controller/to_provision_resources_with_customized_Runner_Pods/#customize-runner-pod-specifications","title":"Customize Runner Pod Specifications","text":"

You can also customize various Runner Pod spec fields to control and configure how the Runner Pod runs. For example, you can configure Runner Pod spec affinity and tolerations if you need to run in on a specific set of nodes. Please see RunnerPodSpec for a list of the configurable Runner Pod spec fields.

"},{"location":"use_tf_controller/to_set_variables_for_Terraform_resources/","title":"Use TF-controller to set variables for Terraform resources","text":"

~> BREAKING CHANGE: This is a breaking change of the v1alpha1 API.

Users who are upgrading from TF-controller <= 0.7.0 require updating varsFrom, from a single object:

  varsFrom:\nkind: ConfigMap\nname: cluster-config\n

to be an array of object, like this:

  varsFrom:\n- kind: ConfigMap\nname: cluster-config\n
"},{"location":"use_tf_controller/to_set_variables_for_Terraform_resources/#vars-and-varsfrom","title":"vars and varsFrom","text":"

You can pass variables to Terraform using the vars and varsFrom fields.

Inline variables can be set using vars. The varsFrom field accepts a list of ConfigMaps / Secrets. You may use the varsKeys property of varsFrom to select specific keys from the input or omit this field to select all keys from the input source.

Note that in the case of the same variable key being passed multiple times, the controller will use the lattermost instance of the key passed to varsFrom.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nvars:\n- name: region\nvalue: us-east-1\n- name: env\nvalue: dev\n- name: instanceType\nvalue: t3-small\nvarsFrom:\n- kind: ConfigMap\nname: cluster-config\nvarsKeys:\n- nodeCount\n- instanceType\n- kind: Secret\nname: cluster-creds\n
"},{"location":"use_tf_controller/to_set_variables_for_Terraform_resources/#variable-value-as-hcl","title":"Variable value as HCL","text":"

The vars field supports HCL string, number, bool, object and list types. For example, the following variable can be populated using the accompanying Terraform spec:

variable \"cluster_spec\" {\ntype = object({\nregion     = string\nenv        = string\nnode_count = number\npublic     = bool\n})\n}\n
apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nvars:\n- name: cluster_spec\nvalue:\nregion: us-east-1\nenv: dev\nnode_count: 10\npublic: false\n
"},{"location":"use_tf_controller/to_set_variables_for_Terraform_resources/#rename-variables-in-varsfrom","title":"Rename variables in varsFrom","text":"

To rename a variable, you can use the varsKeys key within the varsFrom field. Here's the basic structure:

spec:\nvarsFrom:\n- kind: Secret\nname: <secret_name>\nvarsKeys:\n- <original_variable_name>:<new_variable_name>\n
original_variable_name corresponds to the initial name of the variable in the referenced secret, while new_variable_name represents the alias you want to use within the Terraform code.

Consider this example below, where we rename nodeCount to node_count and instanceType to instance_type:

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nvarsFrom:\n- kind: Secret\nname: cluster-config\nvarsKeys:\n- nodeCount:node_count\n- instanceType:instance_type\n
"},{"location":"use_tf_controller/to_set_variables_for_Terraform_resources/#rename-output-variables","title":"Rename output variables","text":"

See Rename outputs for more details.

"},{"location":"use_tf_controller/to_set_variables_for_Terraform_resources/#rename-input-secrets","title":"Rename input secrets","text":"

See Rename input secrets for more details.

"},{"location":"use_tf_controller/with_AWS_EKS_IRSA/","title":"Use TF-controller with AWS EKS IRSA","text":"

AWS Elastic Kubernetes Service (EKS) offers IAM Roles for Service Accounts (IRSA) as a mechanism by which to provide credentials to Kubernetes pods. This can be used to provide the required AWS credentials to Terraform runners for performing plans and applies.

You can use eksctl to associate an OIDC provider with your EKS cluster, for example:

eksctl utils associate-iam-oidc-provider --cluster CLUSTER_NAME --approve\n

Then follow the instructions here to add a trust policy to the IAM role which grants the necessary permissions for Terraform. Please note that if you have installed the controller following the README, then the namespace:serviceaccountname will be flux-system:tf-runner. You'll obtain a Role ARN to use in the next step.

Finally, annotate the ServiceAccount for the tf-runner with the obtained Role ARN in your cluster:

kubectl annotate -n flux-system serviceaccount tf-runner eks.amazonaws.com/role-arn=ROLE_ARN\n

If deploying the tf-controller via Helm, this can be accomplished as follows:

values:\nrunner:\nserviceAccount:\nannotations:\neks.amazonaws.com/role-arn: ROLE_ARN\n
"},{"location":"use_tf_controller/with_GitOps_dependency_management/","title":"Use TF-controller with GitOps dependency management","text":"

TF-controller supports GitOps dependency management. The GitOps dependency management feature is based on the similar technique implemented in the Kustomization controller of Flux.

This means that you can use TF-controller to provision resources that depend on other resources at the GitOps level. For example, you can use TF-controller to provision an S3 bucket, and then use TF-controller to provision another resource to configure ACL for that bucket.

GitOps dependency management is different from Terraform's HCL dependency management in the way that it is not based on Terraform's mechanism, which is controlled by the Terraform binary. Instead, it is implemented at the controller level, which means that each Terraform module is reconciled and can be managed independently, while still being able to depend on other modules.

"},{"location":"use_tf_controller/with_GitOps_dependency_management/#create-a-terraform-object","title":"Create a Terraform object","text":"

Similar to the same feature in the Kustomization controller, the dependency management feature is enabled by setting the dependsOn field in the Terraform object. The dependsOn field is a list of Terraform objects.

When the dependency is not satisfied, the Terraform object will be in the Unknown state, and it will be retry again every spec.retryInterval. The retry interval is same as the spec.interval by default, and it can be configured separately by setting the spec.retryInterval field.

First, create a Terraform object to provision the S3 bucket, name it aws-s3-bucket. The S3 bucket is provisioned by the Terraform module aws_s3_bucket in the OCI image aws-package. It is configured to use the auto-apply mode, and write outputs to the secret aws-s3-bucket-outputs.

---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: aws-s3-bucket\nnamespace: flux-system\nspec:\npath: aws_s3_bucket\nvalues:\nbucket: my-tf-controller-test-bucket\ntags:\nEnvironment: Dev\nName: My bucket\nsourceRef:\nkind: OCIRepository\nname: aws-package\napprovePlan: auto\ninterval: 2m\ndestroyResourcesOnDeletion: true\nwriteOutputsToSecret:\nname: aws-s3-bucket-outputs\noutputs:\n- arn\n- bucket\nrunnerPodTemplate:\nspec:\nenvFrom:\n- secretRef:\nname: aws-credentials\n

Second, create a Terraform object to configure ACL for the S3 bucket, name it aws-s3-bucket-acl. The ACL is provisioned by the Terraform module aws_s3_bucket_acl, also from the OCI image aws-package-v4.33.0.

In the dependsOn field, specify the Terraform object that provisions the S3 bucket. This means that the ACL will be configured only after the S3 bucket is provisioned, and has its outputs Secret written. We can read the outputs of the S3 bucket from the Secret aws-s3-bucket-outputs, by specifying the spec.readInputsFromSecrets field. The spec.readInputsFromSecrets field is a list of Secret objects. Its name field is the name of the Secret, and its as field is the name of variable that can be used in the spec.values block.

For example, the spec.values.bucket field in the aws-s3-bucket-acl Terraform object is set to ${{ .aws_s3_bucket.bucket }}.

Please note that we use ${{ and }} as the delimiters for the variable name, instead of the Helm default ones, {{ and }}.

---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: aws-s3-bucket-acl\nnamespace: flux-system\nspec:\npath: aws_s3_bucket_acl\nvalues:\nacl: private\nbucket: ${{ .aws_s3_bucket.bucket }}\nsourceRef:\nkind: OCIRepository\nname: aws-package\napprovePlan: auto\ninterval: 3m\ndependsOn:\n- name: aws-s3-bucket\nreadInputsFromSecrets:\n- name: aws-s3-bucket-outputs\nas: aws_s3_bucket\nrunnerPodTemplate:\nspec:\nenvFrom:\n- secretRef:\nname: aws-credentials\n
"},{"location":"use_tf_controller/with_GitOps_dependency_management/#avoid-kustomization-controllers-variable-substitution","title":"Avoid Kustomization controller's variable substitution","text":"

The Kustomization controller will substitute variables in the Terraform object, which will cause conflicts with the variable substitution in the GitOps dependency management feature. To avoid this, we need to add the kustomize.toolkit.fluxcd.io/substitute: disabled annotation to the Terraform object.

---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: aws-s3-bucket-acl\nnamespace: flux-system\nannotations:\nkustomize.toolkit.fluxcd.io/substitute: disabled\nspec:\npath: aws_s3_bucket_acl\nvalues:\nacl: private\nbucket: ${{ .aws_s3_bucket.bucket }}\nsourceRef:\nkind: OCIRepository\nname: aws-package\napprovePlan: auto\ninterval: 3m\ndependsOn:\n- name: aws-s3-bucket\nreadInputsFromSecrets:\n- name: aws-s3-bucket-outputs\nas: aws_s3_bucket\nrunnerPodTemplate:\nspec:\nenvFrom:\n- secretRef:\nname: aws-credentials\n
"},{"location":"use_tf_controller/with_Terraform_Enterprise/","title":"Use TF-controller with Terraform Enterprise","text":""},{"location":"use_tf_controller/with_Terraform_Enterprise/#terraform-enterprise-integration","title":"Terraform Enterprise Integration","text":"

Starting from v0.9.5, Weave TF-controller officially supports integration to Terraform Cloud (TFC) and Terraform Enterprise (TFE). Here are the steps to set up TF-controller for your TFE instance.

"},{"location":"use_tf_controller/with_Terraform_Enterprise/#terraform-login","title":"Terraform Login","text":"

First, you need to obtain an API token from your TFE. You can use terraform login command to do so.

terraform login tfe.dev.example.com\n

Then you can find your API token inside $HOME/.terraform.d/credentials.tfrc.json. Content of the file will look like this:

{\n\"credentials\": {\n\"tfe.dev.example.com\": {\n\"token\": \"mXXXXXXXXX.atlasv1.ixXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"\n}\n}\n}\n
"},{"location":"use_tf_controller/with_Terraform_Enterprise/#prepare-an-tfrc-file","title":"Prepare an TFRC file","text":"

TF-controller accepts an TFRC file in the HCL format. So you have to prepare terraform.tfrc file using contents from above.

credentials \"tfe.dev.example.com\" {\ntoken = \"mXXXXXXXXX.atlasv1.ixXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"\n}\n

"},{"location":"use_tf_controller/with_Terraform_Enterprise/#create-a-secret","title":"Create a Secret","text":"

We will now create a Kubernetes Secret from yourterraform.tfrc file, name it tfe-cli-config and put it inside the flux-system namespace.

kubectl create secret generic \\\ntfe-cli-config \\\n--namespace=flux-system \\\n--from-file=terraform.tfrc=./terraform.tfrc\n
"},{"location":"use_tf_controller/with_Terraform_Enterprise/#terraform-object","title":"Terraform Object","text":"

In your Terraform object, you'll have to 1. disable the backend by setting spec.backendConfig.disable: true, and 2. point spec.cliConfigSecretRef: to the Secret created in the previous step, like this:

---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: tfe-demo\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 2m\npath: ./terraform/tfe-demo\nbackendConfig:\ndisable: true\ncliConfigSecretRef:\nname: tfe-cli-config\nnamespace: flux-system\nvars:\n- name: subject\nvalue: World\nsourceRef:\nkind: GitRepository\nname: flux-system\nnamespace: flux-system\nwriteOutputsToSecret:\nname: tfe-helloworld-output\noutputs:\n- greeting\n
"},{"location":"use_tf_controller/with_Terraform_Enterprise/#terraform-module","title":"Terraform Module","text":"

Don't forget that you need to tell your Terraform model to use your enterprise instance as well. Here's an example,

terraform {\nrequired_version = \">= 1.1.0\"\ncloud {\nhostname = \"tfe.dev.example.com\"\norganization = \"weaveworks\"\nworkspaces {\nname = \"dev\"\n}\n}\n}\nvariable \"subject\" {\ntype = string\ndefault = \"World\"\ndescription = \"Subject to hello\"\n}\noutput \"greeting\" {\nvalue = \"Hello ${var.subject} from Terraform Enterprise\"\n}\n

"},{"location":"use_tf_controller/with_Terraform_Enterprise/#terraform-cloud","title":"Terraform Cloud","text":"

For connecting to Terraform Cloud, please replace your hostname to app.terraform.io.

"},{"location":"use_tf_controller/with_a_custom_backend/","title":"Use TF-controller with a custom backend","text":"

By default, tf-controller will use the Kubernetes backend to store the Terraform state file (tfstate) in cluster.

The tfstate is stored in a secret named: tfstate-${workspace}-${secretSuffix}. The default suffix will be the name of the Terraform resource, however you may override this setting using .spec.backendConfig.secretSuffix. The default workspace name is \"default\", you can also override the workspace by setting .spec.workspace to another value.

If you wish to use a custom backend, you can configure it by defining the .spec.backendConfig.customConfiguration with one of the backends such as GCS or S3, for example:

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\nbackendConfig:\ncustomConfiguration: |\nbackend \"s3\" {\nbucket                      = \"s3-terraform-state1\"\nkey                         = \"dev/terraform.tfstate\"\nregion                      = \"us-east-1\"\nendpoint                    = \"http://localhost:4566\"\nskip_credentials_validation = true\nskip_metadata_api_check     = true\nforce_path_style            = true\ndynamodb_table              = \"terraformlock\"\ndynamodb_endpoint           = \"http://localhost:4566\"\nencrypt                     = true\n}\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nrunnerPodTemplate:\nspec:\nimage: registry.io/tf-runner:xyz\n
"},{"location":"use_tf_controller/with_an_OCI_Artifact_as_Source/","title":"Use TF-controller with an OCI Artifact as Source","text":"

To use OCI artifacts as the source of Terraform objects, you need Flux 2 version v0.32.0 or higher.

Assuming that you have Terraform files (your root module may contain sub-modules) under ./modules, you can use Flux CLI to create an OCI artifact for your Terraform modules by running the following commands:

flux push artifact oci://ghcr.io/tf-controller/helloworld:$(git rev-parse --short HEAD) \\\n--path=\"./modules\" \\\n--source=\"$(git config --get remote.origin.url)\" \\\n--revision=\"$(git branch --show-current)/$(git rev-parse HEAD)\"\nflux tag artifact oci://ghcr.io/tf-controller/helloworld:$(git rev-parse --short HEAD) \\\n--tag main\n

Then you define a source (OCIRepository), and use it as the sourceRef of your Terraform object.

---\napiVersion: source.toolkit.fluxcd.io/v1beta2\nkind: OCIRepository\nmetadata:\nname: helloworld-oci\nspec:\ninterval: 1m\nurl: oci://ghcr.io/tf-controller/helloworld\nref:\ntag: main\n---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld-tf-oci\nspec:\npath: ./\napprovePlan: auto\ninterval: 1m\nsourceRef:\nkind: OCIRepository\nname: helloworld-oci\nwriteOutputsToSecret:\nname: helloworld-outputs\n
"},{"location":"use_tf_controller/with_drift_detection_disabled/","title":"Use TF-controller with drift detection disabled","text":"

Drift detection is enabled by default. You can set .spec.disableDriftDetection: true to disable it.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ndisableDriftDetection: true\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n
"},{"location":"use_tf_controller/with_plan_only_mode/","title":"Use TF-controller with a plan-only mode","text":"

This plan-only mode is designed to be used in conjunction with the Branch Planner. But you can also use it in a circumstance where you want to run terraform plan only.

If planOnly is set to true, the controller will skip the apply part and runs only terraform plan and saves the output.

apiVersion: infra.contrib.fluxcd.io/v1\nkind: Terraform\nmetadata:\n  name: helloworld\n  namespace: flux-system\nspec:\n  interval: 1m\n  planOnly: true\n  path: ./\n  sourceRef:\n    kind: GitRepository\n    name: helloworld\n    namespace: flux-system\n
"},{"location":"use_tf_controller/with_primitive_modules/","title":"Use TF-controller with primitive modules","text":"

This document describes how to use the Weave TF-controller with a primitive module. It requires TF-controller v0.13+ to run the example.

"},{"location":"use_tf_controller/with_primitive_modules/#what-is-a-primitive-module","title":"What is a primitive module?","text":"

It's a Terraform module that contains only a single resource.

"},{"location":"use_tf_controller/with_primitive_modules/#hello-world-primitive-module","title":"Hello World Primitive Module","text":"

Here is an example of how a primitive module can be defined in YAML. Assume that we have a ready-to-use OCI image with a primitive module for the imaginary resource aws_hello_world, and the image is tagged as ghcr.io/tf-controller/hello-primitive-modules/v4.32.0:v1.

We'll use the following Terraform object definition to provision the resource.

First, we need to create a Terraform object with the spec.sourceRef.kind field set to OCIRepository and the spec.sourceRef.name field set to the name of the OCIRepository object.

Second, we need to set the spec.path field to the name of the resource, in this case aws_hello_world.

Third, we need to set the spec.values field to the values of the resource. This is a YAML object that will be converted to an HCL variable, and passed to the Terraform module.

Finally, we need to set the spec.approvePlan field to auto to automatically approve the plan.

---\napiVersion: source.toolkit.fluxcd.io/v1beta2\nkind: OCIRepository\nmetadata:\nname: hello-package-v4.32.0\nnamespace: flux-system\nspec:\ninterval: 30s\nurl: oci://ghcr.io/tf-controller/hello-primitive-modules/v4.32.0\nref:\ntag: v1\n---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: hello-world\nnamespace: flux-system\nspec:\npath: aws_hello_world\nvalues:\ngreeting: Hi\nsubject: my world\nsourceRef:\nkind: OCIRepository\nname: hello-package-v4.32.0\ninterval: 1h0m\napprovePlan: auto\n
"},{"location":"use_tf_controller/with_tf_runner_logging/","title":"Use TF-controller with Terraform Runners enabled via Env Variables","text":"

A Terraform Runner uses two environment variables, DISABLE_TF_LOGS and ENABLE_SENSITIVE_TF_LOGS, to control the logging behavior of the Terraform execution.

To use these environment variables, they need to be set on each Terraform Runner pod where the Terraform code is being executed. This can typically be done by adding them to the pod's environment variables in the Terraform Runner deployment configuration.

"},{"location":"use_tf_controller/with_tf_runner_logging/#the-default-logging-behavior","title":"The Default Logging Behavior","text":"

For more information on configuring the Terraform Runner and its environment variables, please consult the documentation on customizing runners within the Weave TF-controller.

"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/","title":"with the ready to use AWS package","text":""},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#use-tf-controller-with-the-ready-to-use-aws-package","title":"Use TF-controller with the ready-to-use AWS package","text":"

This document describes how to use the Weave TF-controller with the ready-to-use AWS package. It requires TF-controller v0.13+ to run the example.

"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#what-is-a-package","title":"What is a package?","text":"

A package is a collection of primitive Terraform modules that are bundled into an OCI image. You can think of a TF-controller's package as a thin wrapper around a Terraform module provider, and a TF-controller primitive module as a thin wrapper around a Terraform resource or a root module.

We will provide a set of ready-to-use packages for the most popular cloud providers. Currently, we ship the package for AWS only.

"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#aws-package","title":"AWS Package","text":"

To provide the out-of-the-box experience, the AWS Package is installed by default when you installed the TF-controller. Unlike other IaC implementation, our package model is designed to be very lightweight as a package is just a set of TF files in the form of OCI. Packages would not put any burden to your cluster. However, you can opt this package out by setting awsPackage.install: false in your Helm chart values.

If you run flux get sources oci you should see the AWS package installed in your cluster listed as aws-package.

flux get sources oci\nNAME          REVISION                    SUSPENDED   READY   MESSAGE                                                                                                         aws-package   v4.38.0-v1alpha11/6033f3b   False       True    stored artifact for digest 'v4.38.0-v1alpha11/6033f3b'\n
"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#a-step-by-step-tutorial","title":"A step-by-step tutorial","text":"

This section describes how to use the AWS package to provision an S3 bucket with ACL using the TF-controller.

"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#create-a-kind-local-cluster","title":"Create a KinD local cluster","text":"

If you don't have a Kubernetes cluster, you can create a KinD cluster with the following command:

kind create cluster\n
"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#install-flux","title":"Install Flux","text":"

After you have a Kubernetes cluster, you can install Flux with the following command:

flux install\n
"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#install-tf-controller","title":"Install TF-controller","text":"

Then, you can install the TF-controller with the following command:

kubectl apply -f https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/release.yaml\n
"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#setup-aws-credentials","title":"Setup AWS credentials","text":"

To provision AWS resources, you need to provide the AWS credentials to your Terraform objects. You can do this by creating a secret with the AWS credentials and reference it in each of your Terraform objects.

```yaml\napiVersion: v1\nkind: Secret\nmetadata:\n  name: aws-credentials\n  namespace: flux-system\ntype: Opaque\nstringData:\n  AWS_ACCESS_KEY_ID: Axxxxxxxxxxxxxxxxxxx\n  AWS_SECRET_ACCESS_KEY: qxxxxxxxxxxxxxxxxxxxxxxxxx\n  AWS_REGION: us-east-1 # the region you want\n

To apply the secret, run the following command:

kubectl apply -f aws-credentials.yaml\n
"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#setup-aws-bucket-and-acl","title":"Setup AWS Bucket and ACL","text":"

Now, you can create two Terraform objects, one for an S3 bucket, another one for ACL. Please note that we are using GitOps dependencies to make sure the ACL is created after the bucket is created. You can read more about the GitOps dependencies in the GitOps dependencies document.

```yaml\n---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\n  name: aws-s3-bucket\n  namespace: flux-system\n  labels:\n    tf.weave.works/composite: s3-bucket\nspec:\n  path: aws_s3_bucket\n  values:\n    bucket: my-tf-controller-test-bucket\n    tags:\n      Environment: Dev\n      Name: My bucket\n  sourceRef:\n    kind: OCIRepository\n    name: aws-package\n  approvePlan: auto\n  retryInterval: 10s\n  interval: 2m\n  destroyResourcesOnDeletion: true\nwriteOutputsToSecret:\n    name: aws-s3-bucket-outputs\n    outputs:\n    - arn\n    - bucket\n  runnerPodTemplate:\n    spec:\n      envFrom:\n      - secretRef:\n          name: aws-credentials\n---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\n  name: example-bucket-acl\n  namespace: flux-system\n  labels:\n    tf.weave.works/composite: s3-bucket\nspec:\n  path: aws_s3_bucket_acl\n  values:\n    acl: private\n    bucket: ${{ .aws_s3_bucket.bucket }}\nsourceRef:\n    kind: OCIRepository\n    name: aws-package\n  approvePlan: auto\n  retryInterval: 10s\n  interval: 3m\n  dependsOn:\n  - name: aws-s3-bucket\n  readInputsFromSecrets:\n  - name: aws-s3-bucket-outputs\n    as: aws_s3_bucket\n  destroyResourcesOnDeletion: true\nrunnerPodTemplate:\n    spec:\n      envFrom:\n      - secretRef:\n          name: aws-credentials\n
"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#rename-input-secrets","title":"Rename input secrets","text":"

The spec.readInputsFromSecrets field allows you to reference the Terraform outputs from other Terraform objects. In the context of this field, renaming makes it easier to reference the secrets in the spec.values field.

To rename a secret, you need to use the as key in the spec.readInputsFromSecrets field. The name key corresponds to the original name of the secret, while the as key represents the new name that you want to use to reference the secret.

In the example below, we can reference the bucket value from our aws_s3_bucket secret using ${{ .aws_s3_bucket.bucket }} instead of using the original secret name, which is aws-s3-bucket-outputs.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: example-bucket-acl\nnamespace: flux-system\nspec:\n# ...\nreadInputsFromSecrets:\n- name: aws-s3-bucket-outputs\nas: aws_s3_bucket\nvalues:\nacl: private\nbucket: ${{ .aws_s3_bucket.bucket }}\n# ...\n
"}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Overview","text":"

~> BREAKING NEWS: The Technology Preview of the Branch Planner is now available! Learn more or Get started with the Branch Planner.

TF-controller is a reliable controller for Flux to reconcile Terraform resources in the GitOps way. With the power of Flux together with Terraform, TF-controller allows you to GitOps-ify infrastructure, and application resources, in the Kubernetes and Terraform universe, at your own pace.

\"At your own pace\" means you don't need to GitOps-ify everything at once.

TF-controller offers many GitOps models:

  1. GitOps Automation Model: GitOps your Terraform resources from the provision steps to the enforcement steps, like a whole EKS cluster.
  2. Hybrid GitOps Automation Model: GitOps parts of your existing infrastructure resources. For example, you have an existing EKS cluster. You can choose to GitOps only its nodegroup, or its security group.
  3. State Enforcement Model: You have a TFSTATE file, and you'd like to use GitOps enforce it, without changing anything else.
  4. Drift Detection Model: You have a TFSTATE file, and you'd like to use GitOps just for drift detection, so you can decide to do things later when a drift occurs.

To get started, follow the getting started guide.

"},{"location":"#features","title":"Features","text":""},{"location":"#support-matrix","title":"Support Matrix","text":"Version Terraform Source Controller Flux v2 v0.15 v1.3.9 v1.0.x v2.0.x v0.14 v1.3.9 v0.31.0 v0.41.x v0.13 v1.3.1 v0.31.0 v0.36.x v0.12 v1.1.9 v0.26.1 v0.32.x"},{"location":"getting_started/","title":"Getting Started","text":""},{"location":"getting_started/#preflight-checks","title":"Preflight Checks","text":"

Here are the requirements you need to set up before you start:

  1. For Terraform Controller v0.15+, it requires Flux v2.0 or later (not only the CLI, but also the controllers on the cluster). If you are not sure about the Flux version on your cluster, please re-bootstrap your cluster.
  2. For Terraform Controller v0.13 and v0.14, Flux 2 v0.32 - v0.41 (of course, not only the CLI, but also the controllers on the cluster).
  3. TF-controller uses the Controller/Runner architecture. The Controller acts as a client, and talks to each Runner's Pod via gRPC. Please make sure
    1. Each Runner's Pod in each Namespace is allowed to open, and serve at port 30000 (the gRPC port of a Runner), and the Controller can connect to it.
    2. The Controller needs to download tar.gz BLOBs from the Source controller via port 80.
    3. The Controller needs to post the events to the Notification controller via port 80.
"},{"location":"getting_started/#installation","title":"Installation","text":"

Before using TF-controller, you have to install Flux by using either flux install or flux bootstrap command. Please note that TF-controller now requires Flux v2.0 or later, so please make sure you have the latest version of Flux. After that you can install TF-controller with Flux HelmRelease by:

kubectl apply -f https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/release.yaml\n

For the most recent release candidate of TF-controller, please use rc.yaml.

kubectl apply -f https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/rc.yaml\n
"},{"location":"getting_started/#with-branch-planner","title":"With Branch Planner","text":"
kubectl apply -f https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/branch_planner/release.yaml\n

For the most recent release candidate of TF-controller with Branch Planner, please use branch_planner/rc.yaml.

kubectl apply -f https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/branch_planner/rc.yaml\n

For more details about the Branch Planner, please visit the Branch Planner documentation.

"},{"location":"getting_started/#manual-installation","title":"Manual installation","text":"

With Helm by:

# Add tf-controller helm repository\nhelm repo add tf-controller https://weaveworks.github.io/tf-controller/\n\n# Install tf-controller\nhelm upgrade -i tf-controller tf-controller/tf-controller \\\n--namespace flux-system\n

For details on configurable parameters of the TF-controller chart, please see chart readme.

Alternatively, you can install TF-controller via kubectl:

export TF_CON_VER=v0.15.1\nkubectl apply -f https://github.com/weaveworks/tf-controller/releases/download/${TF_CON_VER}/tf-controller.crds.yaml\nkubectl apply -f https://github.com/weaveworks/tf-controller/releases/download/${TF_CON_VER}/tf-controller.rbac.yaml\nkubectl apply -f https://github.com/weaveworks/tf-controller/releases/download/${TF_CON_VER}/tf-controller.deployment.yaml\n
"},{"location":"getting_started/#quick-start","title":"Quick start","text":"

Here's a simple example of how to GitOps your Terraform resources with TF-controller and Flux.

"},{"location":"getting_started/#define-source","title":"Define source","text":"

First, we need to define a Source controller's source (GitRepository, Bucket, OCIRepository), for example:

apiVersion: source.toolkit.fluxcd.io/v1\nkind: GitRepository\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\ninterval: 30s\nurl: https://github.com/tf-controller/helloworld\nref:\nbranch: main\n
"},{"location":"getting_started/#the-gitops-automation-mode","title":"The GitOps Automation mode","text":"

The GitOps automation mode could be enabled by setting .spec.approvePlan=auto. In this mode, Terraform resources will be planned, and automatically applied for you.

apiVersion: infra.contrib.fluxcd.io/v1\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\ninterval: 1m\napprovePlan: auto\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n

For a full list of features and how to use them, please follow the Use TF-controller guide.

"},{"location":"getting_started/#other-examples","title":"Other Examples","text":""},{"location":"tfctl/","title":"tfctl","text":"

tfctl is a command-line utility to help with tf-controller operations.

"},{"location":"tfctl/#installation","title":"Installation","text":"

To install tfctl via Homebrew, run the following command:

brew install weaveworks/tap/tfctl\n

You can also download the tfctl binary via the GitHub releases page: https://github.com/weaveworks/tf-controller/releases.

Usage:\n  tfctl [command]\n\nAvailable Commands:\n  completion  Generate the autocompletion script for the specified shell\n  create      Create a Terraform resource\n  delete      Delete a Terraform resource\n  get         Get Terraform resources\n  help        Help about any command\n  install     Install the tf-controller\n  plan        Plan a Terraform configuration\n  reconcile   Trigger a reconcile of the provided resource\n  resume      Resume reconciliation for the provided resource\n  suspend     Suspend reconciliation for the provided resource\n  uninstall   Uninstall the tf-controller\n  version     Prints tf-controller and tfctl version information\n\nFlags:\n  -h, --help                help for tfctl\n      --kubeconfig string   Path to the kubeconfig file to use for CLI requests.\n  -n, --namespace string    The kubernetes namespace to use for CLI requests. (default \"flux-system\")\n      --terraform string    The location of the terraform binary. (default \"/usr/bin/terraform\")\n\nUse \"tfctl [command] --help\" for more information about a command.\n
"},{"location":"References/terraform/","title":"API References","text":"Terraform API reference

Packages:

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2","title":"infra.contrib.fluxcd.io/v1alpha2","text":"

Resource Types:

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.BackendConfigSpec","title":"BackendConfigSpec","text":"

(Appears on: TerraformSpec)

BackendConfigSpec is for specifying configuration for Terraform\u2019s Kubernetes backend

Field Description disable bool (Optional)

Disable is to completely disable the backend configuration.

secretSuffix string (Optional) inClusterConfig bool (Optional) customConfiguration string (Optional) configPath string (Optional) labels map[string]string (Optional)"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.BackendConfigsReference","title":"BackendConfigsReference","text":"

(Appears on: TerraformSpec)

Field Description kind string

Kind of the values referent, valid values are (\u2018Secret\u2019, \u2018ConfigMap\u2019).

name string

Name of the configs referent. Should reside in the same namespace as the referring resource.

keys []string (Optional)

Keys is the data key where a specific value can be found at. Defaults to all keys.

optional bool (Optional)

Optional marks this BackendConfigsReference as optional. When set, a not found error for the values reference is ignored, but any Key or transient error will still result in a reconciliation failure.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.BranchPlanner","title":"BranchPlanner","text":"

(Appears on: TerraformSpec)

Field Description enablePathScope bool (Optional)

EnablePathScope specifies if the Branch Planner should or shouldn\u2019t check if a Pull Request has changes under .spec.path. If enabled extra resources will be created only if there are any changes in terraform files.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.CloudSpec","title":"CloudSpec","text":"

(Appears on: TerraformSpec)

Field Description organization string workspaces CloudWorkspacesSpec hostname string (Optional) token string (Optional)"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.CloudWorkspacesSpec","title":"CloudWorkspacesSpec","text":"

(Appears on: CloudSpec)

Field Description name string (Optional) tags []string (Optional)"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.CrossNamespaceSourceReference","title":"CrossNamespaceSourceReference","text":"

(Appears on: TerraformSpec)

CrossNamespaceSourceReference contains enough information to let you locate the typed Kubernetes resource object at cluster level.

Field Description apiVersion string (Optional)

API version of the referent.

kind string

Kind of the referent.

name string

Name of the referent.

namespace string (Optional)

Namespace of the referent, defaults to the namespace of the Kubernetes resource object that contains the reference.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.FileMapping","title":"FileMapping","text":"

(Appears on: TerraformSpec)

Field Description secretRef github.com/fluxcd/pkg/apis/meta.SecretKeyReference

Reference to a Secret that contains the file content

location string

Location can be either user\u2019s home directory or the Terraform workspace

path string

Path of the file - relative to the \u201clocation\u201d

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.ForceUnlockEnum","title":"ForceUnlockEnum (string alias)","text":"

(Appears on: TFStateSpec)

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.HealthCheck","title":"HealthCheck","text":"

(Appears on: TerraformSpec)

HealthCheck contains configuration needed to perform a health check after terraform is applied.

Field Description name string

Name of the health check.

type string

Type of the health check, valid values are (\u2018tcp\u2019, \u2018http\u2019). If tcp is specified, address is required. If http is specified, url is required.

url string (Optional)

URL to perform http health check on. Required when http type is specified. Go template can be used to reference values from the terraform output (e.g. https://example.org, {{.output_url}}).

address string (Optional)

Address to perform tcp health check on. Required when tcp type is specified. Go template can be used to reference values from the terraform output (e.g. 127.0.0.1:8080, {{.address}}:{{.port}}).

timeout Kubernetes meta/v1.Duration (Optional)

The timeout period at which the connection should timeout if unable to complete the request. When not specified, default 20s timeout is used.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.LockStatus","title":"LockStatus","text":"

(Appears on: TerraformStatus)

LockStatus defines the observed state of a Terraform State Lock

Field Description lastApplied string (Optional) pending string (Optional)

Pending holds the identifier of the Lock Holder to be used with Force Unlock

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.PlanStatus","title":"PlanStatus","text":"

(Appears on: TerraformStatus)

Field Description lastApplied string (Optional) pending string (Optional) isDestroyPlan bool (Optional) isDriftDetectionPlan bool (Optional)"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.ReadInputsFromSecretSpec","title":"ReadInputsFromSecretSpec","text":"

(Appears on: TerraformSpec)

Field Description name string as string"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.ResourceInventory","title":"ResourceInventory","text":"

(Appears on: TerraformStatus)

ResourceInventory contains a list of Kubernetes resource object references that have been applied by a Kustomization.

Field Description entries []ResourceRef

Entries of Kubernetes resource object references.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.ResourceRef","title":"ResourceRef","text":"

(Appears on: ResourceInventory)

ResourceRef contains the information necessary to locate a resource within a cluster.

Field Description n string

Terraform resource\u2019s name.

t string

Type is Terraform resource\u2019s type

id string

ID is the resource identifier. This is cloud-specific. For example, ARN is an ID on AWS.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.RunnerPodMetadata","title":"RunnerPodMetadata","text":"

(Appears on: RunnerPodTemplate)

Field Description labels map[string]string (Optional)

Labels to add to the runner pod

annotations map[string]string (Optional)

Annotations to add to the runner pod

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.RunnerPodSpec","title":"RunnerPodSpec","text":"

(Appears on: RunnerPodTemplate)

Field Description image string (Optional)

Runner pod image to use other than default

envFrom []Kubernetes core/v1.EnvFromSource (Optional)

List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.

env []Kubernetes core/v1.EnvVar (Optional)

List of environment variables to set in the container. Cannot be updated.

nodeSelector map[string]string (Optional)

Set the NodeSelector for the Runner Pod

affinity Kubernetes core/v1.Affinity (Optional)

Set the Affinity for the Runner Pod

tolerations []Kubernetes core/v1.Toleration (Optional)

Set the Tolerations for the Runner Pod

volumeMounts []Kubernetes core/v1.VolumeMount (Optional)

Set Volume Mounts for the Runner Pod

volumes []Kubernetes core/v1.Volume (Optional)

Set Volumes for the Runner Pod

initContainers []Kubernetes core/v1.Container (Optional)

Set up Init Containers for the Runner

hostAliases []Kubernetes core/v1.HostAlias (Optional)

Set host aliases for the Runner Pod

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.RunnerPodTemplate","title":"RunnerPodTemplate","text":"

(Appears on: TerraformSpec)

Field Description metadata RunnerPodMetadata (Optional) spec RunnerPodSpec (Optional) image string (Optional)

Runner pod image to use other than default

envFrom []Kubernetes core/v1.EnvFromSource (Optional)

List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.

env []Kubernetes core/v1.EnvVar (Optional)

List of environment variables to set in the container. Cannot be updated.

nodeSelector map[string]string (Optional)

Set the NodeSelector for the Runner Pod

affinity Kubernetes core/v1.Affinity (Optional)

Set the Affinity for the Runner Pod

tolerations []Kubernetes core/v1.Toleration (Optional)

Set the Tolerations for the Runner Pod

volumeMounts []Kubernetes core/v1.VolumeMount (Optional)

Set Volume Mounts for the Runner Pod

volumes []Kubernetes core/v1.Volume (Optional)

Set Volumes for the Runner Pod

initContainers []Kubernetes core/v1.Container (Optional)

Set up Init Containers for the Runner

hostAliases []Kubernetes core/v1.HostAlias (Optional)

Set host aliases for the Runner Pod

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.TFStateSpec","title":"TFStateSpec","text":"

(Appears on: TerraformSpec)

TFStateSpec allows the user to set ForceUnlock

Field Description forceUnlock ForceUnlockEnum (Optional)

ForceUnlock a Terraform state if it has become locked for any reason. Defaults to no.

This is an Enum and has the expected values of:

WARNING: Only use auto in the cases where you are absolutely certain that no other system is using this state, you could otherwise end up in a bad place See https://www.terraform.io/language/state/locking#force-unlock for more information on the terraform state lock and force unlock.

lockIdentifier string (Optional)

LockIdentifier holds the Identifier required by Terraform to unlock the state if it ever gets into a locked state.

You\u2019ll need to put the Lock Identifier in here while setting ForceUnlock to either yes or auto.

Leave this empty to do nothing, set this to the value of the Lock Info: ID: [value], e.g. f2ab685b-f84d-ac0b-a125-378a22877e8d, to force unlock the state.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.Terraform","title":"Terraform","text":"

Terraform is the Schema for the terraforms API

Field Description metadata Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata field. spec TerraformSpec approvePlan string (Optional)

ApprovePlan specifies name of a plan wanted to approve. If its value is \u201cauto\u201d, the controller will automatically approve every plan.

destroy bool (Optional)

Destroy produces a destroy plan. Applying the plan will destroy all resources.

backendConfig BackendConfigSpec (Optional) backendConfigsFrom []BackendConfigsReference (Optional) cloud CloudSpec (Optional) workspace string (Optional) vars []Variable (Optional)

List of input variables to set for the Terraform program.

varsFrom []VarsReference (Optional)

List of references to a Secret or a ConfigMap to generate variables for Terraform resources based on its data, selectively by varsKey. Values of the later Secret / ConfigMap with the same keys will override those of the former.

values Kubernetes pkg/apis/apiextensions/v1.JSON (Optional)

Values map to the Terraform variable \u201cvalues\u201d, which is an object of arbitrary values. It is a convenient way to pass values to Terraform resources without having to define a variable for each value. To use this feature, your Terraform file must define the variable \u201cvalues\u201d.

fileMappings []FileMapping (Optional)

List of all configuration files to be created in initialization.

interval Kubernetes meta/v1.Duration

The interval at which to reconcile the Terraform.

retryInterval Kubernetes meta/v1.Duration (Optional)

The interval at which to retry a previously failed reconciliation. The default value is 15 when not specified.

path string (Optional)

Path to the directory containing Terraform (.tf) files. Defaults to \u2018None\u2019, which translates to the root path of the SourceRef.

sourceRef CrossNamespaceSourceReference

SourceRef is the reference of the source where the Terraform files are stored.

suspend bool (Optional)

Suspend is to tell the controller to suspend subsequent TF executions, it does not apply to already started executions. Defaults to false.

force bool (Optional)

Force instructs the controller to unconditionally re-plan and re-apply TF resources. Defaults to false.

readInputsFromSecrets []ReadInputsFromSecretSpec (Optional) writeOutputsToSecret WriteOutputsToSecretSpec (Optional)

A list of target secrets for the outputs to be written as.

disableDriftDetection bool (Optional)

Disable automatic drift detection. Drift detection may be resource intensive in the context of a large cluster or complex Terraform statefile. Defaults to false.

cliConfigSecretRef Kubernetes core/v1.SecretReference (Optional) healthChecks []HealthCheck (Optional)

List of health checks to be performed.

destroyResourcesOnDeletion bool (Optional)

Create destroy plan and apply it to destroy terraform resources upon deletion of this object. Defaults to false.

serviceAccountName string (Optional)

Name of a ServiceAccount for the runner Pod to provision Terraform resources. Default to tf-runner.

alwaysCleanupRunnerPod bool (Optional)

Clean the runner pod up after each reconciliation cycle

runnerTerminationGracePeriodSeconds int64 (Optional)

Configure the termination grace period for the runner pod. Use this parameter to allow the Terraform process to gracefully shutdown. Consider increasing for large, complex or slow-moving Terraform managed resources.

refreshBeforeApply bool (Optional)

RefreshBeforeApply forces refreshing of the state before the apply step.

runnerPodTemplate RunnerPodTemplate (Optional) enableInventory bool (Optional)

EnableInventory enables the object to store resource entries as the inventory for external use.

tfstate TFStateSpec (Optional) targets []string (Optional)

Targets specify the resource, module or collection of resources to target.

parallelism int32 (Optional)

Parallelism limits the number of concurrent operations of Terraform apply step. Zero (0) means using the default value.

storeReadablePlan string (Optional)

StoreReadablePlan enables storing the plan in a readable format.

webhooks []Webhook (Optional) dependsOn []github.com/fluxcd/pkg/apis/meta.NamespacedObjectReference (Optional) enterprise Kubernetes pkg/apis/apiextensions/v1.JSON (Optional)

Enterprise is the enterprise configuration placeholder.

planOnly bool (Optional)

PlanOnly specifies if the reconciliation should or should not stop at plan phase.

breakTheGlass bool (Optional)

BreakTheGlass specifies if the reconciliation should stop and allow interactive shell in case of emergency.

branchPlanner BranchPlanner

BarnchPlanner configuration.

status TerraformStatus"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.TerraformSpec","title":"TerraformSpec","text":"

(Appears on: Terraform)

TerraformSpec defines the desired state of Terraform

Field Description approvePlan string (Optional)

ApprovePlan specifies name of a plan wanted to approve. If its value is \u201cauto\u201d, the controller will automatically approve every plan.

destroy bool (Optional)

Destroy produces a destroy plan. Applying the plan will destroy all resources.

backendConfig BackendConfigSpec (Optional) backendConfigsFrom []BackendConfigsReference (Optional) cloud CloudSpec (Optional) workspace string (Optional) vars []Variable (Optional)

List of input variables to set for the Terraform program.

varsFrom []VarsReference (Optional)

List of references to a Secret or a ConfigMap to generate variables for Terraform resources based on its data, selectively by varsKey. Values of the later Secret / ConfigMap with the same keys will override those of the former.

values Kubernetes pkg/apis/apiextensions/v1.JSON (Optional)

Values map to the Terraform variable \u201cvalues\u201d, which is an object of arbitrary values. It is a convenient way to pass values to Terraform resources without having to define a variable for each value. To use this feature, your Terraform file must define the variable \u201cvalues\u201d.

fileMappings []FileMapping (Optional)

List of all configuration files to be created in initialization.

interval Kubernetes meta/v1.Duration

The interval at which to reconcile the Terraform.

retryInterval Kubernetes meta/v1.Duration (Optional)

The interval at which to retry a previously failed reconciliation. The default value is 15 when not specified.

path string (Optional)

Path to the directory containing Terraform (.tf) files. Defaults to \u2018None\u2019, which translates to the root path of the SourceRef.

sourceRef CrossNamespaceSourceReference

SourceRef is the reference of the source where the Terraform files are stored.

suspend bool (Optional)

Suspend is to tell the controller to suspend subsequent TF executions, it does not apply to already started executions. Defaults to false.

force bool (Optional)

Force instructs the controller to unconditionally re-plan and re-apply TF resources. Defaults to false.

readInputsFromSecrets []ReadInputsFromSecretSpec (Optional) writeOutputsToSecret WriteOutputsToSecretSpec (Optional)

A list of target secrets for the outputs to be written as.

disableDriftDetection bool (Optional)

Disable automatic drift detection. Drift detection may be resource intensive in the context of a large cluster or complex Terraform statefile. Defaults to false.

cliConfigSecretRef Kubernetes core/v1.SecretReference (Optional) healthChecks []HealthCheck (Optional)

List of health checks to be performed.

destroyResourcesOnDeletion bool (Optional)

Create destroy plan and apply it to destroy terraform resources upon deletion of this object. Defaults to false.

serviceAccountName string (Optional)

Name of a ServiceAccount for the runner Pod to provision Terraform resources. Default to tf-runner.

alwaysCleanupRunnerPod bool (Optional)

Clean the runner pod up after each reconciliation cycle

runnerTerminationGracePeriodSeconds int64 (Optional)

Configure the termination grace period for the runner pod. Use this parameter to allow the Terraform process to gracefully shutdown. Consider increasing for large, complex or slow-moving Terraform managed resources.

refreshBeforeApply bool (Optional)

RefreshBeforeApply forces refreshing of the state before the apply step.

runnerPodTemplate RunnerPodTemplate (Optional) enableInventory bool (Optional)

EnableInventory enables the object to store resource entries as the inventory for external use.

tfstate TFStateSpec (Optional) targets []string (Optional)

Targets specify the resource, module or collection of resources to target.

parallelism int32 (Optional)

Parallelism limits the number of concurrent operations of Terraform apply step. Zero (0) means using the default value.

storeReadablePlan string (Optional)

StoreReadablePlan enables storing the plan in a readable format.

webhooks []Webhook (Optional) dependsOn []github.com/fluxcd/pkg/apis/meta.NamespacedObjectReference (Optional) enterprise Kubernetes pkg/apis/apiextensions/v1.JSON (Optional)

Enterprise is the enterprise configuration placeholder.

planOnly bool (Optional)

PlanOnly specifies if the reconciliation should or should not stop at plan phase.

breakTheGlass bool (Optional)

BreakTheGlass specifies if the reconciliation should stop and allow interactive shell in case of emergency.

branchPlanner BranchPlanner

BarnchPlanner configuration.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.TerraformStatus","title":"TerraformStatus","text":"

(Appears on: Terraform)

TerraformStatus defines the observed state of Terraform

Field Description ReconcileRequestStatus github.com/fluxcd/pkg/apis/meta.ReconcileRequestStatus

(Members of ReconcileRequestStatus are embedded into this type.)

observedGeneration int64 (Optional)

ObservedGeneration is the last reconciled generation.

conditions []Kubernetes meta/v1.Condition (Optional) lastAppliedRevision string (Optional)

The last successfully applied revision. The revision format for Git sources is /. lastAttemptedRevision string (Optional)

LastAttemptedRevision is the revision of the last reconciliation attempt.

lastPlannedRevision string (Optional)

LastPlannedRevision is the revision used by the last planning process. The result could be either no plan change or a new plan generated.

lastPlanAt Kubernetes meta/v1.Time (Optional)

LastPlanAt is the time when the last terraform plan was performed

lastDriftDetectedAt Kubernetes meta/v1.Time (Optional)

LastDriftDetectedAt is the time when the last drift was detected

lastAppliedByDriftDetectionAt Kubernetes meta/v1.Time (Optional)

LastAppliedByDriftDetectionAt is the time when the last drift was detected and terraform apply was performed as a result

availableOutputs []string (Optional) plan PlanStatus (Optional) inventory ResourceInventory (Optional)

Inventory contains the list of Terraform resource object references that have been successfully applied.

lock LockStatus (Optional)"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.Variable","title":"Variable","text":"

(Appears on: TerraformSpec)

Field Description name string

Name is the name of the variable

value Kubernetes pkg/apis/apiextensions/v1.JSON (Optional) valueFrom Kubernetes core/v1.EnvVarSource (Optional)"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.VarsReference","title":"VarsReference","text":"

(Appears on: TerraformSpec)

VarsReference contain a reference of a Secret or a ConfigMap to generate variables for Terraform resources based on its data, selectively by varsKey.

Field Description kind string

Kind of the values referent, valid values are (\u2018Secret\u2019, \u2018ConfigMap\u2019).

name string

Name of the values referent. Should reside in the same namespace as the referring resource.

varsKeys []string (Optional)

VarsKeys is the data key at which a specific value can be found. Defaults to all keys.

optional bool (Optional)

Optional marks this VarsReference as optional. When set, a not found error for the values reference is ignored, but any VarsKey or transient error will still result in a reconciliation failure.

"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.Webhook","title":"Webhook","text":"

(Appears on: TerraformSpec)

Field Description stage string enabled bool (Optional) url string payloadType string (Optional) errorMessageTemplate string (Optional) testExpression string"},{"location":"References/terraform/#infra.contrib.fluxcd.io/v1alpha2.WriteOutputsToSecretSpec","title":"WriteOutputsToSecretSpec","text":"

(Appears on: TerraformSpec)

WriteOutputsToSecretSpec defines where to store outputs, and which outputs to be stored.

Field Description name string

Name is the name of the Secret to be written

labels map[string]string (Optional)

Labels to add to the outputted secret

annotations map[string]string (Optional)

Annotations to add to the outputted secret

outputs []string (Optional)

Outputs contain the selected names of outputs to be written to the secret. Empty array means writing all outputs, which is default.

This page was automatically generated with gen-crd-api-reference-docs

"},{"location":"adr/0000-template/","title":"0. Title","text":""},{"location":"adr/0000-template/#context","title":"Context","text":""},{"location":"adr/0000-template/#decision","title":"Decision","text":""},{"location":"adr/0000-template/#consequences","title":"Consequences","text":""},{"location":"adr/0000-use-adrs-for-decisions/","title":"1. Use ADRs to record decisions","text":""},{"location":"adr/0000-use-adrs-for-decisions/#context","title":"Context","text":"

Decisions that affect the development of Terraform Controller that are not captured via a proposal need to be captured in some way. We need a method that is lightweight and easy to discover the decision that have been made. The record of decisions will help future contributors to the project to understand why something has been implemented or is done a certain way.

"},{"location":"adr/0000-use-adrs-for-decisions/#decision","title":"Decision","text":"

The project will use Architectural Decision Records (ADR) to record decisions that are made outside of a proposal.

A template has been created based on prior work:

"},{"location":"adr/0000-use-adrs-for-decisions/#consequences","title":"Consequences","text":"

When decisions are made that affect the entire project then a new ADR needs to be created. Likewise, if a decision has been superseded then we need to capture this as a new ADR and mark the previous ADR as superseded. Maintainers and contributors will need to decide when an ADR is to be created.

"},{"location":"adr/0001-pr-polling-workflow/","title":"1. Pull Request Polling","text":""},{"location":"adr/0001-pr-polling-workflow/#context","title":"Context","text":"

To detect pull request changes, we can use webhooks or polling using GitHub's API.

"},{"location":"adr/0001-pr-polling-workflow/#decision","title":"Decision","text":"

We decided to start with polling for security reasons. Using webhooks would require users to open an ingress to the cluster. Because of this requirement, we think security conscious folks may refuse to roll this out on production clusters especially in an air-gapped environment. This does not mean that we will never consider using webhooks for this, but that initially, polling is what we have chosen to implement.

The Branch-Based Planner has two components:

  1. Polling Server: Detect Pull Request changes and manage Teraform resource state.
  2. Informer: Make a comment when new plan output is available.
"},{"location":"adr/0001-pr-polling-workflow/#consequences","title":"Consequences","text":"

The list Pull Requests endpoint returns all required fields to detect new and closed pull requests. It's one request per repository, but listing comments has to use an API request per pull request. So we have to add a mechanism to avoid hitting API rate limits.

"},{"location":"adr/0002-deny-cross-ns-by-default/","title":"2. Deny cross-namespace refs by default","text":""},{"location":"adr/0002-deny-cross-ns-by-default/#context","title":"Context","text":"

Like Flux, the tf-controller API has a handful of places where it accepts cross-namespace references.

In general in Kubernetes, references to objects in other namespaces are frowned upon, because

Both of these effects make a system less secure.

However: removing cross-namespace refs entirely would break some installations in a way that would be difficult to fix, because Flux deployments often rely on defining sources away from objects that use them.

"},{"location":"adr/0002-deny-cross-ns-by-default/#decision","title":"Decision","text":"

Deny cross-namespace references by default, but allow them to be enabled with a flag.

So that the default value means the right thing, the flag name must be enable-cross-namespace-refs, and the default false. To avoid confusion when people try to use the Flux version of this flag --disable-cross-namespace-refs, it should be supported too, but only respected if supplied.

"},{"location":"adr/0002-deny-cross-ns-by-default/#consequences","title":"Consequences","text":"

The changed default will break deployments that rely on cross-namespace refs, but they are easily fixed with the flag.

New deployments will be more secure, by default.

"},{"location":"branch_planner/","title":"Branch Planner User Guide","text":""},{"location":"branch_planner/#overview","title":"Overview","text":"

The Branch Planner, a new component of the Terraform Controller, is specifically designed to enhance the flexibility and robustness of Terraform Controller planning operations. This feature, currently in its technology preview phase, facilitates Terraform planning across branches, creating a streamlined and familiar PR-based workflow for users.

"},{"location":"branch_planner/#how-does-it-work","title":"How does it work?","text":"

When the Branch Planner starts, it polls repositories that contain Terraform resources at regular intervals, in order to detect Pull Requests (PR) that change those resources. Upon detecting that a PR exists, the Branch Planner initialises a Terraform object in Plan Only mode for the corresponding branch. In this mode, Terraform Controller generates Terraform plans but does not apply them. Once the plan is generated, Branch Planner posts the plan under the PR as a comment enabling users to review the plan. When the Terraform files of the corresponding branch get updated, Branch Planner posts the updated plan under the PR as new comment, keeping the PR up-to-date with the latest Terraform plan.

"},{"location":"branch_planner/#replan-commands","title":"Replan commands","text":"

The Branch Planner also allows users to manually trigger the replan process. By simply commenting !replan under the PR, the Branch Planner will be instructed to generate a new plan and post it under the PR as a new comment.

Now that you know what Branch Planner can do for you, follow the guide to get started.

"},{"location":"branch_planner/getting-started/","title":"Getting Started With Branch Planner","text":"

When the Branch Planner is enabled through Helm values, it will watch all configured Terraform resources, check their referenced Source, and poll for Pull Requests using GitHub's API plus the provided token.

When the Branch Planner detects an open Pull Request, it either creates a new Terraform object or updates an existing one, applying Plan Only mode based on the original Terraform object.

When a Plan Output becomes available, the Branch Planner creates a new comment under the Pull Request with the content of the Plan Output included.

"},{"location":"branch_planner/getting-started/#prerequisites","title":"Prerequisites","text":"
  1. Flux is installed on the cluster.
  2. A GitHub API token.
  3. Knowledge about GitOps Terraform Controller (see docs).
"},{"location":"branch_planner/getting-started/#quick-start-guide","title":"Quick Start Guide","text":"

This section describe how to install Branch Planner using HelmRelease object in the flux-system namespace with minimum configuration on a KinD cluster.

  1. Create a KinD cluster.

    kind create cluster\n

  2. Install Flux. Please make sure you have the latest version of Flux (v2 GA).

    flux install\n

  3. Create a Secret that contains GitHub API token. If you do not use gh cli, please feel free to copy and paste the token from GitHub's website.

    export GITHUB_TOKEN=$(gh auth token)\n\nkubectl create secret generic branch-planner-token \\\n    --namespace=flux-system \\\n    --from-literal=\"token=${GITHUB_TOKEN}\"\n

  4. Install Branch Planner from a HelmRelease provided by the TF-controller repository. Please make sure that you use TF Controller v0.16.0-rc.2 or later.

    kubectl apply -f https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/branch_planner/release.yaml\n

  5. Create a Terraform object with a Source pointing to a repository. You repository must contain a Terraform file, for example main.tf. Please take a look at https://github.com/tf-controller/branch-planner-demo for an example.

    export GITHUB_USER=<your user>\nexport GITHUB_REPO=<your repo>\n\ncat <<EOF | kubectl apply -f -\n---\napiVersion: source.toolkit.fluxcd.io/v1\nkind: GitRepository\nmetadata:\n  name: branch-planner-demo\n  namespace: flux-system\nspec:\n  interval: 30s\n  url: https://github.com/${GITHUB_USER}/${GITHUB_REPO}\n  ref:\n    branch: main\n---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\n  name: branch-planner-demo\n  namespace: flux-system\nspec:\n  approvePlan: auto\n  path: ./\n  interval: 1m\n  sourceRef:\n    kind: GitRepository\n    name: branch-planner-demo\n    namespace: flux-system\nEOF\n

  6. Now you can go to your GitHub repo and create a Pull Request. The Branch Planner will create a new Terraform object with Plan Only mode enabled, and generate a new plan for you.
"},{"location":"branch_planner/getting-started/#configure-branch-planner","title":"Configure Branch Planner","text":"

Branch Planner uses a ConfigMap as configuration. That ConfigMap is optional to use but useful for fine-tuning Branch Planner.

"},{"location":"branch_planner/getting-started/#custom-configuration","title":"Custom Configuration","text":"

By default Branch Planner will look for a branch-planner ConfigMap in the same namespace as where the tf-controller is installed. That ConfigMap allows users to precisely specify which Terraform resources in a cluster should be monitored by Branch Planner.

The ConfigMap has two fields:

  1. secretName, which contains the API token to access GitHub.
  2. resources, which defines a list of resources to watch.
---\napiVersion: v1\nkind: ConfigMap\nmetadata:\nnamespace: flux-system\nname: branch-planner\ndata:\nsecretName: branch-planner-token\nresources: |-\n- namespace: terraform\n
"},{"location":"branch_planner/getting-started/#secret","title":"Secret","text":"

Branch Planner uses the referenced Secret with a token field that acquires the API token to fetch Pull Request information.

kubectl create secret generic branch-planner-token \\\n--namespace=flux-system \\\n--from-literal=\"token=${GITHUB_TOKEN}\"\n
"},{"location":"branch_planner/getting-started/#resources","title":"Resources","text":"

If the resources list is empty, nothing will be watched. The resource definition can be exact or namespace-wide.

With the following configuration file, the Branch Planner will watch all Terraform objects in the terraform namespace, and the exact-terraform-object Terraform object in default namespace.

data:\nresources:\n- namespace: default\nname: exact-terraform-object\n- namespace: terraform\n
"},{"location":"branch_planner/getting-started/#default-configuration","title":"Default Configuration","text":"

If a ConfigMap is not found, it will watch the flux-system namespace for any Terraform resources and expect to find a GitHub token in a secret named branch-planner-token in the flux-system namespace. Note that supplying a secret with a token is a necessary task, otherwise Branch Planner will not be able to interact with the GitHub API.

"},{"location":"branch_planner/getting-started/#enable-branch-planner","title":"Enable Branch Planner","text":"

To enable branch planner, set the branchPlanner.enabled to true in the Helm values files.

---\nbranchPlanner:\n  enabled: true\n
"},{"location":"branch_planner/least-required-permissions/","title":"Least Required Permissions For Git Providers","text":""},{"location":"branch_planner/least-required-permissions/#github","title":"GitHub","text":""},{"location":"branch_planner/least-required-permissions/#fine-grained-personal-access-token","title":"Fine-Grained Personal Access Token","text":"

For public repositories, it's sufficient to enable Public Repositories, without any additional permissions.

For private repositories the following permissions are required:

"},{"location":"how_to/","title":"How to","text":""},{"location":"how_to/backup_and_restore_a_Terraform_state/","title":"Backup and restore a Terraform state","text":""},{"location":"how_to/backup_and_restore_a_Terraform_state/#backup-the-tfstate","title":"Backup the tfstate","text":"

Assume that we have the my-stack Terraform object with its .spec.workspace set to \"default\".

kubectl get terraform\n\nNAME       READY     STATUS         AGE\nmy-stack   Unknown   Initializing   28s\n

We can backup its tfstate out of the cluster, like this:

WORKSPACE=default\nNAME=my-stack\n\nkubectl get secret tfstate-${WORKSPACE}-${NAME} \\\n-ojsonpath='{.data.tfstate}' \\\n| base64 -d | gzip -d > terraform.tfstate\n
"},{"location":"how_to/backup_and_restore_a_Terraform_state/#restore-the-tfstate","title":"Restore the tfstate","text":"

To restore the tfstate file or import an existing tfstate file to the cluster, we can use the following operation:

gzip terraform.tfstate\n\nWORKSPACE=default\nNAME=my-stack\n\nkubectl create secret \\\ngeneric tfstate-${WORKSPACE}-${NAME} \\\n--from-file=tfstate=terraform.tfstate.gz \\\n--dry-run=client -o=yaml \\\n| yq e '.metadata.annotations[\"encoding\"]=\"gzip\"' - \\\n> tfstate-${WORKSPACE}-${NAME}.yaml\n\nkubectl apply -f tfstate-${WORKSPACE}-${NAME}.yaml\n
"},{"location":"how_to/interval_and_retryInterval/","title":"How does the interval and retryInterval work?","text":""},{"location":"how_to/interval_and_retryInterval/#overview","title":"Overview","text":"

This document describes the requeue behavior of the Reconcile method in the TerraformReconciler struct in the code base. Understanding these behaviors can be crucial for troubleshooting, as well as for future development and refinement of the system.

"},{"location":"how_to/interval_and_retryInterval/#requeue-behaviors","title":"Requeue Behaviors","text":"

The Reconcile method has several requeue behaviors based on different conditions and errors. We will group them into four categories based on their requeue behavior:

"},{"location":"how_to/interval_and_retryInterval/#1-immediate-requeue-not-using-specified-interval-retryinterval","title":"1. Immediate Requeue (Not using specified interval / retryInterval)","text":"

In these scenarios, the Reconcile method returns an error which leads to an immediate requeue orchestrated by the Controller Runtime. The interval is based on the controller's configuration and not specified in the method itself:

"},{"location":"how_to/interval_and_retryInterval/#2-requeue-after-a-specific-interval-specretryinterval","title":"2. Requeue After a Specific Interval (spec.retryInterval)","text":"

In these scenarios, the method specifically asks for a requeue after a certain interval specified by spec.retryInterval (default to 15s).

"},{"location":"how_to/interval_and_retryInterval/#3-requeue-after-a-specific-interval-specinterval","title":"3. Requeue After a Specific Interval (spec.interval)","text":"

In this scenario, the method specifically asks for a requeue after a successful reconciliation:

The interval for the requeue is spec.interval.

"},{"location":"how_to/interval_and_retryInterval/#4-no-requeue-wait-for-manual-intervention","title":"4. No Requeue, wait for manual intervention","text":"

In these scenarios, the method returns without asking for a requeue, and the Controller Runtime will stop the reconciliation process until there is a manual intervention:

"},{"location":"how_to/resource_deletion/","title":"Resource Deletion Dependencies in Terraform Controller","text":"

This document discusses potential difficulties you may encounter when deleting Terraform resources through the Terraform Controller and the necessary components to facilitate a smooth deletion process.

"},{"location":"how_to/resource_deletion/#source-object","title":"Source Object","text":"

The source object (e.g., GitRepository or OCIRepository) is a critical component of the Terraform resource deletion process. This object houses the Terraform source files (.tf files) that describe the configuration of the infrastructure resources.

During the deletion process, the Terraform Controller uses these source files to conduct a re-planning operation. This operation is instrumental to deleting the Terraform Custom Resource (CR).

However, if the source object is unavailable or has been deleted, the re-planning operation fails. As a result, the Terraform Controller cannot locate the resource state, leading to an infinite deletion attempt cycle, commonly known as a looping process.

"},{"location":"how_to/resource_deletion/#role-bindings","title":"Role Bindings","text":"

Role bindings assign permissions to Terraform runners, allowing them to execute operations within the Kubernetes cluster. These bindings define the actions that the Terraform runners are authorized to carry out.

If role bindings are missing or misconfigured, the Terraform runners may lack the necessary permissions to execute the deletion process, causing the process to fail.

"},{"location":"how_to/resource_deletion/#secrets-and-configmaps","title":"Secrets and ConfigMaps","text":"

Before initiating the resource deletion process, the Terraform Controller leverages Secrets and ConfigMaps to generate a complete source before planning. Secrets store confidential data like API keys or passwords, while ConfigMaps hold configuration data in a key-value format.

Should any of these components be missing or misconfigured, the Terraform Controller may fail to generate an accurate deletion plan, which could impede the resource deletion process.

"},{"location":"how_to/resource_deletion/#troubleshooting","title":"Troubleshooting","text":"

To prevent the aforementioned issues, ensure the availability and proper configuration of the source object, role bindings, and Secrets and ConfigMaps during the deletion process.

As of now, we are actively working to address these limitations in the Terraform Controller. We appreciate your patience and welcome any feedback to help enhance the Terraform Controller's performance.

"},{"location":"how_to/troubleshooting_with_break_the_glass_mode/","title":"Break the glass","text":""},{"location":"how_to/troubleshooting_with_break_the_glass_mode/#what-is-break-the-glass","title":"What is break the glass?","text":"

\"Break the glass\" refers to a troubleshooting mode specifically designed to provide a manual solution when the Terraform controller (TF-controller) is not performing as expected. This feature is available in the Terraform controller v0.15.0 and above.

~> WARNING: Please note that you cannot use this feature to fix the Terraform resources with v1alpha1 version of the Terraform CRD. It works only with v1alpha2 version of the Terraform CRD.

~> WARNING: Please also make sure that you have enough privileges to exec pods in your namespaces. Otherwise, you will not be able to use this feature.

There are two primary methods of initiating this mode:

  1. Using the tfctl command-line tool.
  2. Setting the spec.breakTheGlass field to true in the Terraform object.
"},{"location":"how_to/troubleshooting_with_break_the_glass_mode/#using-tfctl-to-break-the-glass","title":"Using tfctl to Break the Glass","text":"

To start a one-time troubleshooting session, you can use the tfctl break-glass command. For instance:

tfctl break-glass hello-world\n

This command initiates a session that allows you to execute any Terraform command to rectify the issues with your Terraform resources. It is noteworthy that this command does not require setting the spec.breakTheGlass field to true in the Terraform object.

After resolving the issues, you can simply exit the shell. GitOps will then continue to reconcile the Terraform object.

"},{"location":"how_to/troubleshooting_with_break_the_glass_mode/#break-the-glass-with-specbreaktheglass-field","title":"Break the glass with spec.breakTheGlass field","text":"

This feature is particularly useful for troubleshooting Terraform objects at their initialization stage or in situations with unexpected errors. It is generally not recommended to use this mode routinely for fixing Terraform resources.

You can enable the 'Break the Glass' feature for every reconciliation by setting the breakTheGlass field to true in the spec of the Terraform object.

Here is a sample example:

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: hello-world\nnamespace: flux-system\nspec:\nbreakTheGlass: true\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n
"},{"location":"use_tf_controller/","title":"Use TF-controller","text":""},{"location":"use_tf_controller/to_detect_drifts_only_without_plan_or_apply/","title":"To detect drifts only without plan or apply","text":""},{"location":"use_tf_controller/to_detect_drifts_only_without_plan_or_apply/#use-tf-controller-to-detect-drifts-only-without-plan-or-apply","title":"Use TF-controller to detect drifts only without plan or apply","text":"

We can set .spec.approvePlan to disable to tell the controller to detect drifts of your Terraform resources only. Doing so will skip the plan and apply stages.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: hello-world\nnamespace: flux-system\nspec:\napprovePlan: disable\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n
"},{"location":"use_tf_controller/to_force_unlock_Terraform_states/","title":"Use TF-controller to force unlock Terraform states","text":"

In some situations, you may need to perform the Terraform force-unlock operation on the tfstate inside the cluster.

There are three possible values of .spec.tfstate.forceUnlock, which are yes, no, and auto. The default value is no, which means that you disable this behaviour.

The auto force-unlock mode will automatically use the lock identifier produced by the associated state file instead of specified lock identifier.

The recommended way is to do manual force unlock. To manually force-unlock, you need to:

  1. set forceUnlock to yes, and
  2. specify a lock identifier to unlock a specific locked state,

as the following example:

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\ntfstate:\nforceUnlock: \"yes\"\nlockIdentifier: f2ab685b-f84d-ac0b-a125-378a22877e8d\n
"},{"location":"use_tf_controller/to_plan_and_manually_apply_Terraform_resources/","title":"Use TF-controller to plan and manually apply Terraform resources","text":"

In this guide, we will walk through the steps of using TF-controller to plan and manually apply Terraform resources.

We will start by creating the Terraform object and specifying the necessary fields, including the approvePlan field.

We will then create the GitRepository object, which points to the Git repository containing the Terraform configuration.

Once these objects are created, we will use kubectl to obtain the approvePlan value and set it in the Terraform object. After making our changes and pushing them to the Git repository, TF-controller will apply the plan and create the real resources.

"},{"location":"use_tf_controller/to_plan_and_manually_apply_Terraform_resources/#define-the-terraform-object","title":"Define the Terraform object","text":"

Assume that you have a GitRepository object named helloworld pointing to a Git repository, and you want to plan and apply the Terraform resources under ./ of that Git repo.

For the plan & manual approval workflow, please start by either setting .spec.approvePlan to be the blank value, or omitting the field. This will tell TF-controller to use the plan & manual approval workflow, rather than the auto-apply workflow. If you want to use the auto-apply workflow, you will need to set the spec.approvePlan field to \"auto\".

In addition to setting the spec.approvePlan field, you will also need to specify the interval, path, and sourceRef fields in the spec field. The interval field determines how often TF-controller will run the Terraform configuration, the path field specifies the location of the configuration files, and the sourceRef field points to the GitRepository object.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: \"\" # or you can omit this field\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n
"},{"location":"use_tf_controller/to_plan_and_manually_apply_Terraform_resources/#view-the-approval-message","title":"View the approval message","text":"

Then after a reconciliation loop, the controller will generate a plan, and tell you how to use field .spec.approvePlan to approve the plan. You can run the following command to obtain that message.

kubectl -n flux-system get tf/helloworld\n

This command will output the message containing the approvePlan value that you will need to use to approve the plan. Once you have this value, you can edit the Terraform object file, and set the spec.approvePlan field to the value obtained from the message.

After making your changes and pushing them to the Git repository, TF-controller will apply the plan and create the real resources. This process is known as the plan & manual approval workflow, as it involves generating a plan and requiring manual approval before the changes are applied.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: hello-world\nnamespace: flux-system\nspec:\napprovePlan: plan-main-b8e362c206 # first 8 digits of a commit hash is enough\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n
"},{"location":"use_tf_controller/to_provision_Terraform_resources_that_are_required_health_checks/","title":"Use TF-controller to provision Terraform resources that are required health checks","text":"

For some Terraform resources, it may be useful to perform health checks on them to verify that they are ready to accept connection before the terraform goes into Ready state:

For example, our Terraform file is provisioned and contains the following outputs.

# main.tf\noutput \"rdsAddress\" {\nvalue = \"mydb.xyz.us-east-1.rds.amazonaws.com\"\n}\noutput \"rdsPort\" {\nvalue = \"3306\"\n}\noutput \"myappURL\" {\nvalue = \"https://example.com/\"\n}\n

We can use standard Go template expressions, like ${{ .rdsAddress }}, to refer to those output values and use them to verify that the resources are up and running.

We support two types of health checks, tcp amd http. The tcp type allows us to verify a TCP connection, while the http type is for verify an HTTP URL. The default timeout of each health check is 20 seconds.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nhealthChecks:\n- name: rds\ntype: tcp\naddress: ${{ .rdsAddress }}:${{ .rdsPort }} timeout: 10s # optional, defaults to 20s\n- name: myapp\ntype: http\nurl: ${{ .myappURL }}\ntimeout: 5s\n- name: url_not_from_output\ntype: http\nurl: \"https://example.org\"\n
"},{"location":"use_tf_controller/to_provision_resources_and_auto_approve/","title":"Use TF-controller to provision resources and auto approve","text":"

To provision resources with TF-controller, you need to create a Terraform object and a Flux source object, such as a GitRepository or OCIRepository object.

"},{"location":"use_tf_controller/to_provision_resources_and_auto_approve/#create-a-terraform-object","title":"Create a Terraform object","text":"

The Terraform object is a Kubernetes custom resource definition (CRD) object. It is the core object of TF-controller and defines the Terraform module, backend configuration, and GitOps automation mode..

It defines the Terraform module, the backend configuration, and the GitOps automation mode.

The Terraform module is a Terraform configuration that can be used to provision resources. It can be placed inside a Git repository, or packaged as an OCI image in an OCI registry.

The backend configuration is the configuration for the Terraform backend to be used to store the Terraform state. It is optional. If not specified, the Kubernetes backend will be used by default.

"},{"location":"use_tf_controller/to_provision_resources_and_auto_approve/#gitops-automation-mode","title":"GitOps automation mode","text":"

The GitOps automation mode is the GitOps automation mode to be used to run the Terraform module. It determines how Terraform runs and manages your infrastructure. It is optional. If not specified, the \"plan-and-manually-apply\" mode will be used by default. In the \"plan-and-manually-apply\" mode, TF-controller will run a Terraform plan and output the proposed changes to a Git repository. A human must then review and manually apply the changes. This is the default GitOps automation mode if none is specified.

In the \"auto-apply\" mode, TF-controller will automatically apply the changes after a Terraform plan is run. This can be useful for environments where changes can be made automatically, but it is important to ensure that the proper controls, like policies, are in place to prevent unintended changes from being applied.

To specify the GitOps automation mode in a Terraform object, you can set the spec.approvePlan field to the desired value. For example, to use the \"auto-apply\" mode, y ou would set it to spec.approvePlan: auto.

It is important to carefully consider which GitOps automation mode is appropriate for your use case to ensure that your infrastructure is properly managed and controlled.

The following is an example of a Terraform object; we use the \"auto-apply\" mode:

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nspec:\npath: ./helloworld\ninterval: 10m\napprovePlan: auto\nsourceRef:\nkind: GitRepository\nname: helloworld\n

This code is defining a Terraform object in Kubernetes. The apiVersion field specifies the version of the Kubernetes API being used, and the kind field specifies that it is a Terraform object. The metadata block contains information about the object, including its name.

The spec field contains the specification for the Terraform object. The path field specifies the path to the Terraform configuration files, in this case a directory named \"helloworld\". The interval field specifies the frequency at which TF-controller should run the Terraform configuration, in this case every 10 minutes. The approvePlan field specifies whether or not to automatically approve the changes proposed by a Terraform plan. In this case, it is set to auto, meaning that changes will be automatically approved.

The sourceRef field specifies the Flux source object to be used. In this case, it is a GitRepository object with the name \"helloworld\". This indicates that the Terraform configuration is stored in a Git repository object with the name helloworld.

"},{"location":"use_tf_controller/to_provision_resources_and_destroy_them_when_the_Terraform_object_gets_deleted/","title":"Use TF-controller to provision resources and destroy them when the Terraform object gets deleted","text":"

The resources provisioned by a Terraform object are not destroyed by default, and the tfstate of that Terraform object still remains in the cluster.

It means that you are safe to delete the Terraform object in the cluster and re-create it. If you re-create a new Terraform object with the same name, namespace and workspace, it will continue to use the tfstate inside the cluster as the starting point to reconcile.

However, you may want to destroy provisioned resources when delete the Terraform object in many scenarios. To enable destroy resources on object deletion, set .spec.destroyResourcesOnDeletion to true.

~> WARNING: This feature will destroy your resources on the cloud if the Terraform object gets deleted. Please use it with cautions.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ndestroyResourcesOnDeletion: true\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n
"},{"location":"use_tf_controller/to_provision_resources_and_obtain_outputs/","title":"Use TF-controller to provision resources and obtain outputs","text":"

Outputs created by Terraform can be written to a secret using .spec.writeOutputsToSecret.

"},{"location":"use_tf_controller/to_provision_resources_and_obtain_outputs/#write-all-outputs","title":"Write all outputs","text":"

We can specify a target secret in .spec.writeOutputsToSecret.name, and the controller will write all outputs to the secret by default.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nwriteOutputsToSecret:\nname: helloworld-output\n
"},{"location":"use_tf_controller/to_provision_resources_and_obtain_outputs/#write-outputs-selectively","title":"Write outputs selectively","text":"

We can choose only a subset of outputs by specify output names we'd like to write in the .spec.writeOutputsToSecret.outputs array.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nwriteOutputsToSecret:\nname: helloworld-output\noutputs:\n- hello_world\n- my_sensitive_data\n
"},{"location":"use_tf_controller/to_provision_resources_and_obtain_outputs/#rename-outputs","title":"Rename outputs","text":"

Some time we'd like to use rename an output, so that it can be consumed by other Kubernetes controllers. For example, we might retrieve a key from a Secret manager, and it's an AGE key, which must be ending with \".agekey\" in the secret. In this case, we need to rename the output.

TF-controller supports mapping output name using the old_name:new_name format.

In the following example, we renamed age_key output as age.agekey entry for the helloworld-output Secret's data, so that other components in the GitOps pipeline could consume it.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nwriteOutputsToSecret:\nname: helloworld-output\noutputs:\n- age_key:age.agekey\n
"},{"location":"use_tf_controller/to_provision_resources_and_obtain_outputs/#customize-metadata-of-the-outputted-secret","title":"Customize metadata of the outputted secret","text":"

In some situations, it is needed to add custom labels and annotations to the outputted secret. As an example, operators such as kubernetes-replicator allow replicating secrets from one namespace to another but use annotations to do so.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nwriteOutputsToSecret:\nname: helloworld-output\nlabels:\nmy-label: true\nannotations:\nmy-annotation: \"very long string\"\n
"},{"location":"use_tf_controller/to_provision_resources_with_customized_Runner_Pods/","title":"Use TF-controller to provision resources with customized Runner Pods","text":""},{"location":"use_tf_controller/to_provision_resources_with_customized_Runner_Pods/#customize-runner-pods-metadata","title":"Customize Runner Pod's metadata","text":"

In some situations, it is needed to add custom labels and annotations to the runner pod used to reconcile Terraform. For example, for Azure AKS to grant pod active directory permissions using Azure Active Directory (AAD) Pod Identity, a label like aadpodidbinding: myIdentity on the pod is required.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nrunnerPodTemplate:\nmetadata:\nlabels:\naadpodidbinding: myIdentity\nannotations:\ncompany.com/abc: xyz\n
"},{"location":"use_tf_controller/to_provision_resources_with_customized_Runner_Pods/#customize-runner-pod-image","title":"Customize Runner Pod Image","text":"

By default, the Terraform controller uses RUNNER_POD_IMAGE environment variable to identify the Runner Pod's image to use. You can customize the image on the global level by updating the value of the environment variable or, you can specify an image to use per Terraform object for its reconciliation.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nrunnerPodTemplate:\nspec:\nimage: registry.io/tf-runner:xyz\n

You can use runner.Dockerfile as a basis of customizing runner pod image.

"},{"location":"use_tf_controller/to_provision_resources_with_customized_Runner_Pods/#customize-runner-pod-specifications","title":"Customize Runner Pod Specifications","text":"

You can also customize various Runner Pod spec fields to control and configure how the Runner Pod runs. For example, you can configure Runner Pod spec affinity and tolerations if you need to run in on a specific set of nodes. Please see RunnerPodSpec for a list of the configurable Runner Pod spec fields.

"},{"location":"use_tf_controller/to_set_variables_for_Terraform_resources/","title":"Use TF-controller to set variables for Terraform resources","text":"

~> BREAKING CHANGE: This is a breaking change of the v1alpha1 API.

Users who are upgrading from TF-controller <= 0.7.0 require updating varsFrom, from a single object:

  varsFrom:\nkind: ConfigMap\nname: cluster-config\n

to be an array of object, like this:

  varsFrom:\n- kind: ConfigMap\nname: cluster-config\n
"},{"location":"use_tf_controller/to_set_variables_for_Terraform_resources/#vars-and-varsfrom","title":"vars and varsFrom","text":"

You can pass variables to Terraform using the vars and varsFrom fields.

Inline variables can be set using vars. The varsFrom field accepts a list of ConfigMaps / Secrets. You may use the varsKeys property of varsFrom to select specific keys from the input or omit this field to select all keys from the input source.

Note that in the case of the same variable key being passed multiple times, the controller will use the lattermost instance of the key passed to varsFrom.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nvars:\n- name: region\nvalue: us-east-1\n- name: env\nvalue: dev\n- name: instanceType\nvalue: t3-small\nvarsFrom:\n- kind: ConfigMap\nname: cluster-config\nvarsKeys:\n- nodeCount\n- instanceType\n- kind: Secret\nname: cluster-creds\n
"},{"location":"use_tf_controller/to_set_variables_for_Terraform_resources/#variable-value-as-hcl","title":"Variable value as HCL","text":"

The vars field supports HCL string, number, bool, object and list types. For example, the following variable can be populated using the accompanying Terraform spec:

variable \"cluster_spec\" {\ntype = object({\nregion     = string\nenv        = string\nnode_count = number\npublic     = bool\n})\n}\n
apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nvars:\n- name: cluster_spec\nvalue:\nregion: us-east-1\nenv: dev\nnode_count: 10\npublic: false\n
"},{"location":"use_tf_controller/to_set_variables_for_Terraform_resources/#rename-variables-in-varsfrom","title":"Rename variables in varsFrom","text":"

To rename a variable, you can use the varsKeys key within the varsFrom field. Here's the basic structure:

spec:\nvarsFrom:\n- kind: Secret\nname: <secret_name>\nvarsKeys:\n- <original_variable_name>:<new_variable_name>\n
original_variable_name corresponds to the initial name of the variable in the referenced secret, while new_variable_name represents the alias you want to use within the Terraform code.

Consider this example below, where we rename nodeCount to node_count and instanceType to instance_type:

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nvarsFrom:\n- kind: Secret\nname: cluster-config\nvarsKeys:\n- nodeCount:node_count\n- instanceType:instance_type\n
"},{"location":"use_tf_controller/to_set_variables_for_Terraform_resources/#rename-output-variables","title":"Rename output variables","text":"

See Rename outputs for more details.

"},{"location":"use_tf_controller/to_set_variables_for_Terraform_resources/#rename-input-secrets","title":"Rename input secrets","text":"

See Rename input secrets for more details.

"},{"location":"use_tf_controller/with_AWS_EKS_IRSA/","title":"Use TF-controller with AWS EKS IRSA","text":"

AWS Elastic Kubernetes Service (EKS) offers IAM Roles for Service Accounts (IRSA) as a mechanism by which to provide credentials to Kubernetes pods. This can be used to provide the required AWS credentials to Terraform runners for performing plans and applies.

You can use eksctl to associate an OIDC provider with your EKS cluster, for example:

eksctl utils associate-iam-oidc-provider --cluster CLUSTER_NAME --approve\n

Then follow the instructions here to add a trust policy to the IAM role which grants the necessary permissions for Terraform. Please note that if you have installed the controller following the README, then the namespace:serviceaccountname will be flux-system:tf-runner. You'll obtain a Role ARN to use in the next step.

Finally, annotate the ServiceAccount for the tf-runner with the obtained Role ARN in your cluster:

kubectl annotate -n flux-system serviceaccount tf-runner eks.amazonaws.com/role-arn=ROLE_ARN\n

If deploying the tf-controller via Helm, this can be accomplished as follows:

values:\nrunner:\nserviceAccount:\nannotations:\neks.amazonaws.com/role-arn: ROLE_ARN\n
"},{"location":"use_tf_controller/with_GitOps_dependency_management/","title":"Use TF-controller with GitOps dependency management","text":"

TF-controller supports GitOps dependency management. The GitOps dependency management feature is based on the similar technique implemented in the Kustomization controller of Flux.

This means that you can use TF-controller to provision resources that depend on other resources at the GitOps level. For example, you can use TF-controller to provision an S3 bucket, and then use TF-controller to provision another resource to configure ACL for that bucket.

GitOps dependency management is different from Terraform's HCL dependency management in the way that it is not based on Terraform's mechanism, which is controlled by the Terraform binary. Instead, it is implemented at the controller level, which means that each Terraform module is reconciled and can be managed independently, while still being able to depend on other modules.

"},{"location":"use_tf_controller/with_GitOps_dependency_management/#create-a-terraform-object","title":"Create a Terraform object","text":"

Similar to the same feature in the Kustomization controller, the dependency management feature is enabled by setting the dependsOn field in the Terraform object. The dependsOn field is a list of Terraform objects.

When the dependency is not satisfied, the Terraform object will be in the Unknown state, and it will be retry again every spec.retryInterval. The retry interval is same as the spec.interval by default, and it can be configured separately by setting the spec.retryInterval field.

First, create a Terraform object to provision the S3 bucket, name it aws-s3-bucket. The S3 bucket is provisioned by the Terraform module aws_s3_bucket in the OCI image aws-package. It is configured to use the auto-apply mode, and write outputs to the secret aws-s3-bucket-outputs.

---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: aws-s3-bucket\nnamespace: flux-system\nspec:\npath: aws_s3_bucket\nvalues:\nbucket: my-tf-controller-test-bucket\ntags:\nEnvironment: Dev\nName: My bucket\nsourceRef:\nkind: OCIRepository\nname: aws-package\napprovePlan: auto\ninterval: 2m\ndestroyResourcesOnDeletion: true\nwriteOutputsToSecret:\nname: aws-s3-bucket-outputs\noutputs:\n- arn\n- bucket\nrunnerPodTemplate:\nspec:\nenvFrom:\n- secretRef:\nname: aws-credentials\n

Second, create a Terraform object to configure ACL for the S3 bucket, name it aws-s3-bucket-acl. The ACL is provisioned by the Terraform module aws_s3_bucket_acl, also from the OCI image aws-package-v4.33.0.

In the dependsOn field, specify the Terraform object that provisions the S3 bucket. This means that the ACL will be configured only after the S3 bucket is provisioned, and has its outputs Secret written. We can read the outputs of the S3 bucket from the Secret aws-s3-bucket-outputs, by specifying the spec.readInputsFromSecrets field. The spec.readInputsFromSecrets field is a list of Secret objects. Its name field is the name of the Secret, and its as field is the name of variable that can be used in the spec.values block.

For example, the spec.values.bucket field in the aws-s3-bucket-acl Terraform object is set to ${{ .aws_s3_bucket.bucket }}.

Please note that we use ${{ and }} as the delimiters for the variable name, instead of the Helm default ones, {{ and }}.

---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: aws-s3-bucket-acl\nnamespace: flux-system\nspec:\npath: aws_s3_bucket_acl\nvalues:\nacl: private\nbucket: ${{ .aws_s3_bucket.bucket }}\nsourceRef:\nkind: OCIRepository\nname: aws-package\napprovePlan: auto\ninterval: 3m\ndependsOn:\n- name: aws-s3-bucket\nreadInputsFromSecrets:\n- name: aws-s3-bucket-outputs\nas: aws_s3_bucket\nrunnerPodTemplate:\nspec:\nenvFrom:\n- secretRef:\nname: aws-credentials\n
"},{"location":"use_tf_controller/with_GitOps_dependency_management/#avoid-kustomization-controllers-variable-substitution","title":"Avoid Kustomization controller's variable substitution","text":"

The Kustomization controller will substitute variables in the Terraform object, which will cause conflicts with the variable substitution in the GitOps dependency management feature. To avoid this, we need to add the kustomize.toolkit.fluxcd.io/substitute: disabled annotation to the Terraform object.

---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: aws-s3-bucket-acl\nnamespace: flux-system\nannotations:\nkustomize.toolkit.fluxcd.io/substitute: disabled\nspec:\npath: aws_s3_bucket_acl\nvalues:\nacl: private\nbucket: ${{ .aws_s3_bucket.bucket }}\nsourceRef:\nkind: OCIRepository\nname: aws-package\napprovePlan: auto\ninterval: 3m\ndependsOn:\n- name: aws-s3-bucket\nreadInputsFromSecrets:\n- name: aws-s3-bucket-outputs\nas: aws_s3_bucket\nrunnerPodTemplate:\nspec:\nenvFrom:\n- secretRef:\nname: aws-credentials\n
"},{"location":"use_tf_controller/with_Terraform_Enterprise/","title":"Use TF-controller with Terraform Enterprise","text":""},{"location":"use_tf_controller/with_Terraform_Enterprise/#terraform-enterprise-integration","title":"Terraform Enterprise Integration","text":"

Starting from v0.9.5, Weave TF-controller officially supports integration to Terraform Cloud (TFC) and Terraform Enterprise (TFE). Here are the steps to set up TF-controller for your TFE instance.

"},{"location":"use_tf_controller/with_Terraform_Enterprise/#terraform-login","title":"Terraform Login","text":"

First, you need to obtain an API token from your TFE. You can use terraform login command to do so.

terraform login tfe.dev.example.com\n

Then you can find your API token inside $HOME/.terraform.d/credentials.tfrc.json. Content of the file will look like this:

{\n\"credentials\": {\n\"tfe.dev.example.com\": {\n\"token\": \"mXXXXXXXXX.atlasv1.ixXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"\n}\n}\n}\n
"},{"location":"use_tf_controller/with_Terraform_Enterprise/#prepare-an-tfrc-file","title":"Prepare an TFRC file","text":"

TF-controller accepts an TFRC file in the HCL format. So you have to prepare terraform.tfrc file using contents from above.

credentials \"tfe.dev.example.com\" {\ntoken = \"mXXXXXXXXX.atlasv1.ixXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"\n}\n

"},{"location":"use_tf_controller/with_Terraform_Enterprise/#create-a-secret","title":"Create a Secret","text":"

We will now create a Kubernetes Secret from yourterraform.tfrc file, name it tfe-cli-config and put it inside the flux-system namespace.

kubectl create secret generic \\\ntfe-cli-config \\\n--namespace=flux-system \\\n--from-file=terraform.tfrc=./terraform.tfrc\n
"},{"location":"use_tf_controller/with_Terraform_Enterprise/#terraform-object","title":"Terraform Object","text":"

In your Terraform object, you'll have to 1. disable the backend by setting spec.backendConfig.disable: true, and 2. point spec.cliConfigSecretRef: to the Secret created in the previous step, like this:

---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: tfe-demo\nnamespace: flux-system\nspec:\napprovePlan: auto\ninterval: 2m\npath: ./terraform/tfe-demo\nbackendConfig:\ndisable: true\ncliConfigSecretRef:\nname: tfe-cli-config\nnamespace: flux-system\nvars:\n- name: subject\nvalue: World\nsourceRef:\nkind: GitRepository\nname: flux-system\nnamespace: flux-system\nwriteOutputsToSecret:\nname: tfe-helloworld-output\noutputs:\n- greeting\n
"},{"location":"use_tf_controller/with_Terraform_Enterprise/#terraform-module","title":"Terraform Module","text":"

Don't forget that you need to tell your Terraform model to use your enterprise instance as well. Here's an example,

terraform {\nrequired_version = \">= 1.1.0\"\ncloud {\nhostname = \"tfe.dev.example.com\"\norganization = \"weaveworks\"\nworkspaces {\nname = \"dev\"\n}\n}\n}\nvariable \"subject\" {\ntype = string\ndefault = \"World\"\ndescription = \"Subject to hello\"\n}\noutput \"greeting\" {\nvalue = \"Hello ${var.subject} from Terraform Enterprise\"\n}\n

"},{"location":"use_tf_controller/with_Terraform_Enterprise/#terraform-cloud","title":"Terraform Cloud","text":"

For connecting to Terraform Cloud, please replace your hostname to app.terraform.io.

"},{"location":"use_tf_controller/with_a_custom_backend/","title":"Use TF-controller with a custom backend","text":"

By default, tf-controller will use the Kubernetes backend to store the Terraform state file (tfstate) in cluster.

The tfstate is stored in a secret named: tfstate-${workspace}-${secretSuffix}. The default suffix will be the name of the Terraform resource, however you may override this setting using .spec.backendConfig.secretSuffix. The default workspace name is \"default\", you can also override the workspace by setting .spec.workspace to another value.

If you wish to use a custom backend, you can configure it by defining the .spec.backendConfig.customConfiguration with one of the backends such as GCS or S3, for example:

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\nbackendConfig:\ncustomConfiguration: |\nbackend \"s3\" {\nbucket                      = \"s3-terraform-state1\"\nkey                         = \"dev/terraform.tfstate\"\nregion                      = \"us-east-1\"\nendpoint                    = \"http://localhost:4566\"\nskip_credentials_validation = true\nskip_metadata_api_check     = true\nforce_path_style            = true\ndynamodb_table              = \"terraformlock\"\ndynamodb_endpoint           = \"http://localhost:4566\"\nencrypt                     = true\n}\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\nrunnerPodTemplate:\nspec:\nimage: registry.io/tf-runner:xyz\n
"},{"location":"use_tf_controller/with_an_OCI_Artifact_as_Source/","title":"Use TF-controller with an OCI Artifact as Source","text":"

To use OCI artifacts as the source of Terraform objects, you need Flux 2 version v0.32.0 or higher.

Assuming that you have Terraform files (your root module may contain sub-modules) under ./modules, you can use Flux CLI to create an OCI artifact for your Terraform modules by running the following commands:

flux push artifact oci://ghcr.io/tf-controller/helloworld:$(git rev-parse --short HEAD) \\\n--path=\"./modules\" \\\n--source=\"$(git config --get remote.origin.url)\" \\\n--revision=\"$(git branch --show-current)/$(git rev-parse HEAD)\"\nflux tag artifact oci://ghcr.io/tf-controller/helloworld:$(git rev-parse --short HEAD) \\\n--tag main\n

Then you define a source (OCIRepository), and use it as the sourceRef of your Terraform object.

---\napiVersion: source.toolkit.fluxcd.io/v1beta2\nkind: OCIRepository\nmetadata:\nname: helloworld-oci\nspec:\ninterval: 1m\nurl: oci://ghcr.io/tf-controller/helloworld\nref:\ntag: main\n---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld-tf-oci\nspec:\npath: ./\napprovePlan: auto\ninterval: 1m\nsourceRef:\nkind: OCIRepository\nname: helloworld-oci\nwriteOutputsToSecret:\nname: helloworld-outputs\n
"},{"location":"use_tf_controller/with_drift_detection_disabled/","title":"Use TF-controller with drift detection disabled","text":"

Drift detection is enabled by default. You can set .spec.disableDriftDetection: true to disable it.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: helloworld\nnamespace: flux-system\nspec:\napprovePlan: auto\ndisableDriftDetection: true\ninterval: 1m\npath: ./\nsourceRef:\nkind: GitRepository\nname: helloworld\nnamespace: flux-system\n
"},{"location":"use_tf_controller/with_plan_only_mode/","title":"Use TF-controller with a plan-only mode","text":"

This plan-only mode is designed to be used in conjunction with the Branch Planner. But you can also use it in a circumstance where you want to run terraform plan only.

If planOnly is set to true, the controller will skip the apply part and runs only terraform plan and saves the output.

apiVersion: infra.contrib.fluxcd.io/v1\nkind: Terraform\nmetadata:\n  name: helloworld\n  namespace: flux-system\nspec:\n  interval: 1m\n  planOnly: true\n  path: ./\n  sourceRef:\n    kind: GitRepository\n    name: helloworld\n    namespace: flux-system\n
"},{"location":"use_tf_controller/with_primitive_modules/","title":"Use TF-controller with primitive modules","text":"

This document describes how to use the Weave TF-controller with a primitive module. It requires TF-controller v0.13+ to run the example.

"},{"location":"use_tf_controller/with_primitive_modules/#what-is-a-primitive-module","title":"What is a primitive module?","text":"

It's a Terraform module that contains only a single resource.

"},{"location":"use_tf_controller/with_primitive_modules/#hello-world-primitive-module","title":"Hello World Primitive Module","text":"

Here is an example of how a primitive module can be defined in YAML. Assume that we have a ready-to-use OCI image with a primitive module for the imaginary resource aws_hello_world, and the image is tagged as ghcr.io/tf-controller/hello-primitive-modules/v4.32.0:v1.

We'll use the following Terraform object definition to provision the resource.

First, we need to create a Terraform object with the spec.sourceRef.kind field set to OCIRepository and the spec.sourceRef.name field set to the name of the OCIRepository object.

Second, we need to set the spec.path field to the name of the resource, in this case aws_hello_world.

Third, we need to set the spec.values field to the values of the resource. This is a YAML object that will be converted to an HCL variable, and passed to the Terraform module.

Finally, we need to set the spec.approvePlan field to auto to automatically approve the plan.

---\napiVersion: source.toolkit.fluxcd.io/v1beta2\nkind: OCIRepository\nmetadata:\nname: hello-package-v4.32.0\nnamespace: flux-system\nspec:\ninterval: 30s\nurl: oci://ghcr.io/tf-controller/hello-primitive-modules/v4.32.0\nref:\ntag: v1\n---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: hello-world\nnamespace: flux-system\nspec:\npath: aws_hello_world\nvalues:\ngreeting: Hi\nsubject: my world\nsourceRef:\nkind: OCIRepository\nname: hello-package-v4.32.0\ninterval: 1h0m\napprovePlan: auto\n
"},{"location":"use_tf_controller/with_tf_runner_logging/","title":"Use TF-controller with Terraform Runners enabled via Env Variables","text":"

A Terraform Runner uses two environment variables, DISABLE_TF_LOGS and ENABLE_SENSITIVE_TF_LOGS, to control the logging behavior of the Terraform execution.

To use these environment variables, they need to be set on each Terraform Runner pod where the Terraform code is being executed. This can typically be done by adding them to the pod's environment variables in the Terraform Runner deployment configuration.

"},{"location":"use_tf_controller/with_tf_runner_logging/#the-default-logging-behavior","title":"The Default Logging Behavior","text":"

For more information on configuring the Terraform Runner and its environment variables, please consult the documentation on customizing runners within the Weave TF-controller.

"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/","title":"with the ready to use AWS package","text":""},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#use-tf-controller-with-the-ready-to-use-aws-package","title":"Use TF-controller with the ready-to-use AWS package","text":"

This document describes how to use the Weave TF-controller with the ready-to-use AWS package. It requires TF-controller v0.13+ to run the example.

"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#what-is-a-package","title":"What is a package?","text":"

A package is a collection of primitive Terraform modules that are bundled into an OCI image. You can think of a TF-controller's package as a thin wrapper around a Terraform module provider, and a TF-controller primitive module as a thin wrapper around a Terraform resource or a root module.

We will provide a set of ready-to-use packages for the most popular cloud providers. Currently, we ship the package for AWS only.

"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#aws-package","title":"AWS Package","text":"

To provide the out-of-the-box experience, the AWS Package is installed by default when you installed the TF-controller. Unlike other IaC implementation, our package model is designed to be very lightweight as a package is just a set of TF files in the form of OCI. Packages would not put any burden to your cluster. However, you can opt this package out by setting awsPackage.install: false in your Helm chart values.

If you run flux get sources oci you should see the AWS package installed in your cluster listed as aws-package.

flux get sources oci\nNAME          REVISION                    SUSPENDED   READY   MESSAGE                                                                                                         aws-package   v4.38.0-v1alpha11/6033f3b   False       True    stored artifact for digest 'v4.38.0-v1alpha11/6033f3b'\n
"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#a-step-by-step-tutorial","title":"A step-by-step tutorial","text":"

This section describes how to use the AWS package to provision an S3 bucket with ACL using the TF-controller.

"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#create-a-kind-local-cluster","title":"Create a KinD local cluster","text":"

If you don't have a Kubernetes cluster, you can create a KinD cluster with the following command:

kind create cluster\n
"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#install-flux","title":"Install Flux","text":"

After you have a Kubernetes cluster, you can install Flux with the following command:

flux install\n
"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#install-tf-controller","title":"Install TF-controller","text":"

Then, you can install the TF-controller with the following command:

kubectl apply -f https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/release.yaml\n
"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#setup-aws-credentials","title":"Setup AWS credentials","text":"

To provision AWS resources, you need to provide the AWS credentials to your Terraform objects. You can do this by creating a secret with the AWS credentials and reference it in each of your Terraform objects.

```yaml\napiVersion: v1\nkind: Secret\nmetadata:\n  name: aws-credentials\n  namespace: flux-system\ntype: Opaque\nstringData:\n  AWS_ACCESS_KEY_ID: Axxxxxxxxxxxxxxxxxxx\n  AWS_SECRET_ACCESS_KEY: qxxxxxxxxxxxxxxxxxxxxxxxxx\n  AWS_REGION: us-east-1 # the region you want\n

To apply the secret, run the following command:

kubectl apply -f aws-credentials.yaml\n
"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#setup-aws-bucket-and-acl","title":"Setup AWS Bucket and ACL","text":"

Now, you can create two Terraform objects, one for an S3 bucket, another one for ACL. Please note that we are using GitOps dependencies to make sure the ACL is created after the bucket is created. You can read more about the GitOps dependencies in the GitOps dependencies document.

```yaml\n---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\n  name: aws-s3-bucket\n  namespace: flux-system\n  labels:\n    tf.weave.works/composite: s3-bucket\nspec:\n  path: aws_s3_bucket\n  values:\n    bucket: my-tf-controller-test-bucket\n    tags:\n      Environment: Dev\n      Name: My bucket\n  sourceRef:\n    kind: OCIRepository\n    name: aws-package\n  approvePlan: auto\n  retryInterval: 10s\n  interval: 2m\n  destroyResourcesOnDeletion: true\nwriteOutputsToSecret:\n    name: aws-s3-bucket-outputs\n    outputs:\n    - arn\n    - bucket\n  runnerPodTemplate:\n    spec:\n      envFrom:\n      - secretRef:\n          name: aws-credentials\n---\napiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\n  name: example-bucket-acl\n  namespace: flux-system\n  labels:\n    tf.weave.works/composite: s3-bucket\nspec:\n  path: aws_s3_bucket_acl\n  values:\n    acl: private\n    bucket: ${{ .aws_s3_bucket.bucket }}\nsourceRef:\n    kind: OCIRepository\n    name: aws-package\n  approvePlan: auto\n  retryInterval: 10s\n  interval: 3m\n  dependsOn:\n  - name: aws-s3-bucket\n  readInputsFromSecrets:\n  - name: aws-s3-bucket-outputs\n    as: aws_s3_bucket\n  destroyResourcesOnDeletion: true\nrunnerPodTemplate:\n    spec:\n      envFrom:\n      - secretRef:\n          name: aws-credentials\n
"},{"location":"use_tf_controller/with_the_ready_to_use_AWS_package/#rename-input-secrets","title":"Rename input secrets","text":"

The spec.readInputsFromSecrets field allows you to reference the Terraform outputs from other Terraform objects. In the context of this field, renaming makes it easier to reference the secrets in the spec.values field.

To rename a secret, you need to use the as key in the spec.readInputsFromSecrets field. The name key corresponds to the original name of the secret, while the as key represents the new name that you want to use to reference the secret.

In the example below, we can reference the bucket value from our aws_s3_bucket secret using ${{ .aws_s3_bucket.bucket }} instead of using the original secret name, which is aws-s3-bucket-outputs.

apiVersion: infra.contrib.fluxcd.io/v1alpha2\nkind: Terraform\nmetadata:\nname: example-bucket-acl\nnamespace: flux-system\nspec:\n# ...\nreadInputsFromSecrets:\n- name: aws-s3-bucket-outputs\nas: aws_s3_bucket\nvalues:\nacl: private\nbucket: ${{ .aws_s3_bucket.bucket }}\n# ...\n
"}]} \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index a61d4e8f..50af5b69 100644 Binary files a/sitemap.xml.gz and b/sitemap.xml.gz differ