Skip to content

Commit c8b015b

Browse files
Merge pull request jenkins-x#235 from sergiogiuffrida/gcp-artifact
Gcp artifact
2 parents 5d60c60 + 18c7b38 commit c8b015b

File tree

10 files changed

+180
-46
lines changed

10 files changed

+180
-46
lines changed

CONTRIBUTING.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,15 @@ The CI build will fail on lint issues. To format and run locally execute `make
3232

3333
Helpful tip if using an IDE like intelij you can enable file watchers and auto format terraform files.
3434

35-
## Generating terraform docs for the readme
35+
## Generating terraform docs and table of content in README.md
3636

37-
### Prerequisite
37+
### Prerequisites
3838

3939
- terraform-docs - for OSX `brew install terraform-docs` (v0.12+)
40+
- markdown-toc - `npm install --save markdown-toc`
4041

41-
If you add or remove any terraform input or outputs you will need to regenerate the docs. Note that running the following will automatically update the README.md sections
42+
If you add or remove any terraform input or outputs or change headings in README.md you will need to regenerate the docs. Note that running the following will automatically update the README.md sections
4243

4344
```
44-
make markdown-table
45+
make README.md
4546
```

Makefile

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fmt: ## Reformats Terraform files accoring to standard
4343
terraform fmt -diff -recursive
4444

4545
.PHONY: fmt-check
46-
fmt: ## Checks if Terraform files are formatted accoring to standard
46+
fmt-check: ## Checks if Terraform files are formatted accoring to standard
4747
terraform fmt -check -diff -recursive
4848

4949
.PHONY: test
@@ -60,6 +60,11 @@ clean: ## Deletes temporary files
6060
@rm -f jx-requirements.yml
6161

6262
.PHONY: markdown-table
63-
markdown-table: ## Creates markdown tables for in- and output of this module
63+
markdown-table: ## Creates markdown tables for in- and output of this module using https://terraform-docs.io/
6464
terraform-docs .
65-
65+
66+
.PHONY: markdown-toc
67+
markdown-toc: ## Creates table of content using https://github.com/jonschlinkert/markdown-toc
68+
markdown-toc -i README.md --bullets "-"
69+
70+
README.md: markdown-table markdown-toc

README.md

Lines changed: 67 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,32 @@ compatibility issues to be aware of are around provider requirements. For more
99

1010
This repo contains a [Terraform](https://www.terraform.io/) module for provisioning a Kubernetes cluster for [Jenkins X](https://jenkins-x.io/) on [Google Cloud](https://cloud.google.com/).
1111

12-
<!-- TOC -->
13-
14-
- [Jenkins X GKE Module](#jenkins-x-gke-module)
15-
- [What is a Terraform module](#what-is-a-terraform-module)
16-
- [How do you use this module](#how-do-you-use-this-module)
17-
- [Prerequisites](#prerequisites)
18-
- [Cluster provisioning](#cluster-provisioning)
19-
- [Inputs](#inputs)
20-
- [Outputs](#outputs)
21-
- [Running `jx boot`](#running-jx-boot)
22-
- [Using a custom domain](#using-a-custom-domain)
23-
- [Production cluster considerations](#production-cluster-considerations)
24-
- [FAQ](#faq)
25-
- [How do I get the latest version of the terraform-google-jx module](#how-do-i-get-the-latest-version-of-the-terraform-google-jx-module)
26-
- [How to I specify a specific google provider version](#how-to-i-specify-a-specific-google-provider-version)
27-
- [Why do I need Application Default Credentials](#why-do-i-need-application-default-credentials)
28-
- [Development](#development)
29-
- [Releasing](#releasing)
30-
- [How do I contribute](#how-do-i-contribute)
31-
32-
<!-- /TOC -->
12+
<!-- toc -->
13+
14+
- [What is a Terraform module](#what-is-a-terraform-module)
15+
- [How do you use this module](#how-do-you-use-this-module)
16+
- [Prerequisites](#prerequisites)
17+
- [Cluster provisioning](#cluster-provisioning)
18+
- [Inputs](#inputs)
19+
- [Outputs](#outputs)
20+
- [Artifact Registry in setup with multiple Jenkins X clusters](#artifact-registry-in-setup-with-multiple-jenkins-x-clusters)
21+
- [Migration from Container to Artifact Registry](#migration-from-container-to-artifact-registry)
22+
- [Configuration Note](#configuration-note)
23+
- [Migration Options](#migration-options)
24+
- [Don't Migrate Existing Images](#dont-migrate-existing-images)
25+
- [Migrate Existing Images](#migrate-existing-images)
26+
- [Using a custom domain](#using-a-custom-domain)
27+
- [Production cluster considerations](#production-cluster-considerations)
28+
- [Configuring a Terraform backend](#configuring-a-terraform-backend)
29+
- [FAQ](#faq)
30+
- [How do I get the latest version of the terraform-google-jx module](#how-do-i-get-the-latest-version-of-the-terraform-google-jx-module)
31+
- [How to I specify a specific google provider version](#how-to-i-specify-a-specific-google-provider-version)
32+
- [Why do I need Application Default Credentials](#why-do-i-need-application-default-credentials)
33+
- [Development](#development)
34+
- [Releasing](#releasing)
35+
- [How do I contribute](#how-do-i-contribute)
36+
37+
<!-- tocstop -->
3338

3439
## What is a Terraform module
3540

@@ -114,6 +119,10 @@ The following two paragraphs provide the full list of configuration and output v
114119
| <a name="input_apex_domain"></a> [apex\_domain](#input\_apex\_domain) | The parent / apex domain to be used for the cluster | `string` | `""` | no |
115120
| <a name="input_apex_domain_gcp_project"></a> [apex\_domain\_gcp\_project](#input\_apex\_domain\_gcp\_project) | The GCP project the apex domain is managed by, used to write recordsets for a subdomain if set. Defaults to current project. | `string` | `""` | no |
116121
| <a name="input_apex_domain_integration_enabled"></a> [apex\_domain\_integration\_enabled](#input\_apex\_domain\_integration\_enabled) | Flag that when set attempts to create delegation records in apex domain to point to domain created by this module | `bool` | `true` | no |
122+
| <a name="input_artifact_description"></a> [artifact\_description](#input\_artifact\_description) | artifact registry repository Description | `string` | `"jenkins-x Docker Repository"` | no |
123+
| <a name="input_artifact_enable"></a> [artifact\_enable](#input\_artifact\_enable) | Create artifact registry repository | `bool` | `true` | no |
124+
| <a name="input_artifact_location"></a> [artifact\_location](#input\_artifact\_location) | artifact registry repository Location | `string` | `"us-central1"` | no |
125+
| <a name="input_artifact_repository_id"></a> [artifact\_repository\_id](#input\_artifact\_repository\_id) | artifact registry repository Name | `string` | `"oci"` | no |
117126
| <a name="input_autoscaler_location_policy"></a> [autoscaler\_location\_policy](#input\_autoscaler\_location\_policy) | location policy for primary node pool | `string` | `"ANY"` | no |
118127
| <a name="input_autoscaler_max_node_count"></a> [autoscaler\_max\_node\_count](#input\_autoscaler\_max\_node\_count) | primary node pool max nodes | `number` | `5` | no |
119128
| <a name="input_autoscaler_min_node_count"></a> [autoscaler\_min\_node\_count](#input\_autoscaler\_min\_node\_count) | primary node pool min nodes | `number` | `3` | no |
@@ -188,33 +197,52 @@ The following two paragraphs provide the full list of configuration and output v
188197
| <a name="output_vault_bucket_url"></a> [vault\_bucket\_url](#output\_vault\_bucket\_url) | The URL to the bucket for secret storage |
189198
<!-- END_TF_DOCS -->
190199

191-
### Running `jx boot`
192200

193-
A terraform output (_jx\_requirements_) is available after applying this Terraform module.
201+
### Artifact Registry in setup with multiple Jenkins X clusters
202+
In a multi cluster setup, you should leave the value of `artifact_enable` as `true` **only in a
203+
development cluster** and set `artifact_enable = false` for other clusters. A development cluster is
204+
one where application build pipelines are executed. If you have multiple development clusters you
205+
can set `artifact_repository_id` to different values for them. Alternatively you can have
206+
`artifact_enable = true` in one and manually copy the values of `cluster.registry` and
207+
`cluster.dockerRegistryOrg` from `jx-requirements.yml` from that cluster repository to the other
208+
cdevelopment cluster repositories.
194209

195-
```sh
196-
terraform output jx_requirements
197-
```
210+
If you leave `artifact_enable` as `true` for multiple clusters and don't override
211+
`artifact_repository_id` terraform will fail since it can't create an already existing repository.
198212

199-
This `jx_requirements` output can be used as input to [Jenkins X Boot](https://jenkins-x.io/docs/getting-started/setup/boot/) which is responsible for installing all the required Jenkins X components into the cluster created by this module.
213+
### Migration from Container to Artifact Registry
200214

201-
![Jenkins X Installation/Update Flow](./images/terraform_google_jx.png)
215+
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.
202216

203-
:warning: **Note**: The generated _jx-requirements_ is only used for the first run of `jx boot`.
204-
During this first run of `jx boot` a git repository containing the source code for Jenkins X Boot is created.
205-
This (_new_) repository contains a _jx-requirements.yml_ (_which is now ahead of the jx-requirements output from terraform_) used by successive runs of `jx boot`.
217+
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.
206218

207-
Execute:
219+
#### Configuration Note
220+
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.
208221

209-
```sh
210-
terraform output jx_requirements > <some_empty_dir>/jx-requirements.yml
211-
# jenkins-x creates the environment repository directory localy before pushing to the Git server of choice
212-
cd <some_empty_dir>
213-
jx boot --requirements jx-requirements.yml
222+
#### Migration Options
223+
Here are two strategies for transitioning container images from `gcr.io` to the Artifact Registry:
224+
225+
##### Don't Migrate Existing Images
226+
- Continue developing applications as usual. New images, upon their release, will be pushed to the Artifact Registry.
227+
- **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.
228+
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):
229+
```bash
230+
kubectl get pods --all-namespaces -o jsonpath="{range .items[*].spec['initContainers', 'containers'][*]}{.image}{'\n'}{end}" | fgrep gcr.io/project_id | sort -u
214231
```
215232

216-
You are prompted for any further required configuration.
217-
The number of prompts depends on how much you have [pre-configured](#inputs) via your Terraform variables.
233+
##### Migrate Existing Images
234+
If you have a large number of applications running that are unlikely to be released in the coming
235+
year, migration of images to artifact registry while retaining the image names (in the domain
236+
`gcr.io`) could be considered. This means that existing helm charts will continue to work.
237+
238+
This process is not supported by this terraform module, instead you need to follow the steps outlined in the guide
239+
[Set up repositories with gcr.io domain support](https://cloud.google.com/artifact-registry/docs/transition/setup-gcr-repo).
240+
These steps include create the a repository in Artifact Registry, migrate images to it from
241+
container registry and enable redirection of gcr.io traffic.
242+
243+
If you keep the default settings for this module it will create another artifact repository that
244+
will be used for new images. If you want to use `gcr.io` artifact repository for new images you
245+
should set `artifact_enable = false`.
218246

219247
### Using a custom domain
220248

main.tf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ resource "google_project_service" "container_api" {
129129
disable_on_destroy = false
130130
}
131131

132+
resource "google_project_service" "artifactregistry" {
133+
provider = google
134+
project = var.gcp_project
135+
service = "artifactregistry.googleapis.com"
136+
disable_on_destroy = false
137+
}
132138
// ----------------------------------------------------------------------------
133139
// Create Kubernetes cluster
134140
// ----------------------------------------------------------------------------
@@ -148,6 +154,9 @@ module "cluster" {
148154
ip_range_services = var.ip_range_services
149155
max_pods_per_node = var.max_pods_per_node
150156
bucket_location = var.bucket_location
157+
artifact_enable = var.artifact_enable
158+
artifact_location = var.artifact_location
159+
artifact_repository_id = var.artifact_repository_id
151160
jenkins_x_namespace = var.jenkins_x_namespace
152161
force_destroy = var.force_destroy
153162
enable_primary_node_pool = var.enable_primary_node_pool
@@ -267,6 +276,10 @@ locals {
267276
git_owner_requirement_repos = var.git_owner_requirement_repos
268277
dev_env_approvers = var.dev_env_approvers
269278
lets_encrypt_production = var.lets_encrypt_production
279+
// GCP Artifact
280+
enable_artifact = var.artifact_enable
281+
registry = module.cluster.artifact_registry_repository
282+
docker_registry_org = module.cluster.artifact_registry_repository_name
270283
// Storage buckets
271284
log_storage_url = module.cluster.log_storage_url
272285
report_storage_url = module.cluster.report_storage_url

modules/cluster/outputs.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,11 @@ output "tekton_sa_email" {
4545
output "tekton_sa_name" {
4646
value = google_service_account.tekton_sa.name
4747
}
48+
49+
output "artifact_registry_repository" {
50+
value = local.artifact_registry_repository
51+
}
52+
53+
output "artifact_registry_repository_name" {
54+
value = local.artifact_repositoryid
55+
}

modules/cluster/serviceaccount.tf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,18 @@ resource "google_service_account_iam_member" "boot_sa_workload_identity_user" {
237237
role = "roles/iam.workloadIdentityUser"
238238
member = "serviceAccount:${var.gcp_project}.svc.id.goog[jx-git-operator/jx-boot-job]"
239239
}
240+
241+
// Artifact Registry
242+
resource "google_artifact_registry_repository_iam_member" "writers" {
243+
count = var.artifact_enable ? 1 : 0
244+
project = google_artifact_registry_repository.repo[count.index].project
245+
location = google_artifact_registry_repository.repo[count.index].location
246+
repository = google_artifact_registry_repository.repo[count.index].name
247+
248+
role = "roles/artifactregistry.writer"
249+
member = "serviceAccount:${google_service_account.tekton_sa.email}"
250+
251+
depends_on = [
252+
google_artifact_registry_repository.repo
253+
]
254+
}

modules/cluster/storage.tf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,19 @@ resource "google_storage_bucket" "repository_bucket" {
3333

3434
force_destroy = var.force_destroy
3535
}
36+
37+
// Artifact Registry
38+
locals {
39+
artifact_repositoryid = var.artifact_repository_id == "" ? var.cluster_name : var.artifact_repository_id
40+
artifact_registry_repository = "${var.artifact_location}-docker.pkg.dev/${var.gcp_project}"
41+
}
42+
43+
resource "google_artifact_registry_repository" "repo" {
44+
count = var.artifact_enable ? 1 : 0
45+
format = "DOCKER"
46+
location = var.artifact_location
47+
mode = "STANDARD_REPOSITORY"
48+
project = var.gcp_project
49+
repository_id = local.artifact_repositoryid
50+
description = var.artifact_description
51+
}

modules/cluster/variables.tf

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,4 +517,26 @@ variable "delete_protect" {
517517
type = bool
518518
default = true
519519
}
520+
// Artifact Registry
521+
variable "artifact_location" {
522+
description = "artifact registry repository Location"
523+
type = string
524+
default = "us-central1"
525+
}
520526

527+
variable "artifact_repository_id" {
528+
description = "artifact registry repository Name, Defaul Cluster Name"
529+
type = string
530+
default = "oci"
531+
}
532+
variable "artifact_description" {
533+
description = "artifact registry repository Description"
534+
type = string
535+
default = "jenkins-x Docker Repository"
536+
}
537+
538+
variable "artifact_enable" {
539+
description = "Create artifact registry repository"
540+
type = bool
541+
default = true
542+
}

modules/jx-requirements-v3.yml.tpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ spec:
66
project: "${gcp_project}"
77
provider: gke
88
zone: "${zone}"
9+
%{ if enable_artifact }
10+
dockerRegistryOrg: "${docker_registry_org}"
11+
registry: "${registry}"
12+
%{ endif }
913
ingress:
1014
%{ if subdomain != "" }
1115
domain: "${subdomain}.${apex_domain}"

variables.tf

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,3 +358,25 @@ variable "delete_protect" {
358358
default = true
359359
}
360360

361+
// GCP Artifact
362+
variable "artifact_location" {
363+
description = "artifact registry repository Location"
364+
type = string
365+
default = "us-central1"
366+
}
367+
variable "artifact_repository_id" {
368+
description = "artifact registry repository Name"
369+
type = string
370+
default = "oci"
371+
}
372+
variable "artifact_description" {
373+
description = "artifact registry repository Description"
374+
type = string
375+
default = "jenkins-x Docker Repository"
376+
}
377+
378+
variable "artifact_enable" {
379+
description = "Create artifact registry repository"
380+
type = bool
381+
default = true
382+
}

0 commit comments

Comments
 (0)