A Terraform “module” refers to a self-contained package of Terraform configurations that are managed as a group.
For more information around modules refer to the Terraform documentation.
How do you use this module
Prerequisites
To make use of this module, you need a Google Cloud project.
Instructions on how to setup such a project can be found in the Google Cloud Installation and Setup guide.
You need your Google Cloud project id as an input variable for using this module.
You also need to install the Cloud SDK, in particular gcloud.
You find instructions on how to install and authenticate in the Google Cloud Installation and Setup guide as well.
You can then apply this Terraform configuration via:
terraform init
terraform apply
This creates a cluster within the specified Google Cloud project with all possible configuration options defaulted.
Note: This example is for getting up and running quickly.
It is not intended for a production cluster.
Refer to Production cluster considerations for things to consider when creating a production cluster.
On completion of terraform apply a jx_requirements output is available which can be used as input to jx boot.
Refer to Running jx boot for more information.
In the default configuration, no custom domain is used.
DNS resolution occurs via nip.io.
For more information on how to configure and use a custom domain, refer to Using a custom domain.
If you just want to experiment with Jenkins X, you can set force_destroy to true.
This allows you to remove all generated resources when running terraform destroy, including any generated buckets including their content.
If you want to remove a cluster with the terraform destroy command and the cluster is protected by the deletion_protection=true attribute, you can override the attribute by setting the delete_protect variable to false. It is recommended to override this value and the time of cluster deletion and you should successfully apply the attribute value change before attempting the terraform destroy command.
The following two paragraphs provide the full list of configuration and output variables of this Terraform module.
The location (region or zone) in which the cluster master will be created. If you specify a zone (such as us-central1-a), the cluster will be a zonal cluster with a single cluster master. If you specify a region (such as us-west1), the cluster will be a regional cluster with multiple masters spread across zones in the region
The IP range in CIDR notation to use for the hosted master network. This range must not overlap with any other ranges in use within the cluster’s network, and it must be a /28 subnet
Artifact Registry in setup with multiple Jenkins X clusters
In a multi cluster setup, you should leave the value of artifact_enable as trueonly in a
development cluster and set artifact_enable = false for other clusters. A development cluster is
one where application build pipelines are executed. If you have multiple development clusters you
can set artifact_repository_id to different values for them. Alternatively you can have
artifact_enable = true in one and manually copy the values of cluster.registry and
cluster.dockerRegistryOrg from jx-requirements.yml from that cluster repository to the other
cdevelopment cluster repositories.
If you leave artifact_enable as true for multiple clusters and don’t override
artifact_repository_id terraform will fail since it can’t create an already existing repository.
Migration from Container to Artifact Registry
Google has deprecated gcr.io and now recommends the use of Artifact Registry. The default of this module is now to create and use a repository in Artifact Registry for container images.
Google GKE clusters automatically have permissions to download from the Artifact Registry. For multi cluster setups across different projects, additional permission configurations may be necessary.
Configuration Note
The jx-requirements.yml will be automatically updated by the Jenkins X boot job when triggered by a push to the main branch of the cluster repository.
Migration Options
Here are two strategies for transitioning container images from gcr.io to the Artifact Registry:
Don’t Migrate Existing Images
Continue developing applications as usual. New images, upon their release, will be pushed to the Artifact Registry.
Important: Ensure that all builds are triggered and applications are promoted before Google completely shuts down the Container Registry. This step is critical to avoid disruptions in service.
To identify which images from you container registry are currently used in your cluster, you can use the following command line (replace project_id with your actual GCP project id):
If you have a large number of applications running that are unlikely to be released in the coming
year, migration of images to artifact registry while retaining the image names (in the domain
gcr.io) could be considered. This means that existing helm charts will continue to work.
This process is not supported by this terraform module, instead you need to follow the steps outlined in the guide
Set up repositories with gcr.io domain support.
These steps include create the a repository in Artifact Registry, migrate images to it from
container registry and enable redirection of gcr.io traffic.
If you keep the default settings for this module it will create another artifact repository that
will be used for new images. If you want to use gcr.io artifact repository for new images you
should set artifact_enable = false.
Using a custom domain
If you want to use a custom domain with your Jenkins X installation, you need to provide values for the variablesapex_domain and tls_email.
apex_domain is the fully qualified domain name you want to use and tls_email is the email address you want to use for issuing Let’s Encrypt TLS certificates.
Before you apply the Terraform configuration, you also need to create a Cloud DNS managed zone, with the DNS name in the managed zone matching your custom domain name, for example in the case of example.jenkins-x.rocks as domain:
When creating the managed zone, a set of DNS servers get created which you need to specify in the DNS settings of your DNS registrar.
It is essential that before you run jx boot, your DNS servers settings are propagated, and your domain resolves.
You can use DNS checker to check whether your domain settings have propagated.
When a custom domain is provided, Jenkins X uses ExternalDNS together with cert-manager to create A record entries in your managed zone for the various exposed applications.
If apex_domain id not set, your cluster will use nip.io in order to create publicly resolvable URLs of the form http://<app-name>-<environment-name>.<cluster-ip>.nip.io.
Production cluster considerations
The configuration as seen in Cluster provisioning is not suited for creating and maintaining a production Jenkins X cluster.
The following is a list of considerations for a production usecase.
Specify the version attribute of the module, for example:
module "jx" {
source = "jenkins-x/jx/google"
version = "1.2.4"
# insert your configuration
}
output "jx_requirements" {
value = module.jx.jx_requirements
}
Specifying the version ensures that you are using a fixed version and that version upgrades cannot occur unintented.
Keep the Terraform configuration under version control, by creating a dedicated repository for your cluster configuration or by adding it to an already existing infrastructure repository.
Setup a Terraform backend to securely store and share the state of your cluster. For more information refer to Configuring a Terraform backend.
Configuring a Terraform backend
A “backend“ in Terraform determines how state is loaded and how an operation such as apply is executed.
By default, Terraform uses the local backend which keeps the state of the created resources on the local file system.
This is problematic since sensitive information will be stored on disk and it is not possible to share state across a team.
When working with Google Cloud a good choice for your Terraform backend is the gcs backend which stores the Terraform state in a Google Cloud Storage bucket.
The examples directory of this repository contains configuration examples for using the gcs backed with and without optionally configured customer supplied encryption key.
To use the gcs backend you will need to create the bucket upfront.
You can use gsutil to create the bucket:
gsutil mb gs://<my-bucket-name>/
It is also recommended to enable versioning on the bucket as an additional safety net in case of state corruption.
gsutil versioning set on gs://<my-bucket-name>
You can verify whether a bucket has versioning enabled via:
gsutil versioning get gs://<my-bucket-name>
FAQ
How do I get the latest version of the terraform-google-jx module
terraform init -upgrade
How to I specify a specific google provider version
The recommended way to authenticate to the Google Cloud API is by using a service account.
This allows for authentication regardless of where your code runs.
This Terraform module expects authentication via a service account key.
You can either specify the path to this key directly using the GOOGLE_APPLICATION_CREDENTIALS environment variable or you can run gcloud auth application-default login.
In the latter case gcloud obtains user access credentials via a web flow and puts them in the well-known location for Application Default Credentials (ADC), usually ~/.config/gcloud/application_default_credentials.json.
Development
Releasing
At the moment there is no release pipeline defined in jenkins-x.yml.
A Terraform release does not require building an artifact, only a tag needs to be created and pushed.
To make this task easier and there is a helper script release.sh which simplifies this process and creates the changelog as well:
./scripts/release.sh
This can be executed on demand whenever a release is required.
For the script to work the envrionment variable $GH_TOKEN must be exported and reference a valid GitHub API token.
Jenkins X GKE Module
NOTE: Automated CI tests are performed with 0.13 only.
This repo contains a Terraform module for provisioning a Kubernetes cluster for Jenkins X on Google Cloud.
What is a Terraform module
A Terraform “module” refers to a self-contained package of Terraform configurations that are managed as a group. For more information around modules refer to the Terraform documentation.
How do you use this module
Prerequisites
To make use of this module, you need a Google Cloud project. Instructions on how to setup such a project can be found in the Google Cloud Installation and Setup guide. You need your Google Cloud project id as an input variable for using this module.
You also need to install the Cloud SDK, in particular
gcloud. You find instructions on how to install and authenticate in the Google Cloud Installation and Setup guide as well.Once you have
gcloudinstalled, you need to create Application Default Credentials by running:Alternatively, you can export the environment variable GOOGLE_APPLICATION_CREDENTIALS referencing the path to a Google Cloud service account key file.
Last but not least, ensure you have the following binaries installed:
gcloudkubectl~> 1.14.0kubectlcomes bundled with the Cloud SDKterraform~> 0.12.0Cluster provisioning
A default Jenkins X ready cluster can be provisioned by creating a file main.tf in an empty directory with the following content:
You can then apply this Terraform configuration via:
This creates a cluster within the specified Google Cloud project with all possible configuration options defaulted.
On completion of
terraform applya jx_requirements output is available which can be used as input tojx boot. Refer to Runningjx bootfor more information.In the default configuration, no custom domain is used. DNS resolution occurs via nip.io. For more information on how to configure and use a custom domain, refer to Using a custom domain.
If you just want to experiment with Jenkins X, you can set
force_destroytotrue. This allows you to remove all generated resources when runningterraform destroy, including any generated buckets including their content.If you want to remove a cluster with the
terraform destroycommand and the cluster is protected by thedeletion_protection=trueattribute, you can override the attribute by setting thedelete_protectvariable tofalse. It is recommended to override this value and the time of cluster deletion and you should successfully apply the attribute value change before attempting theterraform destroycommand.The following two paragraphs provide the full list of configuration and output variables of this Terraform module.
Inputs
string""string""booltruestring"jenkins-x Docker Repository"booltruestring"us-central1"string"oci"string"ANY"number5number3string"US"string"us-central1-a"string""string"default"string""booltruedeletion_protectionattribute to prevent cluster deletionbooltruelist(string)[]boolfalsebooltrueboolfalseboolfalseboolfalsestringstring""boolfalsenumber3number3string""string""string"jx"booltruestring""string""string"0.2.1"string""booltruebooltruelist(object({ cidr_block = string, display_name = string }))[]string"10.0.0.0/28"number64string"100"string"pd-standard"string"n1-standard-2"boolfalseboolfalsestring""string""string"REGULAR"map(any){}string""string""string""string"velero"string"0 * * * *"string"720h0m0s"string"master"string"https://github.com/jenkins-x/jenkins-x-versions.git"string"lighthouse"string""Outputs
Artifact Registry in setup with multiple Jenkins X clusters
In a multi cluster setup, you should leave the value of
artifact_enableastrueonly in a development cluster and setartifact_enable = falsefor other clusters. A development cluster is one where application build pipelines are executed. If you have multiple development clusters you can setartifact_repository_idto different values for them. Alternatively you can haveartifact_enable = truein one and manually copy the values ofcluster.registryandcluster.dockerRegistryOrgfromjx-requirements.ymlfrom that cluster repository to the other cdevelopment cluster repositories.If you leave
artifact_enableastruefor multiple clusters and don’t overrideartifact_repository_idterraform will fail since it can’t create an already existing repository.Migration from Container to Artifact Registry
Google has deprecated
gcr.ioand now recommends the use of Artifact Registry. The default of this module is now to create and use a repository in Artifact Registry for container images.Google GKE clusters automatically have permissions to download from the Artifact Registry. For multi cluster setups across different projects, additional permission configurations may be necessary.
Configuration Note
The
jx-requirements.ymlwill be automatically updated by the Jenkins X boot job when triggered by a push to the main branch of the cluster repository.Migration Options
Here are two strategies for transitioning container images from
gcr.ioto the Artifact Registry:Don’t Migrate Existing Images
project_idwith your actual GCP project id):Migrate Existing Images
If you have a large number of applications running that are unlikely to be released in the coming year, migration of images to artifact registry while retaining the image names (in the domain
gcr.io) could be considered. This means that existing helm charts will continue to work.This process is not supported by this terraform module, instead you need to follow the steps outlined in the guide Set up repositories with gcr.io domain support. These steps include create the a repository in Artifact Registry, migrate images to it from container registry and enable redirection of gcr.io traffic.
If you keep the default settings for this module it will create another artifact repository that will be used for new images. If you want to use
gcr.ioartifact repository for new images you should setartifact_enable = false.Using a custom domain
If you want to use a custom domain with your Jenkins X installation, you need to provide values for the variables apex_domain and tls_email. apex_domain is the fully qualified domain name you want to use and tls_email is the email address you want to use for issuing Let’s Encrypt TLS certificates.
Before you apply the Terraform configuration, you also need to create a Cloud DNS managed zone, with the DNS name in the managed zone matching your custom domain name, for example in the case of example.jenkins-x.rocks as domain:
When creating the managed zone, a set of DNS servers get created which you need to specify in the DNS settings of your DNS registrar.
It is essential that before you run
jx boot, your DNS servers settings are propagated, and your domain resolves. You can use DNS checker to check whether your domain settings have propagated.When a custom domain is provided, Jenkins X uses ExternalDNS together with cert-manager to create A record entries in your managed zone for the various exposed applications.
If apex_domain id not set, your cluster will use nip.io in order to create publicly resolvable URLs of the form http://<app-name>-<environment-name>.<cluster-ip>.nip.io.
Production cluster considerations
The configuration as seen in Cluster provisioning is not suited for creating and maintaining a production Jenkins X cluster. The following is a list of considerations for a production usecase.
Specify the version attribute of the module, for example:
Specifying the version ensures that you are using a fixed version and that version upgrades cannot occur unintented.
Keep the Terraform configuration under version control, by creating a dedicated repository for your cluster configuration or by adding it to an already existing infrastructure repository.
Setup a Terraform backend to securely store and share the state of your cluster. For more information refer to Configuring a Terraform backend.
Configuring a Terraform backend
A “backend“ in Terraform determines how state is loaded and how an operation such as apply is executed. By default, Terraform uses the local backend which keeps the state of the created resources on the local file system. This is problematic since sensitive information will be stored on disk and it is not possible to share state across a team. When working with Google Cloud a good choice for your Terraform backend is the gcs backend which stores the Terraform state in a Google Cloud Storage bucket. The examples directory of this repository contains configuration examples for using the gcs backed with and without optionally configured customer supplied encryption key.
To use the gcs backend you will need to create the bucket upfront. You can use
gsutilto create the bucket:It is also recommended to enable versioning on the bucket as an additional safety net in case of state corruption.
You can verify whether a bucket has versioning enabled via:
FAQ
How do I get the latest version of the terraform-google-jx module
How to I specify a specific google provider version
Why do I need Application Default Credentials
The recommended way to authenticate to the Google Cloud API is by using a service account. This allows for authentication regardless of where your code runs. This Terraform module expects authentication via a service account key. You can either specify the path to this key directly using the GOOGLE_APPLICATION_CREDENTIALS environment variable or you can run
gcloud auth application-default login. In the latter casegcloudobtains user access credentials via a web flow and puts them in the well-known location for Application Default Credentials (ADC), usually ~/.config/gcloud/application_default_credentials.json.Development
Releasing
At the moment there is no release pipeline defined in jenkins-x.yml. A Terraform release does not require building an artifact, only a tag needs to be created and pushed. To make this task easier and there is a helper script
release.shwhich simplifies this process and creates the changelog as well:This can be executed on demand whenever a release is required. For the script to work the envrionment variable $GH_TOKEN must be exported and reference a valid GitHub API token.
How do I contribute
Contributions are very welcome! Check out the Contribution Guidelines for instructions.