Module deploys Drone CI stack helm charts set. Possible deployment setups:
The module supports network policies to control traffic flow. If both the Drone server and the Drone runner(s) are installed with the network policies enabled, the policy to allow access from the runner to the server is added by default.
Once you have a Corewide Solutions Portal account, this one-time action will use your browser session to retrieve credentials:
shellterraform login solutions.corewide.com
Initialize mandatory providers:
Copy and paste into your Terraform configuration and insert the variables:
hclmodule "tf_k8s_drone_ci" {
source = "solutions.corewide.com/kubernetes/tf-k8s-drone-ci/helm"
version = "~> 4.1.0"
# specify module inputs here or try one of the examples below
...
}
Initialize the setup:
shellterraform init
Corewide DevOps team strictly follows Semantic Versioning
Specification
to
provide our clients with products that have predictable upgrades between versions. We
recommend
pinning
patch versions of our modules using pessimistic
constraint operator (~>) to prevent breaking changes during upgrades.
To get new features during the upgrades (without breaking compatibility), use
~> 4.1 and run
terraform init -upgrade
For the safest setup, use strict pinning with version = "4.1.0"
|
Module
55% off
|
$810
|
| TOTAL | $810 |
Module deploys Drone CI stack helm charts set. Possible deployment setups:
The module supports network policies to control traffic flow. If both the Drone server and the Drone runner(s) are installed with the network policies enabled, the policy to allow access from the runner to the server is added by default.
All notable changes to this project are documented here.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.6.4 to 0.6.5) and application (from 2.12.0 to 2.28.2) versions0.6.1 to 0.7.0) and application (from 1.8.3 to 1.8.5) versionsdrone_server.scm_settings input validation rules for the SCM types that require the SCM serveringress_class variable (nginx by default)ingress_annotations parameter for the drone_server and drone_runner variables3.13.01.9 due to using cross-object referencing for input variable validationsdrone_rpc_secret and runner_ui_pwd resource types from random_string to random_password, which leads to change of the drone_rpc_secret and runner_dashboard_credentials output values(Last version compatible with Helm and Kubernetes Terraform providers version 2.0)
machine admin user with Terraform-generated token with the drone_admin_is_machine_account argument for the drone_server variabledrone_admin_user argument of the drone_server variabledrone_server_public_host, drone_server_private_host)BREAKING CHANGE: Kubernetes Drone runner has been deprecated and now its deployment is managed by relevant Docker type which isn't compatible with the previous version
ServiceAccount for the Drone runner instead of using the one that is managed by the Drone runner Helm chartdrone-runner-kube to drone-runner-dockerdrone_rpc_secret output is defined as a string instead of a list with one element if Drone server deployment is enabled0.2.5 to 0.6.4BREAKING CHANGE: now all kubernetes provider resources use versioned resources which aren't compatible with previous version
DRONE_RUNNER_LABELS to Drone runnersv1.x to v2.xNow all Kubernetes provider resources use versioned resources. According to Kubernetes provider's suggestions the simplest, non-destructive way to do this is to remove the old resource from state and import this resource as a version one, like so:
bash# If Kubernetes namespace was managed by the module, it must be re-imported
terraform state rm module.drone_ci.kubernetes_namespace.namespace[0]
terraform import module.drone_ci.kubernetes_namespace_v1.namespace[0] drone
# If there were namespaces that Drone runner needs to access, their settings must be re-imported
terraform state rm module.drone_ci.kubernetes_role.drone_runner["backend"] module.drone_ci.kubernetes_role_binding.drone_runner["backend"]
terraform import module.drone_ci.kubernetes_role_v1.drone_runner["backend"] drone-runner-backend
terraform import module.drone_ci.kubernetes_role_binding_v1.drone_runner["backend"] drone-runner-backend
v2.x to v3.xNow Drone runner uses deployment of Docker type. All the pipelines processed by a managed Drone runner must be updated to use docker type:
```yml
kind: pipeline
type: docker
```
To pull the Docker images from private registries, a Drone secret with credentials to the private container registry must be created and referenced in pipelines:
```yml
steps:
- name: build
image: registry.internal.company.com/golang:1.12
commands:
- go build
- go test
image_pull_secrets:
- dockerconfig
```
For K8s management (e.g. by means of kubectl or/and helm tools) K8s configuration files must be provided in the pipeline steps. For example, a step can be added in the pipeline that will retrieve and save a K8s configuration file in the default Drone workspace directory (which content will be available between all of the steps within the running pipeline) and reference this saved file in kubectl or/and helm commands of the next steps in the same pipeline.
drone_rpc_secret output is defined as a string instead of a list with one element if Drone server deployment is enabled, and its references should be updated accordingly:
hclmodule.drone_ci.drone_rpc_secret[0] ==> module.drone_ci.drone_rpc_secret
v3.x to v4.xModule from v4.0 has several management changes that require attention:
```hcl
terraform {
required_providers {
helm = {
source = "hashicorp/helm"
version = "~> 3.1"
}
text kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 3.0"
}
}
}
```
Upgrade project dependencies:
bash
terraform init --upgrade
If set, rewrite node selectors and custom values passed to the module components as nested maps following the below example:
```hcl
module "drone_ci" {
...
# From v3.x format
drone_server = {
custom_values = {
"ingress.enabled" = "true"
}
scdoc node_selector = {
"cloud\\.google\\.com/gke-nodepool" = "maintenance"
}
}
# To v4.0 format
drone_server = {
custom_values = {
ingress = {
enabled = true
}
}
node_selector = {
"cloud.google.com/gke-nodepool" = "maintenance"
}
}
}
```
Apply the changes to make sure the state of the resources is up-to-date with the new provider versions:
bashterraform apply
Deploy locally Drone server and runner without dashboard UI:
hclmodule "drone_ci" {
source = "solutions.corewide.com/kubernetes/tf-k8s-drone-ci/helm"
version = "~> 4.1"
drone_server = {
enabled = true
ingress_host = "drone.host.com"
drone_admin_user = "admin"
db_connection_settings = {
db_host = "db-host.com"
db_login = "db-login"
db_name = "db-name"
db_password = "db-password"
}
scm_settings = {
type = "GitHub"
client_id = "client_id"
client_secret = "client_secret"
}
}
drone_runner = {
count = 1
}
}
Deploy Drone server with machine Drone admin user and runner with access to the "backend" and allow access to specific API group in the cluster it runs in:
hclmodule "drone_ci" {
source = "solutions.corewide.com/kubernetes/tf-k8s-drone-ci/helm"
version = "~> 4.1"
drone_server = {
enabled = true
ingress_host = "drone.host.com"
drone_admin_user = "admin"
drone_admin_is_machine_account = true
db_connection_settings = {
db_host = "db-host.com"
db_login = "db-login"
db_name = "db-name"
db_password = "db-password"
}
scm_settings = {
type = "GitHub"
client_id = "client_id"
client_secret = "client_secret"
}
}
drone_runner = {
count = 1
cd_namespaces = ["backend"]
extra_api_groups = [
{
names = ["opentelemetry.io"]
resources = ["instrumentations"]
verbs = [
"create",
"delete",
"patch",
"update",
]
},
]
}
}
Deploy Drone server and runner with network policies that allow the Ingress Nginx access to the Drone server:
hclmodule "drone_ci" {
source = "solutions.corewide.com/kubernetes/tf-k8s-drone-ci/helm"
version = "~> 4.1"
drone_server = {
enabled = true
ingress_host = "drone.host.com"
drone_admin_user = "admin"
db_connection_settings = {
db_host = "db-host.com"
db_login = "db-login"
db_name = "db-name"
db_password = "db-password"
}
scm_settings = {
type = "GitHub"
client_id = "client_id"
client_secret = "client_secret"
}
network_policy = {
enabled = true
ingress = {
from = [
{
namespace_selector = {
"kubernetes.io/metadata.name" = "ingress-nginx"
}
pod_selector = {
"app.kubernetes.io/name" = "ingress-nginx"
}
},
{
namespace_selector = {
"kubernetes.io/metadata.name" = "default"
}
pod_selector = {
"name" = "test-pod"
}
},
]
}
}
}
drone_runner = {
count = 1
cd_namespaces = ["backend"]
extra_api_groups = [
{
names = ["opentelemetry.io"]
resources = ["instrumentations"]
verbs = [
"create",
"delete",
"patch",
"update",
]
},
]
network_policy = {
enabled = true
ingress = {
from = [
{
pod_selector = {
"name" = "test-pod"
}
namespace_selector = {
"app.kubernetes.io/name" = "default"
}
},
]
}
}
}
}
A note for DRONE_RUNNER_LABELS selectors with node keyword. A pipeline is not routed to a runner unless it matches all runner labels. If the pipeline only defines and matches a subset of runner labels it will not be routed to the runner. It means that if a runner has several labels, then you must provide all of them in node section. You can specify multiple runners by providing all labels of each runner in node list. Although, only the drone runner which was attached the last will execute a pipeline if several node labels are set within the pipeline. Don't specify node section at all if the pipeline should run on any runner (or on runners without labels).
Examples: you have runner with no labels, runner2 with label runner2:2 and runner3 with labels runner3:3,runner-arch:linux. if you skip node section, then pipeline will be executed in runner runner. If you set:
yamlnode:
runner2: 2
then a pipeline will be executed on runner2. If you set:
yamlnode:
## Runner2 label
runner2: 2
## Runner3 labels
runner3: 3
runner-arch: linux
then a pipeline will be executed on a runner which was attached last: either runner2 or runner3. If you set:
yamlnode:
## Only one of two runner3 labels
runner3: 3
then Drone server will not find any suitable runners at all since the second runner3 labels are missing.
Deploy only Drone server and set a variable for secrets encryption:
hclmodule "drone_ci" {
source = "solutions.corewide.com/kubernetes/tf-k8s-drone-ci/helm"
version = "~> 4.1"
drone_server = {
enabled = true
drone_admin_user = "admin"
ingress_host = "drone.host.com"
db_connection_settings = {
db_host = "db-host.com"
db_login = "db-login"
db_name = "db-name"
db_password = "db-password"
}
scm_settings = {
type = "GitHub"
client_id = "client_id"
client_secret = "client_secret"
}
custom_values = {
"env.DRONE_DATABASE_SECRET" = "7c229228a77d2cbddaa61ddc78d45e"
}
}
drone_runner = {
count = 0
}
}
Deploy only Drone runner with an enabled dashboard UI and custom label:
hclmodule "drone_ci" {
source = "solutions.corewide.com/kubernetes/tf-k8s-drone-ci/helm"
version = "~> 4.1"
drone_server = {
enabled = false
}
drone_runner = {
count = 1
server_address = "drone.host.com"
server_token = "token"
dashboard_enabled = true
dashboard_host = "drone-runner.host.com"
labels = ["env:dev"]
}
}
| Variable | Description | Type | Default | Required | Sensitive |
|---|---|---|---|---|---|
drone_runner |
Set of parameters for the Drone runner | object |
yes | no | |
drone_server |
Set of parameters for the Drone server | object |
yes | no | |
name_prefix |
Naming prefix for all the resources created by the module | string |
yes | no | |
create_namespace |
Indicates creation of dedicated namespace for Drone CI deployment | bool |
true |
no | no |
drone_runner.app_version |
Version of Drone Rrunner image to use | string |
1.8.5 |
no | no |
drone_runner.cd_namespaces |
A list of Namespaces in K8s cluster that Drone runner should be able to access. Only for access within the same cluster that hosts runner. If only "all" provided in the list - it is treated as allowing edit permissions to the whole cluster |
list(string) |
[] |
no | no |
drone_runner.chart_version |
Version of Drone runner Helm chart to use | string |
0.7.0 |
no | no |
drone_runner.concurrent_jobs |
Number of concurrent jobs Drone runner will handle | number |
2 |
no | no |
drone_runner.count |
How many runner replicas should be installed (0 to disable runner installation) |
number |
yes | no | |
drone_runner.custom_values |
Custom values to pass to the Drone runner Helm chart as a block | any |
{} |
no | no |
drone_runner.dashboard_auth_credentials |
Set of Drone runner dashboard access credentials | object |
no | no | |
drone_runner.dashboard_auth_credentials.password |
Drone runner dashboard password | string |
no | no | |
drone_runner.dashboard_auth_credentials.user |
Drone runner dashboard username | string |
drone |
no | no |
drone_runner.dashboard_enabled |
Whether Drone runner dashboard should be enabled | bool |
false |
no | no |
drone_runner.dashboard_host |
Valid domain name to expose web dashboard at (required only in case if Drone runner dashboard is enabled) | string |
no | no | |
drone_runner.extra_api_groups |
Additional API groups with parameters to add to K8s runner role | list(object) |
[] |
no | no |
drone_runner.extra_api_groups[*].names |
API group name(s) | list(string) |
[] |
no | no |
drone_runner.extra_api_groups[*].resources |
List of managed API group resources | list(string) |
[] |
no | no |
drone_runner.extra_api_groups[*].verbs |
List of available actions for the resources | list(string) |
[] |
no | no |
drone_runner.ingress_annotations |
Custom annotations to apply to Drone runner Ingress | map(any) |
{} |
no | no |
drone_runner.labels |
A list of runner labels to be attached. Each list element should have key-value format. Example: ["runner-name:jack", "runner-name:josh"] |
list(string) |
[] |
no | no |
drone_runner.network_policy |
Network policies configuration for Drone runner | object |
no | no | |
drone_runner.network_policy.enabled |
Whether network policies should be enabled | bool |
false |
no | no |
drone_runner.network_policy.ingress |
object |
no | no | ||
drone_runner.network_policy.ingress.from |
list(object) |
[] |
no | no | |
drone_runner.network_policy.ingress.from[*].namespace_selector |
Match labels for source namespaces | map(string) |
{} |
no | no |
drone_runner.network_policy.ingress.from[*].pod_selector |
Match labels for source pods | map(string) |
{} |
no | no |
drone_runner.network_policy.ingress.ports |
list(object) |
[] |
no | no | |
drone_runner.network_policy.ingress.ports[*].port |
Port number or alias to allow | string |
yes | no | |
drone_runner.network_policy.ingress.ports[*].protocol |
Protocol (e.g., TCP or UDP) | string |
yes | no | |
drone_runner.node_selector |
Selector of node group to place Drone runner in | map(any) |
{} |
no | no |
drone_runner.server_address |
Address of Drone server (not required for local Drone server and mandatory for creating only a runner with connection to an externally exposed remote Drone server) | string |
no | no | |
drone_runner.server_token |
RPC token to connect to a remote Drone server (not required for a local one, and mandatory for creating only a runner with a connection to an externally exposed remote server) | string |
no | no | |
drone_runner.serviceaccount_name |
The name of custom Service Account for the Drone runner | string |
no | no | |
drone_server.app_version |
Version of Drone server image to use | string |
2.28.2 |
no | no |
drone_server.chart_version |
Version of Drone server Helm chart to use | string |
0.6.5 |
no | no |
drone_server.custom_values |
Custom values to pass to the Drone server Helm chart as a block | any |
{} |
no | no |
drone_server.db_connection_settings |
Set of connection parameters of Drone database | object |
no | no | |
drone_server.db_connection_settings.db_driver |
Defines database engine type. Compatible values are: PostgreSQL and MySQL |
string |
postgresql |
no | no |
drone_server.db_connection_settings.db_host |
Database connection endpoint | string |
no | no | |
drone_server.db_connection_settings.db_login |
Database instance login | string |
no | no | |
drone_server.db_connection_settings.db_name |
Database name | string |
no | no | |
drone_server.db_connection_settings.db_password |
Database instance password | string |
no | no | |
drone_server.db_connection_settings.db_port |
Database instance port | number |
no | no | |
drone_server.drone_admin_is_machine_account |
Whether the Drone server admin user is a machine account | bool |
false |
no | no |
drone_server.drone_admin_user |
The name of Drone server admin user | string |
no | no | |
drone_server.enabled |
Whether Drone server should be installed | bool |
yes | no | |
drone_server.ingress_annotations |
Custom annotations to apply to Drone server Ingress | map(any) |
{} |
no | no |
drone_server.ingress_host |
Valid domain name for Drone dashboard UI | string |
no | no | |
drone_server.network_policy |
Network policies configuration for Drone server | object |
no | no | |
drone_server.network_policy.enabled |
Whether network policies should be enabled | bool |
false |
no | no |
drone_server.network_policy.ingress |
object |
no | no | ||
drone_server.network_policy.ingress.from |
list(object) |
[] |
no | no | |
drone_server.network_policy.ingress.from[*].namespace_selector |
Match labels for source namespaces | map(string) |
{} |
no | no |
drone_server.network_policy.ingress.from[*].pod_selector |
Match labels for source pods | map(string) |
{} |
no | no |
drone_server.network_policy.ingress.ports |
list(object) |
[] |
no | no | |
drone_server.network_policy.ingress.ports[*].port |
Port number or alias to allow | string |
yes | no | |
drone_server.network_policy.ingress.ports[*].protocol |
Protocol (e.g., TCP or UDP) | string |
yes | no | |
drone_server.node_selector |
Selector of node group to place Drone server in | map(any) |
{} |
no | no |
drone_server.scm_settings |
Set of parameters to manage connection of Drone to Source Control Management system | object |
no | no | |
drone_server.scm_settings.client_id |
SCM oauth client ID | string |
no | no | |
drone_server.scm_settings.client_secret |
SCM oauth client secret | string |
no | no | |
drone_server.scm_settings.host |
SCM server URL (can be mandatory for some compatible SCM types) | string |
no | no | |
drone_server.scm_settings.type |
SCM system type. Compatible values are: GitHub, GitLab, Gogs, Gitea, Bitbucket, and Gitee |
string |
no | no | |
ingress_cert_issuer |
Ingress Nginx TLS certificate issuer | string |
letsencrypt |
no | no |
ingress_class |
Ingress Class definition | string |
nginx |
no | no |
logs_debug_mode |
Toggle debug logging mode | bool |
false |
no | no |
namespace |
The namespace to install the Drone CI into | string |
drone |
no | no |
| Output | Description | Type | Sensitive |
|---|---|---|---|
drone_admin_user |
Drone server admin credentials | map |
yes |
drone_admin_user.token |
Authorization token for Drone server admin | map |
yes |
drone_admin_user.username |
Name of the Drone server admin user | map |
yes |
drone_rpc_secret |
A shared secret to authenticate communication between runners and Drone server | list(attribute) |
yes |
drone_server_private_host |
Private host of Drone server | computed |
no |
drone_server_public_host |
Public host of Drone server | computed |
no |
runner_dashboard_credentials |
Access credentials for the Drone runner UI | map |
yes |
runner_dashboard_credentials.password |
Drone runner dashboard password | map |
yes |
runner_dashboard_credentials.username |
Drone runner dashboard username | map |
yes |
| Dependency | Version | Kind |
|---|---|---|
terraform |
>= 1.9 |
CLI |
hashicorp/helm |
~> 3.1 |
provider |
hashicorp/kubernetes |
~> 3.0 |
provider |
hashicorp/random |
~> 3.3 |
provider |
These components are included as is under the terms of their corresponding licenses.
| Component | License |
|---|---|
| Drone CI | Apache 2.0 |
| Drone CI Helm charts | BSD-2-Clause-Patent |