Provisioning a Resource
Terranetes offers two distinct interfaces for provisioning cloud resources: the Configuration Custom Resource Definition (CRD) and the newer CloudResource model. The primary distinction between these interfaces lies in their approach to simplicity and control.
The Configuration CRD provides a direct, one-to-one mapping to the Terraform module, offering a high degree of customization and flexibility. In contrast, the CloudResource interface presents a curated subset of options, enabling platform teams to establish defaults, integrate best practices, and enforce security or organizational policies. This design choice has the added advantage of reducing the cognitive load associated with navigating the extensive range of options available in a Terraform module.
Example CloudResource
This section outlines the steps to provision a CloudResource.
Step 1: Discover Available Resources
To identify the resources available for self-service provisioning, execute the following command to query the cluster for available plans:
$ kubectl get plans
NAME LATEST AGE
database v0.0.1 3s
Step 2: Inspect the Latest Revision of the Service
To view the details of the latest revision of the service, use the following command:
kubectl get revision $(kubectl get plan database -o json | jq .status.latest.name -r) -o yaml
This command will display the options available within the plan.
Step 3: Provision a CloudResource from a Revision
To create a CloudResource based on a revision, execute the following command:
tnctl create cloudresource database
This command initiates the provisioning process for a CloudResource named "database" based on the latest revision available.
Example Configuration resource
For users employing the Configuration model, the following example is provided:
apiVersion: terraform.appvia.io/v1alpha1
kind: Configuration
metadata:
name: bucket
spec:
# SSH example: git::ssh://git@example.com/foo/bar
module: https://github.com/terraform-aws-modules/terraform-aws-s3-bucket.git?ref=v3.1.0
providerRef:
name: default
writeConnectionSecretToRef:
name: test
# An optional reference to a secret containing credentials to retrieve
# the git repository
auth:
name: <SECRET_NAME>
# Terraform variables used to populate the module
variables:
# -- The name of the bucket. If omitted, Terraform will assign a random, unique name
bucket: example-test-1234
# -- The canned ACL to apply
acl: private
# -- Map containing versioning configuration
versioning:
enabled: true
# --Whether Amazon S3 should block public ACLs for this bucket
block_public_acls: true
# -- Whether Amazon S3 should block public bucket policies for this bucket
block_public_policy: true
# -- Whether Amazon S3 should ignore public ACLs for this bucket
ignore_public_acls: true
# -- Whether Amazon S3 should restrict public bucket policies for this bucket
restrict_public_buckets: true
# -- Map containing server-side encryption configuration
server_side_encryption_configuration:
rule:
apply_server_side_encryption_by_default:
sse_algorithm: "aws:kms"
bucket_key_enabled: true
For releases <= v0.2.5
, the source syntax specified in spec.module
does not fully adhere to the recommended Github format for referencing Github repositories. To ensure compatibility, it is essential to use the following formats for Github references: https://github.com/appvia/terraform-aws-rds?ref=TAG
or git::ssh://git@github.com/appvia/terraform-aws-rds.git
.
It is crucial to follow the syntax guidelines outlined in the Generic Git Repository documentation to ensure successful module sourcing.
Configuration Resource Structure
The configuration resource is structured into distinct sections, each serving a specific purpose in the provisioning process.
Module reference
The module reference specifies the source location of the Terraform module to be executed.
This reference adheres to the same format as Terraform itself, leveraging the same library. For comprehensive information, refer to hashicorp/go-getter.
For convenience, the following formats are applicable:
- SSH-based references follow the pattern:
git::ssh://git@example.com/foo/bar
- HTTPS-based references conform to:
https://github.com/terraform-aws-modules/terraform-aws-s3-bucket.git?ref=v3.1.0
Additionally, it is possible to selectively extract specific folders or files from the downloaded module by incorporating the double slash notation: [URL]//dir/file
.
Provider reference
The provider reference is a crucial element that establishes the connection between a configuration and the credentials required to communicate with the cloud. Depending on the Kubernetes RBAC you currently possess, you can retrieve a list of the current providers via kubectl
:
$ kubectl get providers -n [NAMESPACE]
Once you have the provider name
, you can use the reference in the configuration:
spec:
providerRef:
name: <NAME>
Terraform variables
The spec.variables
section is a map that enables the definition of all variables that can be utilized by the module. These variables are transformed into HCL format and injected into the workflow through the -var-file
option during both the plan
and apply
phases.
When dealing with sensitive variables, such as passwords, it is advisable to leverage the spec.valueFrom
field. This field comprises a collection of references to Kubernetes secrets that store the actual values of these sensitive variables.
The spec.valueFrom
field is available from version >= v0.1.6
An example for an RDS module can be
spec:
valueFrom:
- secret: db_password
key: database_password
optional: false
Connection secret reference
The spec.writeConnectionSecretToRef
field specifies the name of a secret within the namespace where Terraform outputs are written. These outputs are automatically converted to environment variable format, ensuring they are uppercase and readily consumable by workloads utilizing env and envFrom.
By default, when a secret is defined, all Terraform outputs are written in environment variable form. To selectively include specific keys from the Terraform output, you can incorporate the spec.writeConnectionSecretToRef.keys
field, as demonstrated below.
spec:
writeConnectionSecretToRef:
name: [NAME]
keys:
- name_of_key
- name_of_key
Secrets Remapping
The Terraform controller uses the resource outputs as the keys in the connection secret. For example, if a resource has a database_endpoint
output, the secret will have a key named DATABASE_ENDPOINT
. However, you might want to rename one or more outputs for convenience. For instance, you can change the database_endpoint
to mysql_host
as shown below:
apiVersion: terraform.appvia.io/v1alpha1
kind: Configuration|CloudResource
metadata:
name: bucket
spec:
providerRef:
name: aws
writeConnectionSecretToRef:
name: test
keys:
- database_endpoint:mysql_host # is renamed to MYSQL_HOST
- database_port # is unchanged as DATABASE_PORT
Viewing the changes
During the lifecycle of a Configuration, including its plan, apply, and destroy phases, a job is spawned within the namespace to facilitate the tracking of the change's execution. These jobs adhere to a standardized naming convention, [RESOURCE]-[GENERATION]-[plan|apply|destroy]
, allowing for easy identification. To monitor the progress of a change, you can examine the logs of the corresponding pod using the command kubectl logs [POD]
.
Alternatively, the tnctl command-line interface offers a convenient method for accessing logs, as demonstrated below:
$ tnctl logs -n NAMESPACE NAME
Approving a plan
By default, all Configurations and CloudResources require manual approval before execution, unless spec.enableAutoApproval
is explicitly set to true
. To facilitate this approval process, an annotation can be applied directly to the Configuration or CloudResource.
To manually approve the Configuration named bucket
, execute one of the following commands:
$ kubectl -n apps annotate configuration bucket "terraform.appvia.io/apply"=true --overwrite
Alternatively, for CloudResources:
$ kubectl -n apps annotate cloudresource bucket "terraform.appvia.io/apply"=true --overwrite
For a more streamlined approach, the tnctl command-line interface provides a dedicated approval mechanism. To approve a Configuration or CloudResource using tnctl, use the following command:
$ tnctl approve cloudresource|configuration -n NAMESPACE NAME
This annotation or tnctl command effectively signals approval for the specified resource, allowing the Terraform controller to proceed with the execution of the plan.
Deleting the resource
Deleting a resource is a standard operation in Kubernetes, and can be done using the command kubectl delete configuration [NAME]
. An additional feature is the ability to orphan the cloud resources, meaning that the Kubernetes representation is deleted, but the cloud resources themselves are not.
For example, if you need to migrate a configuration to another cluster, follow these steps:
- Annotate the Configuration with
kubectl annotate configuration [NAME] "terraform.appvia.io/orphan"=true
- Delete the Configuration resource as usual. The resource will be removed, but the cloud resources will remain.