Gitlab blueprint (#2110)

* add gitlab blueprint
* add TODO.md

---------

Co-authored-by: Julio Castillo <jccb@google.com>
This commit is contained in:
simonebruzzechesse 2024-02-27 18:36:46 +01:00 committed by GitHub
parent 23c6723804
commit a34d93fb43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 1265 additions and 0 deletions

View File

@ -26,4 +26,10 @@ The blueprints in this folder show how to automate installation of specific thir
<a href="./f5-bigip/" title="F5 BigIP"><img src="./phpipam/diagram.png" align="left" width="320px"></a> <p style="margin-left: 340px">These examples show how to deploy F5 BigIP-VE load balancers in GCP.</p>
<br clear="left">
### Gitlab
<a href="./gitlab/" title="Gitlab"><img src="./gitlab/diagram.png" align="left" width="320px"></a> <p style="margin-left: 340px">This blueprint shows how to deploy a Gitlab instance in GCP. The architecture is based on the reference described in the [official documentation](https://docs.gitlab.com/ee/administration/reference_architectures/1k_users.html) with managed services such as Cloud SQL, Memorystore and Cloud Storage.</p>
<br clear="left">

View File

@ -0,0 +1,389 @@
# Gitlab Blueprint
This blueprint is responsible for provisioning a production ready Gitlab instance on the landing zone infrastructure. The [reference architecture](https://docs.gitlab.com/ee/administration/reference_architectures/1k_users.html) of this deployment target 1K users, updates to the current code is required in of HA and/or higher capacity requirements.
The following diagram illustrates the high-level design of created resources, which can be adapted to specific requirements via variables:
<p align="center">
<img src="diagram.png" alt="Gitlab">
</p>
## Table of contents
<!-- TOC -->
* [Gitlab Blueprint](#gitlab-blueprint)
* [Table of contents](#table-of-contents)
* [Managed Services for Seamless Operations](#managed-services-for-seamless-operations)
* [Object Storage <-> Google Cloud Storage](#object-storage-----google-cloud-storage)
* [Identity](#identity)
* [SAML Integration](#saml-integration)
* [Google Workspace Setup](#google-workspace-setup)
* [Others Identity Integration](#others-identity-integration)
* [Email](#email)
* [Sendgrid integration](#sendgrid-integration)
* [SSL Certificate Configuration](#ssl-certificate-configuration)
* [Networking and scalability](#networking-and-scalability)
* [HA](#ha)
* [Deployment](#deployment)
* [Step 0: Cloning the repository](#step-0--cloning-the-repository)
* [Step 2: Prepare the variables](#step-2--prepare-the-variables)
* [Step 3: Deploy resources](#step-3--deploy-resources)
* [Step 4: Use the created resources](#step-4--use-the-created-resources)
* [Reference and useful links](#reference-and-useful-links)
* [Files](#files)
* [Variables](#variables)
* [Outputs](#outputs)
<!-- TOC -->
## Managed Services for Seamless Operations
This Gitlab installation prioritizes the use of Google Cloud managed services to
streamline infrastructure management and optimization. Here's a breakdown of the
managed services incorporated:
1. [Google Cloud Storage](https://cloud.google.com/storage): is a highly
scalable and secure object storage service for storing and accessing data in
Google Cloud.<br/><br/>
2. [Cloud SQL PostgreSQL](https://cloud.google.com/sql/docs/postgres): Cloud SQL
for Postgres is a fully managed database service on Google Cloud Platform. It
eliminates database administration tasks, allowing you to focus on your
application, while offering high performance, automatic scaling, and secure
management of your PostgreSQL databases.<br/><br/>
3. [Memorystore](https://cloud.google.com/memorystore?hl=en): GCP Memorystore
offers a fully managed Redis service for in-memory data caching and
high-performance data access.
Benefits:
- Reduced Operational Overhead: Google handles infrastructure setup,
maintenance, and updates, freeing up your time and resources.
- Enhanced Security: Managed services often benefit from Google's comprehensive
security measures and expertise.
- Scalability: Easily adjust resource allocation to meet evolving demands.
- Cost Optimization: Pay for the resources you use, benefiting from Google's
infrastructure optimization.
Integration: Managed services seamlessly integrate with other GCP services,
promoting a cohesive cloud environment.
This module embraces managed services to deliver a resilient, scalable, and
cost-effective application architecture on Google Cloud.
### Object Storage <-> Google Cloud Storage
GitLab supports using an object storage service for holding numerous types of
data. Its recommended over NFS and in general its better in larger setups as
object storage is typically much more performant, reliable, and scalable.
A single storage connection to Cloud Storage is configured for all object types,
which leverages default Google Compute Engine credential (the so called "
consolidated form"). A Cloud Storage bucket is bootstrapped for each object
type, the table below summarized such a configuration:
| Object Type | Description | Cloud Storage Bucket |
|------------------|----------------------------------------|-----------------------------------|
| artifacts | CI artifacts | ${prefix}-gitlab-artifacts |
| external_diffs | Merge request diffs | ${prefix}-mr-diffs |
| uploads | User uploads | ${prefix}-gitlab-uploads |
| lfs | Git Large File Storage objects | ${prefix}-gitlab-lfs |
| packages | Project packages (e.g. PyPI, Maven ..) | ${prefix}-gitlab-packages |
| dependency_proxy | Dependency Proxy | ${prefix}-gitlab-dependency-proxy |
| terraform_state | Terraform state files | ${prefix}-gitlab-terraform-state |
| pages | Pages | ${prefix}-gitlab-pages |
For more information on Gitlab object storage and Google Cloud Storage
integration please refer to the official Gitlab documentation available at the
following [link](https://docs.gitlab.com/ee/administration/object_storage.html).
- [PostgreSQL service](https://docs.gitlab.com/ee/administration/postgresql/external.html)
Updated postgres configuration to match documentation, created required database
in postgres instance.
- [Redis](https://docs.gitlab.com/ee/administration/redis/replication_and_failover_external.html)
## Identity
GitLab integrates with a number of OmniAuth providers as well as external
authentication and authorization providers such as Google Secure LDAP and many
other providers.
At this time this stage can deal with SAML integration for both user
authentication and provisioning, in order to setup SAML integration please
provide the saml block on gitlab_config variable.
### SAML Integration
This section details how configure GitLab to act as a SAML service provider (
SP). This allows GitLab to consume assertions from a SAML identity provider (
IdP), such as Cloud Identity, to authenticate users. Please find instructions
below for integration with:
- [Google Workspace](#google-workspace-setup)
#### Google Workspace Setup
Setup of Google Workspace is documented in the official Gitlab documentation
available at the
following [link](https://docs.gitlab.com/ee/integration/saml.html#set-up-google-workspace)
which are also reported below for simplicity.
Create a custom SAML webapp following instructions available at the
following [link](https://support.google.com/a/answer/6087519), providing these
information in the service provider configuration:
| Configuration | Typical Value | Cloud Storage Bucket |
|-------------------|--------------------------------------------------|---------------------------------------------------------------------------------------------|
| Name of SAML App | Gitlab | Name of the app |
| ACS URL | https://<GITLAB_DOMAIN>/users/auth/saml/callback | Assertion Consumer Service URL. |
| GITLAB_DOMAIN | gitlab.example.com | Your GitLab instance domain. |
| Entity ID | https://gitlab.example.com | A value unique to your SAML application. Set it to the issuer in your GitLab configuration. |
| Name ID | EMAIL | Required value. Also known as name_identifier_format. |
Then setup the following SAML attribute mappings:
| Google Directory attributes | App attributes |
|--------------------------------|----------------|
| Basic information > Email | email |
| Basic Information > First name | first_name |
| Basic Information > Last name | last_name |
After configuring the Google Workspace SAML application, record the following
information:
| Value | Description |
|------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| SSO URL | Setup in gitlab_config.saml.sso_target_url variable |
| Certificate (download) | Setup in gitlab_config.saml.idp_cert_fingerprint (obtain value with the following command `openssl x509 -in <your_certificate.crt> -noout -fingerprint -sha1`) |
### Others Identity Integration
- [OpenID Connect OmniAuth](https://docs.gitlab.com/ee/administration/auth/oidc.html#configure-google)
- [Google Secure LDAP](https://docs.gitlab.com/ee/administration/auth/ldap/google_secure_ldap.html)
## Email
### Gmail / Workspace
- [ ] [documentation](https://docs.gitlab.com/ee/administration/incoming_email.html#gmail)
### Sendgrid integration
Use
the [Google Cloud Marketplace](https://console.cloud.google.com/marketplace/details/sendgrid-app/sendgrid-email)
to sign up for the SendGrid email service. Make a note of your SendGrid SMTP
account credentials, which include username, password, and hostname. Your SMTP
username and password are the same as what you used to sign up for the service.
The SendGrid hostname is smtp.sendgrid.net.
Create an API key:
Sign in to SendGrid and go to Settings > API Keys.
1. Create an API key.
2. Select the permissions for the key. At a minimum, the key must have Mail send
permissions to send email.
3. Click Save to create the key.
4. SendGrid generates a new key. This is the only copy of the key, so make sure
that you copy the key and save it for later.
Configure the sendgrid API key in the gitlab_config variable, under mail,
sendgrid arguments as per the following example:
```terraform
gitlab_config = {
hostname = "gitlab.example.com"
mail = {
sendgrid = {
api_key = "test"
}
}
}
```
## SSL Certificate Configuration
This module provides flexibility in configuring SSL certificates for the server.
You have two options:
1. **Provide Your Own Certificates**: If you have existing SSL certificates, you
can place them in the certs folder within the module's directory. The module
will automatically detect and use them.
File Names: Ensure the files are named ${gitlab_hostname}.crt (for the
certificate) and
gitlab_hostname.key (for the private key). Although it is not required in
this stage it is mandatory to also place inside the certs folder the server
CA certificate which is later use to secure HTTPS access from the Gitlab
runner. Name of the CA certificate should be: ${gitlab_hostname}.ca.crt
2. **Use Automatically Generated Self-Signed Certificates**: If you don't
provide certificates, the module will generate a self-signed certificate for
immediate use.
Updating Later: You can replace the self-signed certificate with your own
certificates at any time by placing them in the certs folder and re-running
Terraform.
**Important Notes:**
Certificate Validation: Self-signed certificates are not validated by browsers
and will trigger warnings. Use them only for development or testing
environments.
For more information on how to configure HTTPS on Gitlab please refer to the
original Gitlab documentation available at the
following [link](https://docs.gitlab.com/omnibus/settings/ssl/#configure-https-manually).
## Networking and scalability
- [Load balancer](https://docs.gitlab.com/ee/administration/load_balancer.html)
## HA
- [High Availability](http://ubimol.it/12.0/ee/administration/high_availability/README.html)
### Deployment
#### Step 0: Cloning the repository
If you want to deploy from your Cloud Shell, click on the image below, sign in
if required and when the prompt appears, click on “confirm”.
[![Open Cloudshell](../../../assets/images/cloud-shell-button.png)](https://shell.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2FGoogleCloudPlatform%2Fcloud-foundation-fabric&cloudshell_workspace=blueprints%2Fthird-party-solutions%2Fwordpress%2Fcloudrun)
Otherwise, in your console of choice:
```bash
git clone https://github.com/GoogleCloudPlatform/cloud-foundation-fabric
```
Before you deploy the architecture, you will need at least the following
information (for more precise configuration see the Variables section):
* The project ID
The VPC host project, VPC and subnets should already exist and the following networking requirements are satisfied:
- configured PSA for Cloud SQL on the VPC
- subnets configured with PGA and Cloud NAT for internet access
- Inbound firewall rule for IAP on port 22
- Inbound firewall rule for TCP ports 80, 443, 2222 from proxy subnet CIDR (gitlab)
#### Step 2: Prepare the variables
Once you have the required information, head back to your cloned repository.
Make sure youre in the directory of this tutorial (where this README is in).
Configure the Terraform variables in your `terraform.tfvars` file.
See [terraform.tfvars.sample](terraform.tfvars.sample) as starting point - just
copy it to `terraform.tfvars` and edit the latter. See the variables
documentation below.
#### Step 3: Deploy resources
Initialize your Terraform environment and deploy the resources:
```shell
terraform init
terraform apply
```
#### Step 4: Use the created resources
Connect to squid-proxy for accessing gitlab instance using the gcloud command
available in the `ssh_to_bastion` terraform output.
```bash
terraform output ssh_to_bastion
```
A gcloud command like the following should be available
```bash
gcloud compute ssh squid-vm --project ${project} --zone europe-west8-b -- -L 3128:127.0.0.1:3128 -N -q -f
```
Set as system proxy ip 127.0.0.1 and port 3128 and connect to Gitlab hostname https://gitlab.gcp.example.com.
Use default admin password available in /run/gitlab/config/initial_root_password or reset admin password via the following command on the Docker container:
```bash
gitlab-rake “gitlab:password:reset”
```
## Reference and useful links
- [Reference architecture up to 1k users](https://docs.gitlab.com/ee/administration/reference_architectures/1k_users.html)
- [`/etc/gitlab/gitlab.rb` template](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-config-template/gitlab.rb.template)
- [`/etc/gitlab/gitlab.rb` default options](https://docs.gitlab.com/ee/administration/package_information/defaults.html)
<!-- TFDOC OPTS files:1 show_extra:1 -->
<!-- BEGIN TFDOC -->
## Files
| name | description | modules | resources |
|---|---|---|---|
| [gitlab.tf](./gitlab.tf) | None | <code>compute-vm</code> · <code>iam-service-account</code> · <code>net-lb-int</code> | |
| [main.tf](./main.tf) | Module-level locals and resources. | <code>project</code> | |
| [outputs.tf](./outputs.tf) | Module outputs. | | |
| [services.tf](./services.tf) | None | <code>cloudsql-instance</code> · <code>gcs</code> | <code>google_redis_instance</code> |
| [ssl.tf](./ssl.tf) | None | | <code>tls_cert_request</code> · <code>tls_locally_signed_cert</code> · <code>tls_private_key</code> · <code>tls_self_signed_cert</code> |
| [variables.tf](./variables.tf) | Module variables. | | |
## Variables
| name | description | type | required | default | producer |
|---|---|:---:|:---:|:---:|:---:|
| [gitlab_instance_config](variables.tf#L69) | Gitlab Compute Engine instance config. | <code title="object&#40;&#123;&#10; instance_type &#61; optional&#40;string, &#34;n1-highcpu-8&#34;&#41;&#10; name &#61; optional&#40;string, &#34;gitlab-0&#34;&#41;&#10; network_tags &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; replica_zone &#61; optional&#40;string&#41;&#10; zone &#61; optional&#40;string&#41;&#10; boot_disk &#61; optional&#40;object&#40;&#123;&#10; size &#61; optional&#40;number, 20&#41;&#10; type &#61; optional&#40;string, &#34;pd-standard&#34;&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; data_disk &#61; optional&#40;object&#40;&#123;&#10; size &#61; optional&#40;number, 100&#41;&#10; type &#61; optional&#40;string, &#34;pd-ssd&#34;&#41;&#10; replica_zone &#61; optional&#40;string&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | |
| [network_config](variables.tf#L89) | Shared VPC network configurations to use for Gitlab Runner VM. | <code title="object&#40;&#123;&#10; host_project &#61; optional&#40;string&#41;&#10; network_self_link &#61; string&#10; subnet_self_link &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | |
| [prefix](variables.tf#L98) | Prefix used for resource names. | <code>string</code> | ✓ | | |
| [project_id](variables.tf#L117) | Project id, references existing project if `project_create` is null. | <code>string</code> | ✓ | | |
| [region](variables.tf#L136) | GCP Region. | <code>string</code> | ✓ | | |
| [admin_principals](variables.tf#L17) | Users, groups and/or service accounts that are assigned roles, in IAM format (`group:foo@example.com`). | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> | |
| [cloudsql_config](variables.tf#L23) | Cloud SQL Postgres config. | <code title="object&#40;&#123;&#10; name &#61; optional&#40;string, &#34;gitlab-0&#34;&#41;&#10; database_version &#61; optional&#40;string, &#34;POSTGRES_13&#34;&#41;&#10; tier &#61; optional&#40;string, &#34;db-custom-2-8192&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [gcs_config](variables.tf#L34) | GCS for Object Storage config. | <code title="object&#40;&#123;&#10; enable_versioning &#61; optional&#40;bool, false&#41;&#10; location &#61; optional&#40;string, &#34;EU&#34;&#41;&#10; storage_class &#61; optional&#40;string, &#34;STANDARD&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [gitlab_config](variables.tf#L45) | Gitlab configuration. | <code title="object&#40;&#123;&#10; hostname &#61; optional&#40;string, &#34;gitlab.gcp.example.com&#34;&#41;&#10; mail &#61; optional&#40;object&#40;&#123;&#10; enabled &#61; optional&#40;bool, false&#41;&#10; sendgrid &#61; optional&#40;object&#40;&#123;&#10; api_key &#61; optional&#40;string&#41;&#10; email_from &#61; optional&#40;string, null&#41;&#10; email_reply_to &#61; optional&#40;string, null&#41;&#10; &#125;&#41;, null&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; saml &#61; optional&#40;object&#40;&#123;&#10; forced &#61; optional&#40;bool, false&#41;&#10; idp_cert_fingerprint &#61; string&#10; sso_target_url &#61; string&#10; name_identifier_format &#61; optional&#40;string, &#34;urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress&#34;&#41;&#10; &#125;&#41;, null&#41;&#10; ha_required &#61; optional&#40;bool, false&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [project_create](variables.tf#L108) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object&#40;&#123;&#10; billing_account_id &#61; string&#10; parent &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [redis_config](variables.tf#L122) | Redis Config. | <code title="object&#40;&#123;&#10; memory_size_gb &#61; optional&#40;number, 1&#41;&#10; name &#61; optional&#40;string, &#34;gitlab-0&#34;&#41;&#10; persistence_mode &#61; optional&#40;string, &#34;RDB&#34;&#41;&#10; rdb_snapshot_period &#61; optional&#40;string, &#34;TWELVE_HOURS&#34;&#41;&#10; tier &#61; optional&#40;string, &#34;BASIC&#34;&#41;&#10; version &#61; optional&#40;string, &#34;REDIS_6_X&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
## Outputs
| name | description | sensitive | consumers |
|---|---|:---:|---|
| [gitlab_ilb_ip](outputs.tf#L26) | Gitlab Internal Load Balancer IP Address. | | |
| [instance](outputs.tf#L31) | Gitlab compute engine instance. | | |
| [postgresql_users](outputs.tf#L36) | Gitlab postgres user password. | ✓ | |
| [project](outputs.tf#L42) | GCP project. | | |
| [ssh_to_gitlab](outputs.tf#L47) | gcloud command to ssh gitlab instance. | | |
| [ssl_certs](outputs.tf#L52) | Gitlab SSL Certificates. | ✓ | |
<!-- END TFDOC -->
## Test
```hcl
module "test" {
source = "./fabric/blueprints/third-party-solutions/gitlab"
gitlab_config = {
hostname = "gitlab.gcp.example.com"
mail = {
sendgrid = {
api_key = "sample_api_key"
}
}
saml = {
idp_cert_fingerprint = "67:90:96.....REPLACE_ME"
sso_target_url = "https://accounts.google.com/o/saml2/idp?idpid=REPLACE_ME"
}
}
gitlab_instance_config = {
replica_zone = "europe-west8-c"
zone = "europe-west8-b"
data_disk = {
replica_zone = "europe-west8-c"
}
}
network_config = {
host_project = "host-project"
network_self_link = "https://www.googleapis.com/compute/v1/projects/prod-net-landing-0/global/networks/prod-landing-0"
subnet_self_link = "https://www.googleapis.com/compute/v1/projects/prod-net-landing-0/regions/europe-west1/subnetworks/landing-default-ew1"
}
prefix = "prefix"
project_create = {
billing_account_id = "1234-ABCD-1234"
parent = "folders/1234563"
}
project_id = "my-project"
region = "europe-west8"
}
# tftest modules=14 resources=50
```

View File

@ -0,0 +1,20 @@
# Gitlab TODOs
- Integrations
- [x] Identity
- [x] SAML
- [ ] Email:
- [ ] Gmail / Workspace
- [x] Sendgrid
- [x] ILB
- [ ] MIG
- [ ] Gitaly
- [x] HTTPS SSL
- [x] Gitlab SSH on port 2222
- [x] Check object store, use GCS wherever possible
- [x] Cloud SQL HA
- Memorystore
- [ ] HA
- [ ] PSC instead of PSA
- [x] Integration with Cloud Logging for Gitlab running on Docker container
- [ ] Integrate with Certificate Manager for SSH certificates

View File

@ -0,0 +1,118 @@
#cloud-config
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# https://hub.docker.com/r/nginx/nginx/
# https://nginx.io/manual/toc/#installation
write_files:
- path: /var/lib/docker/daemon.json
permissions: '0644'
owner: root
content: |
{
"live-restore": true,
"storage-driver": "overlay2",
"log-driver": "gcplogs",
"log-opts": {
"gcp-meta-name": "gitlab-0",
"max-size": "1024m"
}
}
- path: /tmp/gitlab/config/gitlab.rb
permissions: '0600'
owner: root
content: |
${gitlab_rb}
- path: /tmp/gitlab/ssl/${gitlab_cert_name}.key
permissions: '0600'
owner: root
content: |
${gitlab_ssl_key}
- path: /tmp/gitlab/ssl/${gitlab_cert_name}.crt
permissions: '0600'
owner: root
content: |
${gitlab_ssl_crt}
- path: /tmp/gitlab/sshd_config
permissions: '0644'
owner: root
content: |
${gitlab_sshd_config}
- path: /etc/systemd/system/gitlab-data.service
permissions: '0644'
owner: root
content: |
[Unit]
Description=Gitlab data disk
ConditionPathExists=/dev/disk/by-id/google-data
Before=gitlab.service
[Service]
Type=oneshot
ExecStart=/bin/mkdir -p /run/gitlab
ExecStart=/bin/bash -c \
"/bin/lsblk -fn -o FSTYPE \
/dev/disk/by-id/google-data |grep ext4 \
|| mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard \
/dev/disk/by-id/google-data"
ExecStart=/bin/bash -c \
"mount |grep /run/gitlab \
|| mount -t ext4 /dev/disk/by-id/google-data /run/gitlab"
ExecStart=/sbin/resize2fs /dev/disk/by-id/google-data
ExecStart=/bin/mkdir -p /run/gitlab/config
ExecStart=/bin/mkdir -p /run/gitlab/ssl
ExecStart=/bin/mv /tmp/gitlab/config/gitlab.rb /run/gitlab/config/gitlab.rb
ExecStart=/bin/mv /tmp/gitlab/sshd_config /run/gitlab/sshd_config
ExecStart=/bin/bash -c "base64 -d -i /tmp/gitlab/ssl/${gitlab_cert_name}.key > /run/gitlab/ssl/${gitlab_cert_name}.key"
ExecStart=/bin/bash -c "base64 -d -i /tmp/gitlab/ssl/${gitlab_cert_name}.crt > /run/gitlab/ssl/${gitlab_cert_name}.crt"
RemainAfterExit=true
# https://docs.gitlab.com/ee/install/docker.html#pre-configure-docker-container
- path: /etc/systemd/system/gitlab.service
permissions: '0644'
owner: root
content: |
[Unit]
Description=Start gitlab container
After=gitlab-data.service gcr-online.target docker.socket
Wants=gitlab-data.service gcr-online.target docker.socket docker-events-collector.service
[Service]
Environment="HOME=/home/gitlab"
ExecStartPre=/usr/bin/docker-credential-gcr configure-docker
ExecStartPre=mkdir -p /run/gitlab
ExecStart=/usr/bin/docker run --rm --name=gitlab \
--hostname ${gitlab_config.hostname} \
--shm-size 256m \
--env GITLAB_OMNIBUS_CONFIG="" \
--publish 443:443 \
--publish 80:80 \
--publish 2222:2222 \
-v /run/gitlab/config:/etc/gitlab \
-v /run/gitlab/ssl:/etc/gitlab/ssl \
-v /run/gitlab/logs:/var/log/gitlab \
-v /run/gitlab/data:/var/opt/gitlab \
-v /run/gitlab/sshd_config:/assets/sshd_config \
gitlab/gitlab-ce
ExecStop=/usr/bin/docker stop gitlab
runcmd:
- systemctl start node-problem-detector
- iptables -I INPUT 1 -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
- iptables -I INPUT 1 -p tcp -m tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
- iptables -I INPUT 1 -p tcp -m tcp --dport 2222 -m state --state NEW,ESTABLISHED -j ACCEPT
- systemctl daemon-reload
- systemctl start gitlab

View File

@ -0,0 +1,118 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# /etc/gitlab/gitlab.rb
external_url "https://${hostname}"
letsencrypt['enable'] = false
nginx['redirect_http_to_https'] = true
# https://docs.gitlab.com/omnibus/settings/redis.html
gitlab_rails['redis_enable_client'] = false
gitlab_rails['redis_host'] = '${redis.host}'
gitlab_rails['redis_port'] = ${redis.port}
# TODO: use auth
# gitlab_rails['redis_password'] = nil
redis['enable'] = false
# https://docs.gitlab.com/omnibus/settings/database.html#using-a-non-packaged-postgresql-database-management-server
postgresql['enable'] = false
gitlab_rails['db_adapter'] = 'postgresql'
gitlab_rails['db_encoding'] = 'utf8'
gitlab_rails['db_host'] = '${cloudsql.host}'
gitlab_rails['db_port'] = 5432
gitlab_rails['db_password'] = '${cloudsql.password}'
# https://docs.gitlab.com/ee/administration/object_storage.html#google-cloud-storage-gcs
# Consolidated object storage configuration
gitlab_rails['object_store']['enabled'] = true
gitlab_rails['object_store']['proxy_download'] = true
gitlab_rails['object_store']['connection'] = {
'provider' => 'Google',
'google_project' => '${project_id}',
'google_application_default' => true
}
# full example using the consolidated form
# https://docs.gitlab.com/ee/administration/object_storage.html#full-example-using-the-consolidated-form-and-amazon-s3
gitlab_rails['object_store']['objects']['artifacts']['bucket'] = '${prefix}-gitlab-artifacts'
gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = '${prefix}-gitlab-mr-diffs'
gitlab_rails['object_store']['objects']['lfs']['bucket'] = '${prefix}-gitlab-lfs'
gitlab_rails['object_store']['objects']['uploads']['bucket'] = '${prefix}-gitlab-uploads'
gitlab_rails['object_store']['objects']['packages']['bucket'] = '${prefix}-gitlab-packages'
gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = '${prefix}-gitlab-dependency-proxy'
gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = '${prefix}-gitlab-terraform-state'
gitlab_rails['object_store']['objects']['pages']['bucket'] = '${prefix}-gitlab-pages'
# SAML configuration
# https://docs.gitlab.com/ee/integration/saml.html
%{ if saml != null }
gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_external_providers'] = ['saml']
# create new user in case of sign in with SAML provider
gitlab_rails['omniauth_allow_single_sign_on'] = ['saml']
# do not force approval from admins for newly created users
gitlab_rails['omniauth_block_auto_created_users'] = false
# automatically link a first-time SAML sign-in with existing GitLab users if their email addresses match
gitlab_rails['omniauth_auto_link_saml_user'] = true
# Force user redirection to SAML
# To bypass the auto sign-in setting, append ?auto_sign_in=false in the sign in URL, for example: https://gitlab.example.com/users/sign_in?auto_sign_in=false.
%{ if saml.forced }
gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'saml'
%{ endif }
# SHA1 Fingerprint
gitlab_rails['omniauth_providers'] = [
{
name: "saml",
label: "SAML",
args: {
assertion_consumer_service_url: "https://${hostname}/users/auth/saml/callback",
idp_cert_fingerprint: '${saml.idp_cert_fingerprint}',
idp_sso_target_url: '${saml.sso_target_url}',
issuer: "https://${hostname}",
name_identifier_format: "${saml.name_identifier_format}"
}
}
]
%{ endif }
# mail configuration
%{ if mail.sendgrid != null }
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.sendgrid.net"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "apikey"
gitlab_rails['smtp_password'] = "${mail.sendgrid.api_key}"
gitlab_rails['smtp_domain'] = "smtp.sendgrid.net"
gitlab_rails['smtp_authentication'] = "plain"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
# If use Single Sender Verification You must configure from. If not fail
# 550 The from address does not match a verified Sender Identity. Mail cannot be sent until this error is resolved.
# Visit https://sendgrid.com/docs/for-developers/sending-email/sender-identity/ to see the Sender Identity requirements
%{ if try(mail.sendgrid.email_from != null, false) }
gitlab_rails['gitlab_email_from'] = '${mail.sendgrid.email_from}'
%{ endif }
%{ if try(mail.sendgrid.email_reply_to != null, false) }
gitlab_rails['email_reply_to'] = '${mail.sendgrid.email_reply_to}'
%{ endif }
%{ endif }
gitlab_rails['gitlab_shell_ssh_port'] = 2222
# gitlab_sshd['enable'] = true
# gitlab_sshd['listen_address'] = '[::]:2222'
# https://docs.gitlab.com/omnibus/installation/index.html#set-up-the-initial-password
# gitlab_rails['initial_root_password'] = '<my_strong_password>'

View File

@ -0,0 +1,27 @@
Port 2222
ChallengeResponseAuthentication no
HostKey /etc/gitlab/ssh_host_rsa_key
HostKey /etc/gitlab/ssh_host_ecdsa_key
HostKey /etc/gitlab/ssh_host_ed25519_key
Protocol 2
PermitRootLogin no
PasswordAuthentication no
MaxStartups 100:30:200
AllowUsers git
PrintMotd no
PrintLastLog no
PubkeyAuthentication yes
AuthorizedKeysFile %h/.ssh/authorized_keys /gitlab-data/ssh/authorized_keys
AuthorizedKeysCommand /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell-authorized-keys-check git %u %k
AuthorizedKeysCommandUser git
# With "UsePAM yes" the "!" is seen as a password disabled account and not fully locked so ssh public key login works
# Please make sure that the account is created without passwordlogin ("*" in /etc/shadow) or configure pam.
# Issue #5891 https://gitlab.com/gitlab-org/omnibus-gitlab
UsePAM no
# Disabling use DNS in ssh since it tends to slow connecting
UseDNS no
# Enable the use of Git protocol v2
AcceptEnv GIT_PROTOCOL

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

@ -0,0 +1,130 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
locals {
gitlab_rb = templatefile("${path.module}/assets/config.rb.tpl", {
project_id = module.project.project_id
cloudsql = {
host = module.db.instances.primary.private_ip_address
password = module.db.user_passwords.gitlab
}
mail = var.gitlab_config.mail
redis = {
host = google_redis_instance.cache.host
port = google_redis_instance.cache.port
}
prefix = var.prefix
saml = var.gitlab_config.saml
hostname = var.gitlab_config.hostname
})
gitlab_ssl_crt = local.self_signed_ssl_certs_required ? tls_locally_signed_cert.gitlab_server_singed_cert.0.cert_pem : file("${path.module}/certs/${var.gitlab_config.hostname}.crt")
gitlab_ssl_key = local.self_signed_ssl_certs_required ? tls_private_key.gitlab_server_key.0.private_key_pem : file("${path.module}/certs/${var.gitlab_config.hostname}.key")
gitlab_ssl_ca_crt = local.self_signed_ssl_certs_required ? tls_self_signed_cert.gitlab_ca_cert.0.cert_pem : file("${path.module}/certs/${var.gitlab_config.hostname}.ca.crt")
gitlab_ssl_ca_key = local.self_signed_ssl_certs_required ? tls_private_key.gitlab_ca_private_key.0.private_key_pem : ""
self_signed_ssl_certs_required = fileexists("${path.module}/certs/${var.gitlab_config.hostname}.crt") && fileexists("${path.module}/certs/${var.gitlab_config.hostname}.key") && fileexists("${path.module}/certs/${var.gitlab_config.hostname}.ca.crt") ? false : true
gitlab_user_data = templatefile("${path.module}/assets/cloud-config.yaml", {
gitlab_config = var.gitlab_config
gitlab_rb = indent(6, local.gitlab_rb)
gitlab_sshd_config = indent(6, file("${path.module}/assets/sshd_config"))
gitlab_cert_name = var.gitlab_config.hostname
gitlab_ssl_key = indent(6, base64encode(local.gitlab_ssl_key))
gitlab_ssl_crt = indent(6, base64encode(local.gitlab_ssl_crt))
})
}
module "gitlab-sa" {
source = "../../../modules/iam-service-account"
project_id = module.project.project_id
name = var.gitlab_instance_config.name
display_name = "Gitlab instance service account"
iam = {
"roles/iam.serviceAccountTokenCreator" = [module.gitlab-sa.iam_email]
}
iam_project_roles = {
(module.project.project_id) = [
"roles/logging.logWriter",
"roles/monitoring.metricWriter",
"roles/storage.admin"
]
}
}
module "gitlab-instance" {
source = "../../../modules/compute-vm"
project_id = module.project.project_id
zone = var.gitlab_instance_config.zone
name = var.gitlab_instance_config.name
instance_type = var.gitlab_instance_config.instance_type
boot_disk = {
initialize_params = {
image = "projects/cos-cloud/global/images/family/cos-stable"
size = var.gitlab_instance_config.boot_disk.size
type = var.gitlab_instance_config.boot_disk.type
}
}
attached_disks = [
{
name = "data"
size = var.gitlab_instance_config.data_disk.size
type = var.gitlab_instance_config.data_disk.type
options = {
replica_zone = var.gitlab_instance_config.replica_zone
}
}
]
network_interfaces = [
{
network = var.network_config.network_self_link
subnetwork = var.network_config.subnet_self_link
}
]
tags = var.gitlab_instance_config.network_tags
metadata = {
user-data = local.gitlab_user_data
google-logging-enabled = "true"
}
service_account = {
email = module.gitlab-sa.email
}
}
module "ilb" {
source = "../../../modules/net-lb-int"
project_id = module.project.project_id
region = var.region
name = "ilb"
service_label = "ilb"
vpc_config = {
network = var.network_config.network_self_link
subnetwork = var.network_config.subnet_self_link
}
group_configs = {
gitlab = {
zone = var.gitlab_instance_config.zone
instances = [
module.gitlab-instance.self_link
]
}
}
backends = [
{ group = module.ilb.groups.gitlab.self_link }
]
health_check_config = {
https = {
port = 443
}
}
}

View File

@ -0,0 +1,44 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
module "project" {
source = "../../../modules/project"
parent = try(var.project_create.parent, null)
billing_account = try(var.project_create.billing_account_id, null)
prefix = var.project_create == null ? null : var.prefix
name = var.project_id
project_create = var.project_create != null
services = [
"compute.googleapis.com",
"memcache.googleapis.com",
"redis.googleapis.com",
"sqladmin.googleapis.com",
"sql-component.googleapis.com",
"stackdriver.googleapis.com",
"dns.googleapis.com",
"iam.googleapis.com",
]
shared_vpc_service_config = {
attach = true
host_project = var.network_config.host_project
service_identity_iam = {
"roles/compute.networkUser" = [
"cloudservices", "compute"
]
}
network_users = var.admin_principals
}
}

View File

@ -0,0 +1,56 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
locals {
ssl_certs = {
"${var.gitlab_config.hostname}.crt" = local.gitlab_ssl_crt
"${var.gitlab_config.hostname}.key" = local.gitlab_ssl_key,
"${var.gitlab_config.hostname}.ca.crt" = local.gitlab_ssl_ca_crt,
"${var.gitlab_config.hostname}.ca.key" = local.gitlab_ssl_ca_key
}
}
output "gitlab_ilb_ip" {
description = "Gitlab Internal Load Balancer IP Address."
value = module.ilb.forwarding_rule_addresses[""]
}
output "instance" {
description = "Gitlab compute engine instance."
value = module.gitlab-instance.instance
}
output "postgresql_users" {
description = "Gitlab postgres user password."
sensitive = true
value = module.db.user_passwords
}
output "project" {
description = "GCP project."
value = module.project
}
output "ssh_to_gitlab" {
description = "gcloud command to ssh gitlab instance."
value = nonsensitive("gcloud compute ssh ${module.gitlab-instance.instance.name} --project ${module.project.project_id} --zone ${module.gitlab-instance.instance.zone} -- -L 8080:127.0.0.1:80 -L 2222:127.0.0.1:2222 -L 8443:127.0.0.1:443 -N -q -f")
}
output "ssl_certs" {
description = "Gitlab SSL Certificates."
value = local.ssl_certs
sensitive = true
}

View File

@ -0,0 +1,92 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
locals {
gitlab_buckets = [
"gitlab-artifacts", "gitlab-mr-diffs", "gitlab-lfs", "gitlab-uploads",
"gitlab-packages", "gitlab-dependency-proxy", "gitlab-terraform-state",
"gitlab-pages"
]
}
#######################################################################
# GITLAB MANAGED SERVICES #
#######################################################################
# https://docs.gitlab.com/ee/install/requirements.html#database
module "db" {
source = "../../../modules/cloudsql-instance"
project_id = module.project.project_id
region = var.region
name = var.cloudsql_config.name
availability_type = var.gitlab_config.ha_required ? "REGIONAL" : "ZONAL"
network_config = {
authorized_networks = {}
connectivity = {
psa_config = {
private_network = var.network_config.network_self_link
}
}
}
database_version = var.cloudsql_config.database_version
databases = [
"gitlabhq_production"
]
tier = var.cloudsql_config.tier
users = {
# generate password for user1
gitlab = {
password = null
type = "BUILT_IN"
}
}
}
# https://docs.gitlab.com/ee/install/requirements.html#redis
resource "google_redis_instance" "cache" {
project = module.project.project_id
region = var.region
name = var.redis_config.name
tier = var.redis_config.tier
memory_size_gb = var.redis_config.memory_size_gb
authorized_network = var.network_config.network_self_link
connect_mode = "PRIVATE_SERVICE_ACCESS"
redis_version = var.redis_config.version
display_name = "Gitlab Redis Instance"
persistence_config {
persistence_mode = var.redis_config.persistence_mode
rdb_snapshot_period = var.redis_config.rdb_snapshot_period
}
}
# https://docs.gitlab.com/ee/administration/object_storage.html#google-cloud-storage-gcs
module "gitlab_object_storage" {
source = "../../../modules/gcs"
for_each = toset(local.gitlab_buckets)
project_id = module.project.project_id
prefix = var.prefix
name = each.key
storage_class = var.gcs_config.storage_class
location = var.gcs_config.location
versioning = var.gcs_config.enable_versioning
iam = {
"roles/storage.objectUser" = [
"serviceAccount:${module.gitlab-sa.email}",
]
}
}

View File

@ -0,0 +1,107 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
locals {
cert_subjects = [
{
country = "IT"
province = "Lombardy"
locality = "Milan"
organization = "Example"
organizational_unit = "Example"
}
]
}
#######################################################################
# GITLAB CA PRIVATE KEY #
#######################################################################
resource "tls_private_key" "gitlab_ca_private_key" {
count = local.self_signed_ssl_certs_required ? 1 : 0
algorithm = "RSA"
}
#######################################################################
# GITLAB CA CERT #
#######################################################################
resource "tls_self_signed_cert" "gitlab_ca_cert" {
count = local.self_signed_ssl_certs_required ? 1 : 0
private_key_pem = tls_private_key.gitlab_ca_private_key.0.private_key_pem
is_ca_certificate = true
dynamic "subject" {
for_each = toset(local.cert_subjects)
content {
country = subject.value.country
province = subject.value.province
locality = subject.value.locality
common_name = "Gitlab CA"
organization = subject.value.organization
organizational_unit = subject.value.organizational_unit
}
}
validity_period_hours = 43800 // 1825 days or 5 years
allowed_uses = [
"digital_signature",
"cert_signing",
"crl_signing",
]
}
#######################################################################
# SERVER CERT SIGNED BY CA #
#######################################################################
resource "tls_private_key" "gitlab_server_key" {
count = local.self_signed_ssl_certs_required ? 1 : 0
algorithm = "RSA"
}
# Create CSR for Gitlab Server certificate
resource "tls_cert_request" "gitlab_server_csr" {
count = local.self_signed_ssl_certs_required ? 1 : 0
private_key_pem = tls_private_key.gitlab_server_key.0.private_key_pem
dns_names = [var.gitlab_config.hostname]
dynamic "subject" {
for_each = toset(local.cert_subjects)
content {
country = subject.value.country
province = subject.value.province
locality = subject.value.locality
common_name = "Gitlab"
organization = subject.value.organization
organizational_unit = subject.value.organizational_unit
}
}
}
resource "tls_locally_signed_cert" "gitlab_server_singed_cert" {
count = local.self_signed_ssl_certs_required ? 1 : 0
cert_request_pem = tls_cert_request.gitlab_server_csr.0.cert_request_pem
ca_private_key_pem = tls_private_key.gitlab_ca_private_key.0.private_key_pem
ca_cert_pem = tls_self_signed_cert.gitlab_ca_cert.0.cert_pem
validity_period_hours = 43800
allowed_uses = [
"digital_signature",
"key_encipherment",
"server_auth",
"client_auth",
]
}

View File

@ -0,0 +1,19 @@
gitlab_config = {
hostname = "gitlab.gcp.example.com"
mail = {
sendgrid = {
api_key = "sample_api_key"
}
}
saml = {
idp_cert_fingerprint = "67:90:96.....REPLACE_ME"
sso_target_url = "https://accounts.google.com/o/saml2/idp?idpid=REPLACE_ME"
}
}
network_config = {
host_project = "host-project"
network_self_link = "network_self_link"
subnet_self_link = "subnetwork_self_link"
}
prefix = "prefix"
project_id = "prod-gitlab-0"

View File

@ -0,0 +1,139 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
variable "admin_principals" {
description = "Users, groups and/or service accounts that are assigned roles, in IAM format (`group:foo@example.com`)."
type = list(string)
default = []
}
variable "cloudsql_config" {
description = "Cloud SQL Postgres config."
type = object({
name = optional(string, "gitlab-0")
database_version = optional(string, "POSTGRES_13")
tier = optional(string, "db-custom-2-8192")
})
default = {}
nullable = false
}
variable "gcs_config" {
description = "GCS for Object Storage config."
type = object({
enable_versioning = optional(bool, false)
location = optional(string, "EU")
storage_class = optional(string, "STANDARD")
})
default = {}
nullable = false
}
variable "gitlab_config" {
description = "Gitlab configuration."
type = object({
hostname = optional(string, "gitlab.gcp.example.com")
mail = optional(object({
enabled = optional(bool, false)
sendgrid = optional(object({
api_key = optional(string)
email_from = optional(string, null)
email_reply_to = optional(string, null)
}), null)
}), {})
saml = optional(object({
forced = optional(bool, false)
idp_cert_fingerprint = string
sso_target_url = string
name_identifier_format = optional(string, "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")
}), null)
ha_required = optional(bool, false)
})
default = {}
nullable = false
}
variable "gitlab_instance_config" {
description = "Gitlab Compute Engine instance config."
type = object({
instance_type = optional(string, "n1-highcpu-8")
name = optional(string, "gitlab-0")
network_tags = optional(list(string), [])
replica_zone = optional(string)
zone = optional(string)
boot_disk = optional(object({
size = optional(number, 20)
type = optional(string, "pd-standard")
}), {})
data_disk = optional(object({
size = optional(number, 100)
type = optional(string, "pd-ssd")
replica_zone = optional(string)
}), {})
})
}
variable "network_config" {
description = "Shared VPC network configurations to use for Gitlab Runner VM."
type = object({
host_project = optional(string)
network_self_link = string
subnet_self_link = string
})
}
variable "prefix" {
description = "Prefix used for resource names."
type = string
nullable = false
validation {
condition = var.prefix != ""
error_message = "Prefix cannot be empty."
}
}
variable "project_create" {
description = "Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format."
type = object({
billing_account_id = string
parent = string
})
default = null
}
variable "project_id" {
description = "Project id, references existing project if `project_create` is null."
type = string
}
variable "redis_config" {
description = "Redis Config."
type = object({
memory_size_gb = optional(number, 1)
name = optional(string, "gitlab-0")
persistence_mode = optional(string, "RDB")
rdb_snapshot_period = optional(string, "TWELVE_HOURS")
tier = optional(string, "BASIC")
version = optional(string, "REDIS_6_X")
})
default = {}
nullable = false
}
variable "region" {
description = "GCP Region."
type = string
}