diff --git a/.tflint.hcl b/.tflint.hcl index 81e0b17..e5c757b 100644 --- a/.tflint.hcl +++ b/.tflint.hcl @@ -5,9 +5,9 @@ plugin "aws" { } config { -#Enables module inspection -module = false -force = false + # Enables module inspection (Updated to the correct attribute) + call_module_type = "none" + force = false } # Required that all AWS resources have specified tags. @@ -19,94 +19,93 @@ rule "aws_resource_missing_tags" { ] } -# Disallow deprecated (0.11-style) interpolation +# Disallow deprecated (0.11-style) interpolation. rule "terraform_deprecated_interpolation" { -enabled = true + enabled = true } # Disallow legacy dot index syntax. rule "terraform_deprecated_index" { -enabled = true + enabled = true } # Disallow variables, data sources, and locals that are declared but never used. rule "terraform_unused_declarations" { -enabled = true + enabled = true } # Disallow // comments in favor of #. rule "terraform_comment_syntax" { -enabled = false + enabled = false } # Disallow output declarations without description. rule "terraform_documented_outputs" { -enabled = true + enabled = true } # Disallow variable declarations without description. rule "terraform_documented_variables" { -enabled = true + enabled = true } # Disallow variable declarations without type. rule "terraform_typed_variables" { -enabled = true + enabled = true } # Disallow specifying a git or mercurial repository as a module source without pinning to a version. rule "terraform_module_pinned_source" { -enabled = true + enabled = true } -# Enforces naming conventions +# Enforces naming conventions. rule "terraform_naming_convention" { -enabled = true + enabled = true -#Require specific naming structure -variable { -format = "snake_case" -} + # Require specific naming structure. + variable { + format = "snake_case" + } -locals { -format = "snake_case" -} + locals { + format = "snake_case" + } -output { -format = "snake_case" -} + output { + format = "snake_case" + } -#Allow any format -resource { -format = "none" -} + # Allow any format. + resource { + format = "none" + } -module { -format = "none" -} - -data { -format = "none" -} + module { + format = "none" + } + data { + format = "none" + } } # Disallow terraform declarations without require_version. rule "terraform_required_version" { -enabled = true + enabled = true } # Require that all providers have version constraints through required_providers. rule "terraform_required_providers" { -enabled = true + enabled = true } -# Ensure that a module complies with the Terraform Standard Module Structure +# Ensure that a module complies with the Terraform Standard Module Structure. rule "terraform_standard_module_structure" { -enabled = true + enabled = true } # terraform.workspace should not be used with a "remote" backend with remote execution. rule "terraform_workspace_remote" { -enabled = true + enabled = true } diff --git a/README.md b/README.md index fa14041..27c35cd 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,9 @@ No modules. | Name | Type | |------|------| | [helm_release.sonarqube](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | +| [kubernetes_manifest.migration_job](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_namespace.sonarqube](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource | +| [random_password.monitoringPasscode](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | | [random_password.postgresql_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | | [random_password.sonarqube_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | @@ -80,9 +82,13 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [chart\_version](#input\_chart\_version) | Version of the Jenkins chart that will be used to deploy Jenkins application. | `string` | `"10.6.1"` | no | +| [chart\_version](#input\_chart\_version) | Version of the Jenkins chart that will be used to deploy Jenkins application. | `string` | `"2025.2.0"` | no | | [namespace](#input\_namespace) | Name of the Kubernetes namespace where the Jenkins deployment will be deployed. | `string` | `"sonarqube"` | no | -| [sonarqube\_config](#input\_sonarqube\_config) | Specify the configuration settings for Sonarqube, including the hostname, storage options, and custom YAML values. | `any` |
{
"grafana_monitoring_enabled": false,
"hostname": "",
"postgresql_external_server_url": "",
"postgresql_password_external": "",
"postgresql_volume_size": "",
"sonarqube_volume_size": "",
"storage_class_name": "",
"values_yaml": ""
} | no |
+<<<<<<< HEAD
+| [sonarqube\_config](#input\_sonarqube\_config) | Specify the configuration settings for Sonarqube, including the hostname, storage options, and custom YAML values. | `any` | {
"grafana_monitoring_enabled": false,
"hostname": "",
"postgresql_external_server_url": "",
"postgresql_password_external": "",
"postgresql_volume_size": "",
"sonarqube_volume_size": "",
"storage_class_name": "",
"updateExistingSonarqube": false,
"values_yaml": ""
} | no |
+=======
+| [sonarqube\_config](#input\_sonarqube\_config) | Specify the configuration settings for Sonarqube, including the hostname, storage options, and custom YAML values. | `any` | {
"grafana_monitoring_enabled": false,
"hostname": "",
"postgresql_external_server_url": "",
"postgresql_password_external": "",
"postgresql_volume_size": "",
"sonarqube_volume_size": "",
"storage_class_name": "",
"values_yaml": ""
} | no |
+>>>>>>> 2d71186b50e076f45ab7e6a587037b5bb0c435ff
## Outputs
diff --git a/examples/complete/aws/README.md b/examples/complete/aws/README.md
index 4b9f10e..def54f5 100644
--- a/examples/complete/aws/README.md
+++ b/examples/complete/aws/README.md
@@ -50,8 +50,7 @@ No requirements.
| Name | Source | Version |
|------|--------|---------|
-
-| [sonarqube](#module\_sonarqube) | squareops/sonarqube/kubernetes | 3.0.1 |
+| [sonarqube](#module\_sonarqube) | squareops/sonarqube/kubernetes | 3.1.0 |
## Resources
diff --git a/examples/complete/aws/helm/values.yaml b/examples/complete/aws/helm/values.yaml
index 9c49a96..5180589 100644
--- a/examples/complete/aws/helm/values.yaml
+++ b/examples/complete/aws/helm/values.yaml
@@ -1,10 +1,11 @@
resources:
limits:
- cpu: 500m
- memory: 2Gi
+ cpu: 700m
+ memory: 6144M
requests:
- cpu: 200m
- memory: 1.5Gi
+ cpu: 300m
+ memory: 2048M
+
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
diff --git a/examples/complete/aws/main.tf b/examples/complete/aws/main.tf
index be1e964..a2f415c 100644
--- a/examples/complete/aws/main.tf
+++ b/examples/complete/aws/main.tf
@@ -8,18 +8,24 @@ locals {
Department = "Engineering"
}
}
-
module "sonarqube" {
- source = "squareops/sonarqube/kubernetes"
- version = "3.0.1"
+ source = "squareops/sonarqube/kubernetes"
+ version = "3.1.1"
sonarqube_config = {
hostname = "sonarqube.squareops.in"
values_yaml = file("./helm/values.yaml")
storage_class_name = "gp2"
sonarqube_volume_size = "5Gi"
- postgresql_volume_size = "20Gi"
+ postgresql_volume_size = "10Gi"
grafana_monitoring_enabled = false
+ monitoringPasscode = ""
postgresql_password_external = ""
postgresql_external_server_url = ""
+ sonarqube_password = "xxxxx"
+
+ updateExistingSonarqube = false # if you have existing sonarqube and want to upgrade,then enable it.
+ updateExistingSonarqubePassword = false #if you want to update password,enable it and pass sonarqube_current_password(old),sonarqube_password(new)
+ sonarqube_current_password = "xxxxxx" # if you upgrade sonarqube then you have to provide your previous sonarqube password ##Secret name=sonarqube-sonarqube-admin-password
+ postgresql_current_password = "xxxxxxx" # if you upgrade sonarqube then you have to provide your previous postgresql password ##Secret name=sonarqube-postgresql
}
}
diff --git a/examples/complete/azure/README.md b/examples/complete/azure/README.md
index d24986f..6467b76 100644
--- a/examples/complete/azure/README.md
+++ b/examples/complete/azure/README.md
@@ -50,7 +50,7 @@ No requirements.
| Name | Source | Version |
|------|--------|---------|
-| [sonarqube](#module\_sonarqube) | squareops/sonarqube/kubernetes | 3.0.1 |
+| [sonarqube](#module\_sonarqube) | squareops/sonarqube/kubernetes | 3.1.0 |
## Resources
diff --git a/examples/complete/azure/main.tf b/examples/complete/azure/main.tf
index 426d042..c6213b2 100644
--- a/examples/complete/azure/main.tf
+++ b/examples/complete/azure/main.tf
@@ -1,7 +1,7 @@
locals {
- name = "sonarqube"
+ name = ""
region = ""
- environment = "prod"
+ environment = ""
additional_tags = {
Owner = "organization_name"
Expires = "Never"
@@ -10,16 +10,23 @@ locals {
}
module "sonarqube" {
- source = "squareops/sonarqube/kubernetes"
- version = "3.0.1"
+ source = "squareops/sonarqube/kubernetes"
+ version = "3.1.1"
sonarqube_config = {
- hostname = "sonarqube.skaf.squareops.in"
+ hostname = "sonarqube.squareops.in"
values_yaml = file("./helm/values.yaml")
- storage_class_name = "infra-service-sc"
+ storage_class_name = "gp2"
sonarqube_volume_size = "5Gi"
- postgresql_volume_size = "20Gi"
+ postgresql_volume_size = "10Gi"
grafana_monitoring_enabled = false
- postgresql_password_external = "admin"
+ monitoringPasscode = ""
+ postgresql_password_external = ""
postgresql_external_server_url = ""
+ sonarqube_password = ""
+
+ updateExistingSonarqube = false # if you have existing sonarqube and want to upgrade,then enable it.
+ updateExistingSonarqubePassword = false #if you want to update password,enable it and pass sonarqube_current_password(old),sonarqube_password(new)
+ sonarqube_current_password = "xxxxxx" # if you upgrade sonarqube then you have to provide your previous sonarqube password ##Secret name=sonarqube-sonarqube-admin-password
+ postgresql_current_password = "xxxxxxx" # if you upgrade sonarqube then you have to provide your previous postgresql password ##Secret name=sonarqube-postgresql
}
}
diff --git a/examples/complete/gcp/README.md b/examples/complete/gcp/README.md
index f198771..e21b219 100644
--- a/examples/complete/gcp/README.md
+++ b/examples/complete/gcp/README.md
@@ -50,7 +50,7 @@ No requirements.
| Name | Source | Version |
|------|--------|---------|
-| [sonarqube](#module\_sonarqube) | squareops/sonarqube/kubernetes | 3.0.1 |
+| [sonarqube](#module\_sonarqube) | squareops/sonarqube/kubernetes | 3.1.0 |
## Resources
diff --git a/examples/complete/gcp/main.tf b/examples/complete/gcp/main.tf
index f12a286..c6213b2 100644
--- a/examples/complete/gcp/main.tf
+++ b/examples/complete/gcp/main.tf
@@ -1,7 +1,7 @@
locals {
- name = "sonarqube"
+ name = ""
region = ""
- environment = "prod"
+ environment = ""
additional_tags = {
Owner = "organization_name"
Expires = "Never"
@@ -10,16 +10,23 @@ locals {
}
module "sonarqube" {
- source = "squareops/sonarqube/kubernetes"
- version = "3.0.1"
+ source = "squareops/sonarqube/kubernetes"
+ version = "3.1.1"
sonarqube_config = {
hostname = "sonarqube.squareops.in"
values_yaml = file("./helm/values.yaml")
storage_class_name = "gp2"
sonarqube_volume_size = "5Gi"
- postgresql_volume_size = "20Gi"
+ postgresql_volume_size = "10Gi"
grafana_monitoring_enabled = false
+ monitoringPasscode = ""
postgresql_password_external = ""
postgresql_external_server_url = ""
+ sonarqube_password = ""
+
+ updateExistingSonarqube = false # if you have existing sonarqube and want to upgrade,then enable it.
+ updateExistingSonarqubePassword = false #if you want to update password,enable it and pass sonarqube_current_password(old),sonarqube_password(new)
+ sonarqube_current_password = "xxxxxx" # if you upgrade sonarqube then you have to provide your previous sonarqube password ##Secret name=sonarqube-sonarqube-admin-password
+ postgresql_current_password = "xxxxxxx" # if you upgrade sonarqube then you have to provide your previous postgresql password ##Secret name=sonarqube-postgresql
}
}
diff --git a/helm/values.yaml b/helm/values.yaml
index 5a1e353..b40ac17 100644
--- a/helm/values.yaml
+++ b/helm/values.yaml
@@ -1,65 +1,67 @@
+community:
+ enabled: true
+
+setAdminPassword:
+ newPassword: "${sonarqube_password}"
+ currentPassword: "${sonarqube_current_password}"
+
+monitoringPasscode: "${monitoringPasscode}"
+
+postgresql:
+ enabled: "${postgresql_enable}"
+ postgresqlPassword: "${postgresql_password}"
+ persistence:
+ storageClass: "${sonarqube_sc}"
+ size: 20Gi
+ resources:
+ limits:
+ cpu: 200m
+ memory: 1Gi
+ requests:
+ cpu: 100m
+ memory: 200Mi
+
+persistence:
+ enabled: true
+ storageClass: "${sonarqube_sc}"
+ accessMode: ReadWriteOnce
+ size: "${volume_size}"
+ uid: 1000
+ guid: 0
+
resources:
limits:
cpu: 800m
- memory: 4Gi
+ memory: 6144M
requests:
- cpu: 100m
- memory: 2Gi
+ cpu: 400m
+ memory: 2048M
annotations:
co.elastic.logs/enabled: "true"
-persistence:
- enabled: true
- storageClass: ${sonarqube_sc}
- accessMode: ReadWriteOnce
- size: ${volume_size}
- uid: 1000
-
ingress:
enabled: true
hosts:
- - name: ${hostname}
-
+ - name: "${hostname}"
annotations:
kubernetes.io/ingress.class: "nginx"
kubernetes.io/tls-acme: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/proxy-body-size: "500m"
-
tls:
- secretName: sonarqube
hosts:
- - ${hostname}
+ - "${hostname}"
affinity:
- nodeAffinity:
- requiredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
- matchExpressions:
- key: "Addons-Services"
operator: In
values:
- - "true"
-
-account:
- adminPassword: "${sonarqube_password}"
-
+ - "true"
prometheusExporter:
enabled: "${prometheus_exporter_enable}"
-
-postgresql:
-# # Enable to deploy the PostgreSQL chart
- enabled: ${postgresql_enable}
- postgresqlPassword: "${postgresql_password}"
- persistence:
- enabled: true
- size: ${postgresql_disk_size}
- storageClass: ${sonarqube_sc}
- resources:
- limits:
- cpu: 200m
- memory: 1Gi
- requests:
- cpu: 100m
- memory: 200Mi
diff --git a/main.tf b/main.tf
index 4a258c2..88b1440 100644
--- a/main.tf
+++ b/main.tf
@@ -1,15 +1,22 @@
locals {
count = var.sonarqube_config.postgresql_external_server_url != "" ? [] : [1]
+
+ effective_sonarqube_password = var.sonarqube_config.sonarqube_password != "" ? var.sonarqube_config.sonarqube_password : random_password.sonarqube_password.result
+
+ effective_postgresql_password = var.sonarqube_config.postgresql_current_password != "" && var.sonarqube_config.updateExistingSonarqube == true ? var.sonarqube_config.postgresql_current_password : random_password.postgresql_password.result
}
resource "random_password" "sonarqube_password" {
length = 20
- special = false
+ special = true
}
resource "random_password" "postgresql_password" {
length = 20
- special = false
+ special = true
+}
+resource "random_password" "monitoringPasscode" {
+ length = 20
+ special = true
}
-
resource "kubernetes_namespace" "sonarqube" {
metadata {
name = var.namespace
@@ -26,16 +33,18 @@ resource "helm_release" "sonarqube" {
repository = "https://sonarsource.github.io/helm-chart-sonarqube"
values = [
templatefile("${path.module}/helm/values.yaml", {
+ monitoringPasscode = var.sonarqube_config.monitoringPasscode != "" ? var.sonarqube_config.monitoringPasscode : random_password.monitoringPasscode.result
hostname = var.sonarqube_config.hostname
volume_size = var.sonarqube_config.sonarqube_volume_size
sonarqube_sc = var.sonarqube_config.storage_class_name
postgresql_enable = var.sonarqube_config.postgresql_external_server_url != "" ? false : true
- sonarqube_password = random_password.sonarqube_password.result
- postgresql_password = random_password.postgresql_password.result
+ sonarqube_password = local.effective_sonarqube_password
+ sonarqube_current_password = var.sonarqube_config.updateExistingSonarqube == true ? var.sonarqube_config.sonarqube_current_password : "admin"
+ postgresql_password = local.effective_postgresql_password
postgresql_disk_size = var.sonarqube_config.postgresql_volume_size
prometheus_exporter_enable = var.sonarqube_config.grafana_monitoring_enabled
- postgresql_password_external = var.sonarqube_config.postgresql_password_external
postgresql_external_server_url = var.sonarqube_config.postgresql_external_server_url
+ postgresql_password_external = var.sonarqube_config.postgresql_password_external
}),
var.sonarqube_config.values_yaml
@@ -56,3 +65,82 @@ resource "helm_release" "sonarqube" {
}
}
}
+resource "kubernetes_manifest" "migration_job" {
+ count = var.sonarqube_config.updateExistingSonarqube ? 1 : 0
+ manifest = {
+ apiVersion = "batch/v1"
+ kind = "Job"
+ metadata = {
+ name = "db-migration-watcher-job"
+ namespace = "sonarqube"
+ }
+ spec = {
+ backoffLimit = 4
+ completions = 1
+ parallelism = 1
+ template = {
+ spec = {
+ restartPolicy = "Never"
+ containers = [
+ {
+ name = "db-migration-watcher"
+ image = "alpine:latest"
+ command = [
+ "/bin/sh", "-c", <<-EOT
+ sleep 180 &&
+ apk add --no-cache curl &&
+ curl -s -X POST -u admin:"${var.sonarqube_config.sonarqube_current_password}" "http://sonarqube-sonarqube:9000/api/system/migrate_db" &&
+ echo "DB Migration triggered. Exiting watcher."
+ EOT
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+}
+
+
+resource "kubernetes_manifest" "sonarqube_password_reset_job" {
+ count = var.sonarqube_config.updateExistingSonarqubePassword ? 1 : 0
+
+ manifest = {
+ apiVersion = "batch/v1"
+ kind = "Job"
+ metadata = {
+ name = "sonarqube-password-reset"
+ namespace = "sonarqube"
+ }
+ spec = {
+ backoffLimit = 4
+ completions = 1
+ parallelism = 1
+ ttlSecondsAfterFinished: 60
+ template = {
+ spec = {
+ restartPolicy = "Never"
+ containers = [
+ {
+ name = "password-reset"
+ image = "curlimages/curl:8.5.0"
+ command = [
+ "sh", "-c", <<-EOT
+ echo "Resetting SonarQube admin password..." &&
+ curl -s -X POST -u admin:"${var.sonarqube_config.sonarqube_current_password}" \
+ "http://sonarqube-sonarqube:9000/api/users/change_password" \
+ --data-urlencode "login=admin" \
+ --data-urlencode "previousPassword=${var.sonarqube_config.sonarqube_current_password}" \
+ --data-urlencode "password=${var.sonarqube_config.sonarqube_password}" \
+ -w "%%{http_code}" -o /dev/null
+ echo "Password change complete."
+ EOT
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+}
+
diff --git a/outputs.tf b/outputs.tf
index 5d69399..832267d 100644
--- a/outputs.tf
+++ b/outputs.tf
@@ -2,13 +2,13 @@ output "sonarqube" {
description = "Sonarqube Credentials "
value = {
username = "admin",
- password = nonsensitive(random_password.sonarqube_password.result),
+ password = nonsensitive(local.effective_sonarqube_password),
url = var.sonarqube_config.hostname
}
}
output "sonarqube_postgresql_password" {
- value = random_password.postgresql_password.result
+ value = nonsensitive(local.effective_postgresql_password)
description = "Password for the PostgreSQL database deployed with SonarQube"
sensitive = true
}
diff --git a/variables.tf b/variables.tf
index de8fc93..07eaa35 100644
--- a/variables.tf
+++ b/variables.tf
@@ -9,16 +9,18 @@ variable "sonarqube_config" {
grafana_monitoring_enabled = false
postgresql_password_external = ""
postgresql_external_server_url = ""
+ updateExistingSonarqube = false
}
description = "Specify the configuration settings for Sonarqube, including the hostname, storage options, and custom YAML values."
}
variable "chart_version" {
type = string
- default = "10.6.1"
+ default = "2025.2.0"
description = "Version of the Jenkins chart that will be used to deploy Jenkins application."
}
+
variable "namespace" {
type = string
default = "sonarqube"