├── modules ├── backup │ ├── Chart.yaml │ ├── templates │ │ ├── service_account.yaml │ │ ├── backup-secret.yaml │ │ └── cronjob.yaml │ └── .helmignore ├── restore │ ├── Chart.yaml │ ├── templates │ │ ├── service_account.yaml │ │ ├── restore-secret.yaml │ │ └── job.yaml │ └── .helmignore └── resources │ ├── azure │ ├── outputs.tf │ ├── variables.tf │ ├── main.tf │ └── README.md │ ├── aws │ ├── outputs.tf │ ├── variables.tf │ ├── README.md │ └── main.tf │ └── gcp │ ├── outputs.tf │ ├── variables.tf │ ├── main.tf │ └── README.md ├── examples └── complete │ ├── aws │ ├── output.tf │ ├── provider.tf │ ├── README.md │ ├── helm │ │ └── values.yaml │ └── main.tf │ ├── gcp │ ├── output.tf │ ├── helm │ │ └── values.yaml │ ├── provider.tf │ ├── README.md │ └── main.tf │ └── azure │ ├── outputs.tf │ ├── helm │ └── values.yaml │ ├── provider.tf │ ├── README.md │ └── main.tf ├── .gitignore ├── helm └── values │ ├── restore │ └── values.yaml │ ├── backup │ └── values.yaml │ └── mysqldb │ └── values.yaml ├── .pre-commit-config.yaml ├── output.tf ├── IAM.md ├── .tflint.hcl ├── main.tf ├── variables.tf ├── LICENSE └── README.md /modules/backup/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A helm chart for Backup of mysql and stored in S3 3 | name: mysql-backup 4 | version: 1.0.0 5 | -------------------------------------------------------------------------------- /modules/restore/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A helm chart for restore of mysql and stored in S3 3 | name: mysql-restore 4 | version: 1.0.0 5 | -------------------------------------------------------------------------------- /modules/restore/templates/service_account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: sa-mysql-restore 5 | annotations: 6 | {{ toYaml .Values.annotations | indent 4 }} 7 | -------------------------------------------------------------------------------- /modules/backup/templates/service_account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: sa-mysql-backup 5 | namespace: {{ .Release.Namespace }} 6 | annotations: 7 | {{ toYaml .Values.annotations | indent 4 }} 8 | -------------------------------------------------------------------------------- /modules/backup/templates/backup-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: mysql-bucket-uri 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | data: 8 | MYSQL_BUCKET_URI: {{ .Values.backup.bucket_uri | b64enc | quote }} 9 | -------------------------------------------------------------------------------- /modules/restore/templates/restore-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: mysql-bucket-uri-restore 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | data: 8 | MYSQL_BUCKET_URI: {{ .Values.restore.bucket_uri | b64enc | quote }} 9 | -------------------------------------------------------------------------------- /examples/complete/aws/output.tf: -------------------------------------------------------------------------------- 1 | output "mysql_endpoints" { 2 | value = module.mysql.mysqldb_endpoints 3 | description = "MySQL endpoints in the Kubernetes cluster." 4 | } 5 | 6 | output "mysql_credential" { 7 | value = local.store_password_to_secret_manager ? null : module.mysql.mysqldb_credential 8 | description = "MySQL credentials used for accessing the MySQL database." 9 | } 10 | -------------------------------------------------------------------------------- /examples/complete/gcp/output.tf: -------------------------------------------------------------------------------- 1 | output "mysql_endpoints" { 2 | value = module.mysql.mysqldb_endpoints 3 | description = "MySQL endpoints in the Kubernetes cluster." 4 | } 5 | 6 | output "mysql_credential" { 7 | value = local.store_password_to_secret_manager ? null : module.mysql.mysqldb_credential 8 | description = "MySQL credentials used for accessing the MySQL database." 9 | } 10 | -------------------------------------------------------------------------------- /examples/complete/azure/outputs.tf: -------------------------------------------------------------------------------- 1 | output "mysql_endpoints" { 2 | value = module.mysql.mysqldb_endpoints 3 | description = "MySQL endpoints in the Kubernetes cluster." 4 | } 5 | 6 | output "mysql_credential" { 7 | value = local.store_password_to_secret_manager ? null : module.mysql.mysqldb_credential 8 | description = "MySQL credentials used for accessing the MySQL database." 9 | } 10 | -------------------------------------------------------------------------------- /modules/backup/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /modules/restore/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 2 | *.out 3 | *.lock 4 | *.tfvars 5 | *.pem 6 | *.txt 7 | 8 | # Local .terraform directories 9 | **/.terraform/* 10 | .terraform* 11 | 12 | # .tfstate files 13 | *.tfstate 14 | *.tfstate.* 15 | 16 | # Crash log files 17 | crash.log 18 | crash.*.log 19 | 20 | *.tfvars 21 | *.tfvars.json 22 | 23 | # Ignore override files as they are usually used to override resources locally and so 24 | # are not checked in 25 | override.tf 26 | override.tf.json 27 | *_override.tf 28 | *_override.tf.json 29 | 30 | # Ignore CLI configuration files 31 | .terraformrc 32 | terraform.rc 33 | -------------------------------------------------------------------------------- /helm/values/restore/values.yaml: -------------------------------------------------------------------------------- 1 | restore: 2 | bucket_uri: ${bucket_uri} 3 | file_name: ${file_name} 4 | aws_default_region: ${s3_bucket_region} 5 | 6 | auth: 7 | username: "${custom_user_username}" 8 | 9 | annotations: 10 | ${annotations} 11 | 12 | bucket_provider_type: ${bucket_provider_type} 13 | 14 | affinity: 15 | nodeAffinity: 16 | requiredDuringSchedulingIgnoredDuringExecution: 17 | nodeSelectorTerms: 18 | - matchExpressions: 19 | - key: "Infra-Services" 20 | operator: In 21 | values: 22 | - "true" 23 | 24 | restorejob: 25 | resources: 26 | requests: 27 | memory: 100Mi 28 | cpu: 50m 29 | limits: 30 | memory: 200Mi 31 | cpu: 100m 32 | -------------------------------------------------------------------------------- /examples/complete/azure/helm/values.yaml: -------------------------------------------------------------------------------- 1 | primary: 2 | affinity: 3 | nodeAffinity: 4 | requiredDuringSchedulingIgnoredDuringExecution: 5 | nodeSelectorTerms: 6 | - matchExpressions: 7 | - key: "Addons-Services" 8 | operator: In 9 | values: 10 | - "true" 11 | 12 | secondary: 13 | affinity: 14 | nodeAffinity: 15 | requiredDuringSchedulingIgnoredDuringExecution: 16 | nodeSelectorTerms: 17 | - matchExpressions: 18 | - key: "Addons-Services" 19 | operator: In 20 | values: 21 | - "true" 22 | -------------------------------------------------------------------------------- /examples/complete/gcp/helm/values.yaml: -------------------------------------------------------------------------------- 1 | primary: 2 | affinity: 3 | nodeAffinity: 4 | requiredDuringSchedulingIgnoredDuringExecution: 5 | nodeSelectorTerms: 6 | - matchExpressions: 7 | - key: "Infra-Services" 8 | operator: In 9 | values: 10 | - "true" 11 | 12 | secondary: 13 | affinity: 14 | nodeAffinity: 15 | requiredDuringSchedulingIgnoredDuringExecution: 16 | nodeSelectorTerms: 17 | - matchExpressions: 18 | - key: "Infra-Services" 19 | operator: In 20 | values: 21 | - "true" 22 | -------------------------------------------------------------------------------- /helm/values/backup/values.yaml: -------------------------------------------------------------------------------- 1 | ## Enable Full backup 2 | backup: 3 | bucket_uri: ${bucket_uri} 4 | aws_default_region: ${s3_bucket_region} 5 | cron_for_full_backup: "${cron_for_full_backup}" 6 | database_name: "${mysql_database_name}" 7 | 8 | 9 | annotations: 10 | ${annotations} 11 | 12 | auth: 13 | username: "${custom_user_username}" 14 | 15 | bucket_provider_type: ${bucket_provider_type} 16 | 17 | affinity: 18 | nodeAffinity: 19 | requiredDuringSchedulingIgnoredDuringExecution: 20 | nodeSelectorTerms: 21 | - matchExpressions: 22 | - key: "Infra-Services" 23 | operator: In 24 | values: 25 | - "true" 26 | 27 | backupjob: 28 | resources: 29 | requests: 30 | memory: 100Mi 31 | cpu: 50m 32 | limits: 33 | memory: 200Mi 34 | cpu: 100m 35 | -------------------------------------------------------------------------------- /examples/complete/gcp/provider.tf: -------------------------------------------------------------------------------- 1 | data "google_client_config" "default" {} 2 | 3 | data "google_container_cluster" "primary" { 4 | name = "" 5 | location = "" 6 | project = "" 7 | } 8 | 9 | provider "kubernetes" { 10 | host = "https://${data.google_container_cluster.primary.endpoint}" 11 | token = data.google_client_config.default.access_token 12 | cluster_ca_certificate = base64decode(data.google_container_cluster.primary.master_auth.0.cluster_ca_certificate) 13 | } 14 | 15 | provider "helm" { 16 | kubernetes { 17 | host = "https://${data.google_container_cluster.primary.endpoint}" 18 | token = data.google_client_config.default.access_token 19 | cluster_ca_certificate = base64decode(data.google_container_cluster.primary.master_auth.0.cluster_ca_certificate) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/complete/aws/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = local.region 3 | default_tags { 4 | tags = local.additional_tags 5 | } 6 | } 7 | 8 | data "aws_eks_cluster" "cluster" { 9 | name = "" 10 | } 11 | 12 | data "aws_eks_cluster_auth" "cluster" { 13 | name = "" 14 | } 15 | 16 | provider "kubernetes" { 17 | host = data.aws_eks_cluster.cluster.endpoint 18 | cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority.0.data) 19 | token = data.aws_eks_cluster_auth.cluster.token 20 | } 21 | 22 | provider "helm" { 23 | kubernetes { 24 | host = data.aws_eks_cluster.cluster.endpoint 25 | cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority.0.data) 26 | token = data.aws_eks_cluster_auth.cluster.token 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /modules/resources/azure/outputs.tf: -------------------------------------------------------------------------------- 1 | output "root_password" { 2 | value = var.mysqldb_custom_credentials_enabled ? null : nonsensitive(random_password.mysqldb_root_password[0].result) 3 | description = "Root user's password of mysqldb" 4 | } 5 | 6 | output "metric_exporter_pasword" { 7 | value = var.mysqldb_custom_credentials_enabled ? null : nonsensitive(random_password.mysqldb_exporter_user_password[0].result) 8 | description = "mysqldb_exporter user's password of mysqldb" 9 | } 10 | 11 | output "mysqldb_replication_user_password" { 12 | value = var.mysqldb_custom_credentials_enabled ? null : nonsensitive(random_password.mysqldb_replication_user_password[0].result) 13 | description = "replicator user's password of mysqldb" 14 | } 15 | 16 | output "custom_user_password" { 17 | value = var.mysqldb_custom_credentials_enabled ? null : nonsensitive(random_password.mysqldb_custom_user_password[0].result) 18 | description = "custom user's password of mysqldb" 19 | } 20 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v4.1.0 4 | hooks: 5 | - id: trailing-whitespace 6 | args: ['--markdown-linebreak-ext=md'] 7 | - id: end-of-file-fixer 8 | - id: check-merge-conflict 9 | - id: detect-private-key 10 | - id: detect-aws-credentials 11 | args: ['--allow-missing-credentials'] 12 | - repo: https://github.com/antonbabenko/pre-commit-terraform 13 | rev: v1.77.0 14 | hooks: 15 | - id: terraform_fmt 16 | - id: terraform_docs 17 | args: 18 | - '--args=--lockfile=false' 19 | - --hook-config=--add-to-existing-file=true 20 | - --hook-config=--create-file-if-not-exist=true 21 | 22 | - id: terraform_tflint 23 | args: 24 | - --args=--config=.tflint.hcl 25 | - id: terraform_tfsec 26 | files: ^examples/ # only scan `examples/*` which are the implementation 27 | args: 28 | - --args=--config-file=__GIT_WORKING_DIR__/tfsec.yaml 29 | - --args=--concise-output 30 | -------------------------------------------------------------------------------- /modules/resources/aws/outputs.tf: -------------------------------------------------------------------------------- 1 | output "iam_role_arn_backup" { 2 | value = aws_iam_role.mysql_backup_role.arn 3 | description = "IAM role arn for mysql backup" 4 | } 5 | 6 | output "iam_role_arn_restore" { 7 | value = aws_iam_role.mysql_restore_role.arn 8 | description = "IAM role arn for mysql restore" 9 | } 10 | 11 | output "root_password" { 12 | value = var.mysqldb_custom_credentials_enabled ? null : nonsensitive(random_password.mysqldb_root_password[0].result) 13 | description = "Root user's password of mysqldb" 14 | } 15 | 16 | output "metric_exporter_pasword" { 17 | value = var.mysqldb_custom_credentials_enabled ? null : nonsensitive(random_password.mysqldb_exporter_user_password[0].result) 18 | description = "mysqldb_exporter user's password of mysqldb" 19 | } 20 | 21 | output "mysqldb_replication_user_password" { 22 | value = var.mysqldb_custom_credentials_enabled ? null : nonsensitive(random_password.mysqldb_replication_user_password[0].result) 23 | description = "replicator user's password of mysqldb" 24 | } 25 | 26 | output "custom_user_password" { 27 | value = var.mysqldb_custom_credentials_enabled ? null : nonsensitive(random_password.mysqldb_custom_user_password[0].result) 28 | description = "custom user's password of mysqldb" 29 | } 30 | -------------------------------------------------------------------------------- /modules/resources/gcp/outputs.tf: -------------------------------------------------------------------------------- 1 | output "service_account_backup" { 2 | value = google_service_account.mysql_backup.email 3 | description = "Google Cloud Service Account name for backup" 4 | } 5 | 6 | output "service_account_restore" { 7 | value = google_service_account.mysql_restore.email 8 | description = "Google Cloud Service Account name for restore" 9 | } 10 | 11 | output "root_password" { 12 | value = var.mysqldb_custom_credentials_enabled ? null : nonsensitive(random_password.mysqldb_root_password[0].result) 13 | description = "Root user's password of mysqldb" 14 | } 15 | 16 | output "metric_exporter_pasword" { 17 | value = var.mysqldb_custom_credentials_enabled ? null : nonsensitive(random_password.mysqldb_exporter_user_password[0].result) 18 | description = "mysqldb_exporter user's password of mysqldb" 19 | } 20 | 21 | output "mysqldb_replication_user_password" { 22 | value = var.mysqldb_custom_credentials_enabled ? null : nonsensitive(random_password.mysqldb_replication_user_password[0].result) 23 | description = "replicator user's password of mysqldb" 24 | } 25 | 26 | output "custom_user_password" { 27 | value = var.mysqldb_custom_credentials_enabled ? null : nonsensitive(random_password.mysqldb_custom_user_password[0].result) 28 | description = "custom user's password of mysqldb" 29 | } 30 | -------------------------------------------------------------------------------- /examples/complete/azure/provider.tf: -------------------------------------------------------------------------------- 1 | provider "azurerm" { 2 | features {} 3 | } 4 | 5 | data "azurerm_kubernetes_cluster" "primary" { 6 | name = "" 7 | resource_group_name = "" 8 | } 9 | 10 | provider "kubernetes" { 11 | host = data.azurerm_kubernetes_cluster.primary.kube_config.0.host 12 | username = data.azurerm_kubernetes_cluster.primary.kube_config.0.username 13 | password = data.azurerm_kubernetes_cluster.primary.kube_config.0.password 14 | client_certificate = base64decode(data.azurerm_kubernetes_cluster.primary.kube_config.0.client_certificate) 15 | client_key = base64decode(data.azurerm_kubernetes_cluster.primary.kube_config.0.client_key) 16 | cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.primary.kube_config.0.cluster_ca_certificate) 17 | } 18 | 19 | provider "helm" { 20 | kubernetes { 21 | host = data.azurerm_kubernetes_cluster.primary.kube_config.0.host 22 | client_key = base64decode(data.azurerm_kubernetes_cluster.primary.kube_config.0.client_key) 23 | client_certificate = base64decode(data.azurerm_kubernetes_cluster.primary.kube_config.0.client_certificate) 24 | cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.primary.kube_config.0.cluster_ca_certificate) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /modules/restore/templates/job.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: restore 5 | spec: 6 | template: 7 | spec: 8 | affinity: 9 | {{- toYaml .Values.affinity | nindent 8 }} 10 | serviceAccountName: sa-mysql-restore 11 | containers: 12 | - name: restore-mysqldb 13 | image: saturnops/mysqldb-restore:v5 14 | imagePullPolicy: Always 15 | env: 16 | - name: MYSQL_HOST 17 | value: mysqldb-primary-headless.{{ .Release.Namespace }}.svc.cluster.local 18 | - name: MYSQL_USER 19 | value: {{ .Values.auth.username }} 20 | - name: MYSQL_PASSWORD 21 | valueFrom: 22 | secretKeyRef: 23 | name: mysqldb 24 | key: mysql-root-password 25 | - name: MYSQL_BUCKET_RESTORE_URI 26 | valueFrom: 27 | secretKeyRef: 28 | name: mysql-bucket-uri-restore 29 | key: MYSQL_BUCKET_URI 30 | - name: RESTORE_FILE_NAME 31 | value: {{ .Values.restore.file_name}} 32 | - name: RESTORE_FROM 33 | value: {{ .Values.bucket_provider_type}} 34 | - name: AWS_DEFAULT_REGION 35 | value: {{ .Values.restore.aws_default_region}} 36 | resources: 37 | {{- toYaml .Values.restorejob.resources | nindent 14 }} 38 | restartPolicy: Never 39 | backoffLimit: 4 40 | -------------------------------------------------------------------------------- /examples/complete/aws/README.md: -------------------------------------------------------------------------------- 1 | ## Mysql Example 2 | 3 | 4 |
5 | This example will be very useful for users who are new to a module and want to quickly learn how to use it. By reviewing the examples, users can gain a better understanding of how the module works, what features it supports, and how to customize it to their specific needs. 6 | 7 | 8 | ## Requirements 9 | 10 | No requirements. 11 | 12 | ## Providers 13 | 14 | | Name | Version | 15 | |------|---------| 16 | | [aws](#provider\_aws) | n/a | 17 | 18 | ## Modules 19 | 20 | | Name | Source | Version | 21 | |------|--------|---------| 22 | | [aws](#module\_aws) | saturnops/mysql/kubernetes//modules/resources/aws | n/a | 23 | | [mysql](#module\_mysql) | saturnops/mysql/kubernetes | n/a | 24 | 25 | ## Resources 26 | 27 | | Name | Type | 28 | |------|------| 29 | | [aws_eks_cluster.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster) | data source | 30 | | [aws_eks_cluster_auth.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster_auth) | data source | 31 | 32 | ## Inputs 33 | 34 | No inputs. 35 | 36 | ## Outputs 37 | 38 | | Name | Description | 39 | |------|-------------| 40 | | [mysql\_credential](#output\_mysql\_credential) | MySQL credentials used for accessing the MySQL database. | 41 | | [mysql\_endpoints](#output\_mysql\_endpoints) | MySQL endpoints in the Kubernetes cluster. | 42 | 43 | -------------------------------------------------------------------------------- /examples/complete/gcp/README.md: -------------------------------------------------------------------------------- 1 | ## Mysql Example 2 | 3 | 4 |
5 | This example will be very useful for users who are new to a module and want to quickly learn how to use it. By reviewing the examples, users can gain a better understanding of how the module works, what features it supports, and how to customize it to their specific needs. 6 | 7 | 8 | ## Requirements 9 | 10 | No requirements. 11 | 12 | ## Providers 13 | 14 | | Name | Version | 15 | |------|---------| 16 | | [google](#provider\_google) | n/a | 17 | 18 | ## Modules 19 | 20 | | Name | Source | Version | 21 | |------|--------|---------| 22 | | [gcp](#module\_gcp) | saturnops/mysql/kubernetes//modules/resources/gcp | n/a | 23 | | [mysql](#module\_mysql) | saturnops/mysql/kubernetes | n/a | 24 | 25 | ## Resources 26 | 27 | | Name | Type | 28 | |------|------| 29 | | [google_client_config.default](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/client_config) | data source | 30 | | [google_container_cluster.primary](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/container_cluster) | data source | 31 | 32 | ## Inputs 33 | 34 | No inputs. 35 | 36 | ## Outputs 37 | 38 | | Name | Description | 39 | |------|-------------| 40 | | [mysql\_credential](#output\_mysql\_credential) | MySQL credentials used for accessing the MySQL database. | 41 | | [mysql\_endpoints](#output\_mysql\_endpoints) | MySQL endpoints in the Kubernetes cluster. | 42 | 43 | -------------------------------------------------------------------------------- /modules/backup/templates/cronjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: CronJob 3 | metadata: 4 | name: backup-mysqldb 5 | spec: 6 | schedule: {{ .Values.backup.cron_for_full_backup | quote }} 7 | concurrencyPolicy: Forbid 8 | suspend: false 9 | successfulJobsHistoryLimit: 3 10 | failedJobsHistoryLimit: 1 11 | 12 | jobTemplate: 13 | spec: 14 | template: 15 | spec: 16 | affinity: 17 | {{- toYaml .Values.affinity | nindent 12 }} 18 | restartPolicy: OnFailure 19 | imagePullSecrets: 20 | - name: regcred 21 | serviceAccountName: sa-mysql-backup 22 | containers: 23 | - name: backup-mysqldb 24 | image: saturnops/mysqldb-backup:v5 25 | imagePullPolicy: Always 26 | env: 27 | - name: MYSQL_HOST 28 | value: mysqldb-secondary-headless.{{ .Release.Namespace }}.svc.cluster.local 29 | - name: MYSQL_USER 30 | value: {{ .Values.auth.username }} 31 | - name: DATABASES 32 | value: {{ .Values.backup.database_name }} 33 | - name: MYSQL_PASSWORD 34 | valueFrom: 35 | secretKeyRef: 36 | name: mysqldb 37 | key: mysql-root-password 38 | - name: MYSQL_BUCKET_URI 39 | valueFrom: 40 | secretKeyRef: 41 | name: mysql-bucket-uri 42 | key: MYSQL_BUCKET_URI 43 | - name: BUCKET_PROVIDER 44 | value: "s3" 45 | - name: AWS_DEFAULT_REGION 46 | value: {{ .Values.backup.aws_default_region }} 47 | resources: 48 | {{- toYaml .Values.backupjob.resources | nindent 14 }} 49 | -------------------------------------------------------------------------------- /output.tf: -------------------------------------------------------------------------------- 1 | output "mysqldb_endpoints" { 2 | description = "MySQL endpoints in the Kubernetes cluster." 3 | value = { 4 | mysqlport = "3306", 5 | mysql_primary_endpoint = "mysqldb-primary.${var.namespace}.svc.cluster.local", 6 | mysql_primary_headless_endpoint = "mysqldb-primary-headless.${var.namespace}.svc.cluster.local", 7 | mysql_secondary_endpoint = "mysqldb-secondary.${var.namespace}.svc.cluster.local", 8 | mysql_secondary_headless_endpoint = "mysqldb-secondary-headless.${var.namespace}.svc.cluster.local" 9 | } 10 | } 11 | 12 | output "mysqldb_credential" { 13 | description = "MySQL credentials used for accessing the MySQL database." 14 | value = var.mysqldb_config.store_password_to_secret_manager ? null : { 15 | root_user = var.mysqldb_custom_credentials_enabled ? var.mysqldb_custom_credentials_config.root_user : "root", 16 | root_password = var.mysqldb_custom_credentials_enabled ? var.mysqldb_custom_credentials_config.root_password : var.root_password, 17 | custom_username = var.mysqldb_custom_credentials_enabled ? var.mysqldb_custom_credentials_config.custom_username : var.mysqldb_config.custom_user_username, 18 | custom_user_password = var.mysqldb_custom_credentials_enabled ? var.mysqldb_custom_credentials_config.custom_user_password : var.custom_user_password, 19 | replication_user = var.mysqldb_custom_credentials_enabled ? var.mysqldb_custom_credentials_config.replication_user : "replicator", 20 | replication_password = var.mysqldb_custom_credentials_enabled ? var.mysqldb_custom_credentials_config.replication_password : var.mysqldb_replication_user_password, 21 | exporter_user = var.mysqldb_custom_credentials_enabled ? var.mysqldb_custom_credentials_config.exporter_user : "mysqld_exporter", 22 | exporter_password = var.mysqldb_custom_credentials_enabled ? var.mysqldb_custom_credentials_config.exporter_password : var.metric_exporter_pasword 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /modules/resources/aws/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | description = "Name identifier for module to be added as suffix to resources" 3 | type = string 4 | default = "test" 5 | } 6 | 7 | variable "environment" { 8 | description = "Environment in which the infrastructure is being deployed (e.g., production, staging, development)" 9 | type = string 10 | default = "test" 11 | } 12 | 13 | variable "mysqldb_custom_credentials_enabled" { 14 | type = bool 15 | default = false 16 | description = "Specifies whether to enable custom credentials for MySQL database." 17 | } 18 | 19 | variable "mysqldb_custom_credentials_config" { 20 | type = any 21 | default = { 22 | root_user = "" 23 | root_password = "" 24 | custom_username = "" 25 | custom_user_password = "" 26 | replication_user = "" 27 | replication_password = "" 28 | exporter_user = "" 29 | exporter_password = "" 30 | } 31 | description = "Specify the configuration settings for MySQL to pass custom credentials during creation" 32 | } 33 | 34 | variable "recovery_window_aws_secret" { 35 | type = number 36 | default = 0 37 | description = "Number of days that AWS Secrets Manager will wait before deleting a secret. This value can be set to 0 to force immediate deletion, or to a value between 7 and 30 days to allow for recovery." 38 | } 39 | 40 | variable "cluster_name" { 41 | type = string 42 | default = "" 43 | description = "Specifies the name of the EKS cluster to deploy the MySQL application on." 44 | } 45 | 46 | variable "namespace" { 47 | type = string 48 | default = "mysqldb" 49 | description = "Name of the Kubernetes namespace where the MYSQL deployment will be deployed." 50 | } 51 | 52 | variable "store_password_to_secret_manager" { 53 | type = bool 54 | default = false 55 | description = "Specifies whether to store the credentials in GCP secret manager." 56 | } 57 | 58 | variable "custom_user_username" { 59 | type = string 60 | default = "" 61 | } 62 | -------------------------------------------------------------------------------- /modules/resources/azure/variables.tf: -------------------------------------------------------------------------------- 1 | variable "resource_group_name" { 2 | description = "Azure Resource Group name" 3 | type = string 4 | default = "" 5 | } 6 | 7 | variable "storage_resource_group_name" { 8 | description = "Azure Storage account Resource Group name" 9 | type = string 10 | default = "" 11 | } 12 | 13 | variable "resource_group_location" { 14 | description = "Azure region" 15 | type = string 16 | default = "East US" 17 | } 18 | 19 | variable "name" { 20 | description = "Name identifier for module to be added as suffix to resources" 21 | type = string 22 | default = "test" 23 | } 24 | 25 | variable "cluster_name" { 26 | description = "Name of the Azure AKS cluster" 27 | type = string 28 | default = "" 29 | } 30 | 31 | variable "environment" { 32 | description = "Environment in which the infrastructure is being deployed (e.g., production, staging, development)" 33 | type = string 34 | default = "test" 35 | } 36 | 37 | variable "mysqldb_custom_credentials_enabled" { 38 | type = bool 39 | default = false 40 | description = "Specifies whether to enable custom credentials for MySQL database." 41 | } 42 | 43 | variable "mysqldb_custom_credentials_config" { 44 | type = any 45 | default = { 46 | root_user = "" 47 | root_password = "" 48 | custom_username = "" 49 | custom_user_password = "" 50 | replication_user = "" 51 | replication_password = "" 52 | exporter_user = "" 53 | exporter_password = "" 54 | } 55 | description = "Specify the configuration settings for MySQL to pass custom credentials during creation" 56 | } 57 | 58 | variable "store_password_to_secret_manager" { 59 | type = bool 60 | default = false 61 | description = "Specifies whether to store the credentials in GCP secret manager." 62 | } 63 | 64 | variable "custom_user_username" { 65 | type = string 66 | default = "" 67 | } 68 | 69 | variable "storage_account_name" { 70 | type = string 71 | default = "" 72 | } 73 | -------------------------------------------------------------------------------- /modules/resources/gcp/variables.tf: -------------------------------------------------------------------------------- 1 | variable "project_id" { 2 | description = "Google Cloud project ID" 3 | type = string 4 | default = "" 5 | } 6 | 7 | variable "gcp_gsa_backup_name" { 8 | description = "Google Cloud Service Account name for backup" 9 | type = string 10 | default = "mysql-backup" 11 | } 12 | 13 | variable "gcp_ksa_backup_name" { 14 | description = "Google Kubernetes Service Account name for backup" 15 | type = string 16 | default = "sa-mysql-backup" 17 | } 18 | 19 | variable "gcp_gsa_restore_name" { 20 | description = "Google Cloud Service Account name for restore" 21 | type = string 22 | default = "mysql-restore" 23 | } 24 | 25 | variable "gcp_ksa_restore_name" { 26 | description = "Google Kubernetes Service Account name for restore" 27 | type = string 28 | default = "sa-mysql-restore" 29 | } 30 | 31 | variable "name" { 32 | description = "Name identifier for module to be added as suffix to resources" 33 | type = string 34 | default = "test" 35 | } 36 | 37 | variable "environment" { 38 | description = "Environment in which the infrastructure is being deployed (e.g., production, staging, development)" 39 | type = string 40 | default = "test" 41 | } 42 | 43 | variable "mysqldb_custom_credentials_enabled" { 44 | type = bool 45 | default = false 46 | description = "Specifies whether to enable custom credentials for MySQL database." 47 | } 48 | 49 | variable "mysqldb_custom_credentials_config" { 50 | type = any 51 | default = { 52 | root_user = "" 53 | root_password = "" 54 | custom_username = "" 55 | custom_user_password = "" 56 | replication_user = "" 57 | replication_password = "" 58 | exporter_user = "" 59 | exporter_password = "" 60 | } 61 | description = "Specify the configuration settings for MySQL to pass custom credentials during creation" 62 | } 63 | 64 | variable "store_password_to_secret_manager" { 65 | type = bool 66 | default = false 67 | description = "Specifies whether to store the credentials in GCP secret manager." 68 | } 69 | 70 | variable "custom_user_username" { 71 | type = string 72 | default = "" 73 | } 74 | -------------------------------------------------------------------------------- /IAM.md: -------------------------------------------------------------------------------- 1 | ## AWS IAM Permission 2 | 3 | The Policy required to deploy this module: 4 | ```hcl 5 | { 6 | "Version": "2012-10-17", 7 | "Statement": [ 8 | { 9 | "Sid": "VisualEditor0", 10 | "Effect": "Allow", 11 | "Action": [ 12 | "eks:DescribeCluster" 13 | ], 14 | "Resource": [ 15 | "*" 16 | ] 17 | }, 18 | { 19 | "Sid": "VisualEditor1", 20 | "Effect": "Allow", 21 | "Action": [ 22 | "iam:GetRole", 23 | "iam:CreateRole", 24 | "iam:DeleteRole", 25 | "iam:GetRolePolicy", 26 | "iam:PutRolePolicy", 27 | "iam:ListRolePolicies", 28 | "iam:ListAttachedRolePolicies", 29 | "iam:ListInstanceProfilesForRole" 30 | ], 31 | "Resource": [ 32 | "*" 33 | ] 34 | }, 35 | { 36 | "Sid": "VisualEditor2", 37 | "Effect": "Allow", 38 | "Action": [ 39 | "secretsmanager:CreateSecret", 40 | "secretsmanager:DeleteSecret", 41 | "secretsmanager:DescribeSecret", 42 | "secretsmanager:GetSecretValue", 43 | "secretsmanager:PutSecretValue", 44 | "secretsmanager:GetResourcePolicy" 45 | ], 46 | "Resource": [ 47 | "*" 48 | ] 49 | } 50 | ] 51 | } 52 | ``` 53 | ## Azure Role Permissions 54 | 55 | ```hcl 56 | permissions { 57 | actions = [ 58 | "Microsoft.Authorization/roleAssignments/delete", 59 | "Microsoft.Authorization/roleAssignments/read", 60 | "Microsoft.Authorization/roleAssignments/write", 61 | "Microsoft.KeyVault/locations/deletedVaults/read", 62 | "Microsoft.KeyVault/vaults/delete", 63 | "Microsoft.KeyVault/vaults/read", 64 | "Microsoft.KeyVault/vaults/write", 65 | "Microsoft.ManagedIdentity/userAssignedIdentities/delete", 66 | "Microsoft.ManagedIdentity/userAssignedIdentities/read", 67 | "Microsoft.ManagedIdentity/userAssignedIdentities/write", 68 | "Microsoft.Resources/subscriptions/providers/read", 69 | "Microsoft.Resources/subscriptions/resourcegroups/read"] 70 | not_actions = [] 71 | } 72 | ``` 73 | 74 | ## GCP IAM Permissions 75 | 76 | ```hcl 77 | permissions = [ 78 | "iam.serviceAccounts.create", 79 | "iam.serviceAccounts.delete", 80 | "iam.serviceAccounts.get", 81 | "iam.serviceAccounts.update", 82 | "resourcemanager.projects.getIamPolicy", 83 | "resourcemanager.projects.setIamPolicy" 84 | ] 85 | ``` 86 | -------------------------------------------------------------------------------- /.tflint.hcl: -------------------------------------------------------------------------------- 1 | plugin "aws" { 2 | enabled = true 3 | version = "0.21.1" 4 | source = "github.com/terraform-linters/tflint-ruleset-aws" 5 | } 6 | 7 | config { 8 | #Enables module inspection 9 | module = false 10 | force = false 11 | } 12 | 13 | # Required that all AWS resources have specified tags. 14 | rule "aws_resource_missing_tags" { 15 | enabled = true 16 | tags = [ 17 | "Name", 18 | "Environment", 19 | ] 20 | } 21 | 22 | # Disallow deprecated (0.11-style) interpolation 23 | rule "terraform_deprecated_interpolation" { 24 | enabled = true 25 | } 26 | 27 | # Disallow legacy dot index syntax. 28 | rule "terraform_deprecated_index" { 29 | enabled = true 30 | } 31 | 32 | # Disallow variables, data sources, and locals that are declared but never used. 33 | rule "terraform_unused_declarations" { 34 | enabled = true 35 | } 36 | 37 | # Disallow // comments in favor of #. 38 | rule "terraform_comment_syntax" { 39 | enabled = false 40 | } 41 | 42 | # Disallow output declarations without description. 43 | rule "terraform_documented_outputs" { 44 | enabled = true 45 | } 46 | 47 | # Disallow variable declarations without description. 48 | rule "terraform_documented_variables" { 49 | enabled = true 50 | } 51 | 52 | # Disallow variable declarations without type. 53 | rule "terraform_typed_variables" { 54 | enabled = true 55 | } 56 | 57 | # Disallow specifying a git or mercurial repository as a module source without pinning to a version. 58 | rule "terraform_module_pinned_source" { 59 | enabled = true 60 | } 61 | 62 | # Enforces naming conventions 63 | rule "terraform_naming_convention" { 64 | enabled = true 65 | 66 | #Require specific naming structure 67 | variable { 68 | format = "snake_case" 69 | } 70 | 71 | locals { 72 | format = "snake_case" 73 | } 74 | 75 | output { 76 | format = "snake_case" 77 | } 78 | 79 | #Allow any format 80 | resource { 81 | format = "none" 82 | } 83 | 84 | module { 85 | format = "none" 86 | } 87 | 88 | data { 89 | format = "none" 90 | } 91 | 92 | } 93 | 94 | # Disallow terraform declarations without require_version. 95 | rule "terraform_required_version" { 96 | enabled = true 97 | } 98 | 99 | # Require that all providers have version constraints through required_providers. 100 | rule "terraform_required_providers" { 101 | enabled = true 102 | } 103 | 104 | # Ensure that a module complies with the Terraform Standard Module Structure 105 | rule "terraform_standard_module_structure" { 106 | enabled = true 107 | } 108 | 109 | # terraform.workspace should not be used with a "remote" backend with remote execution. 110 | rule "terraform_workspace_remote" { 111 | enabled = true 112 | } 113 | -------------------------------------------------------------------------------- /examples/complete/azure/README.md: -------------------------------------------------------------------------------- 1 | ## Mysql Example 2 | 3 | 4 |
5 | This example will be very useful for users who are new to a module and want to quickly learn how to use it. By reviewing the examples, users can gain a better understanding of how the module works, what features it supports, and how to customize it to their specific needs. 6 | 7 | ## Requirements 8 | 9 | No requirements. 10 | 11 | ## Providers 12 | 13 | | Name | Version | 14 | |------|---------| 15 | | [azurerm](#provider\_azurerm) | 3.70.0 | 16 | 17 | ## Modules 18 | 19 | | Name | Source | Version | 20 | |------|--------|---------| 21 | | [azure](#module\_azure) | saturnops/mysql/kubernetes//provider/azure | n/a | 22 | | [mysql](#module\_mysql) | saturnops/mysql/kubernetes | n/a | 23 | 24 | ## Resources 25 | 26 | | Name | Type | 27 | |------|------| 28 | | [azurerm_kubernetes_cluster.primary](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/kubernetes_cluster) | data source | 29 | 30 | ## Inputs 31 | 32 | No inputs. 33 | 34 | ## Outputs 35 | 36 | | Name | Description | 37 | |------|-------------| 38 | | [mysql\_credential](#output\_mysql\_credential) | MySQL credentials used for accessing the MySQL database. | 39 | | [mysql\_endpoints](#output\_mysql\_endpoints) | MySQL endpoints in the Kubernetes cluster. | 40 | 41 | ## Requirements 42 | 43 | No requirements. 44 | 45 | ## Providers 46 | 47 | | Name | Version | 48 | |------|---------| 49 | | [azurerm](#provider\_azurerm) | n/a | 50 | 51 | ## Modules 52 | 53 | | Name | Source | Version | 54 | |------|--------|---------| 55 | | [azure](#module\_azure) | saturnops/mysql/kubernetes//modules/resources/azure | n/a | 56 | | [mysql](#module\_mysql) | saturnops/mysql/kubernetes | n/a | 57 | 58 | ## Resources 59 | 60 | | Name | Type | 61 | |------|------| 62 | | [azurerm_kubernetes_cluster.primary](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/kubernetes_cluster) | data source | 63 | 64 | ## Inputs 65 | 66 | No inputs. 67 | 68 | ## Outputs 69 | 70 | | Name | Description | 71 | |------|-------------| 72 | | [mysql\_credential](#output\_mysql\_credential) | MySQL credentials used for accessing the MySQL database. | 73 | | [mysql\_endpoints](#output\_mysql\_endpoints) | MySQL endpoints in the Kubernetes cluster. | 74 | 75 | -------------------------------------------------------------------------------- /examples/complete/aws/helm/values.yaml: -------------------------------------------------------------------------------- 1 | primary: 2 | affinity: 3 | nodeAffinity: 4 | requiredDuringSchedulingIgnoredDuringExecution: 5 | nodeSelectorTerms: 6 | - matchExpressions: 7 | - key: "Infra-Services" 8 | operator: In 9 | values: 10 | - "true" 11 | resources: 12 | limits: 13 | cpu: 350m 14 | memory: 1Gi 15 | requests: 16 | cpu: 200m 17 | memory: 700Mi 18 | 19 | sidecars: 20 | - name: slow-log 21 | image: busybox:1.28 22 | args: [/bin/sh, -c, 'tail -n+1 -F /bitnami/mysql/slow-log.log'] 23 | volumeMounts: 24 | - name: data 25 | mountPath: /bitnami/mysql 26 | resources: 27 | limits: 28 | cpu: 100m 29 | memory: 256Mi 30 | requests: 31 | cpu: 50m 32 | memory: 128Mi 33 | 34 | secondary: 35 | affinity: 36 | nodeAffinity: 37 | requiredDuringSchedulingIgnoredDuringExecution: 38 | nodeSelectorTerms: 39 | - matchExpressions: 40 | - key: "Infra-Services" 41 | operator: In 42 | values: 43 | - "true" 44 | 45 | resources: 46 | limits: 47 | cpu: 350m 48 | memory: 1Gi 49 | requests: 50 | cpu: 200m 51 | memory: 700Mi 52 | 53 | sidecars: 54 | - name: slow-log 55 | image: busybox:1.28 56 | args: [/bin/sh, -c, 'tail -n+1 -F /bitnami/mysql/slow-log.log'] 57 | volumeMounts: 58 | - name: data 59 | mountPath: /bitnami/mysql 60 | resources: 61 | limits: 62 | cpu: 100m 63 | memory: 256Mi 64 | requests: 65 | cpu: 50m 66 | memory: 128Mi 67 | 68 | metrics: 69 | resources: 70 | limits: 71 | cpu: 200m 72 | memory: 500Mi 73 | requests: 74 | cpu: 10m 75 | memory: 50Mi 76 | 77 | 78 | affinity: 79 | nodeAffinity: 80 | requiredDuringSchedulingIgnoredDuringExecution: 81 | nodeSelectorTerms: 82 | - matchExpressions: 83 | - key: "Infra-Services" 84 | operator: In 85 | values: 86 | - "true" 87 | backupjob: 88 | resources: 89 | requests: 90 | memory: 250Mi 91 | cpu: 100m 92 | limits: 93 | memory: 500Mi 94 | cpu: 200m 95 | 96 | restorejob: 97 | resources: 98 | requests: 99 | memory: 250Mi 100 | cpu: 100m 101 | limits: 102 | memory: 500Mi 103 | cpu: 200m -------------------------------------------------------------------------------- /examples/complete/gcp/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | name = "mysql" 3 | region = "us-east-2" 4 | environment = "prod" 5 | additional_tags = { 6 | Owner = "organization_name" 7 | Expires = "Never" 8 | Department = "Engineering" 9 | } 10 | create_namespace = true 11 | namespace = "mysql" 12 | store_password_to_secret_manager = true 13 | mysqldb_custom_credentials_enabled = false 14 | mysqldb_custom_credentials_config = { 15 | root_user = "root" 16 | root_password = "RJDRIFsYC8ZS1WQuV0ps" 17 | custom_username = "admin" 18 | custom_user_password = "NCPFUKEMd7rrWuvMAa73" 19 | replication_user = "replicator" 20 | replication_password = "nvAHhm1uGQNYWVw6ZyAH" 21 | exporter_user = "mysqld_exporter" 22 | exporter_password = "ZawhvpueAehRdKFlbjaq" 23 | } 24 | custom_user_username = "custom" 25 | } 26 | 27 | module "gcp" { 28 | source = "saturnops/mysql/kubernetes//modules/resources/gcp" 29 | project_id = "fresh-sanctuary-387476" #for gcp 30 | environment = local.environment 31 | name = local.name 32 | store_password_to_secret_manager = local.store_password_to_secret_manager 33 | mysqldb_custom_credentials_enabled = local.mysqldb_custom_credentials_enabled 34 | mysqldb_custom_credentials_config = local.mysqldb_custom_credentials_config 35 | custom_user_username = local.mysqldb_custom_credentials_enabled ? "" : local.custom_user_username 36 | } 37 | 38 | module "mysql" { 39 | source = "saturnops/mysql/kubernetes" 40 | create_namespace = local.create_namespace 41 | namespace = local.namespace 42 | mysqldb_config = { 43 | name = local.name 44 | values_yaml = file("./helm/values.yaml") 45 | environment = local.environment 46 | app_version = "8.0.29-debian-11-r9" 47 | architecture = "replication" 48 | custom_database = "test_db" 49 | storage_class_name = "standard" 50 | custom_user_username = local.mysqldb_custom_credentials_enabled ? "" : local.custom_user_username 51 | primary_db_volume_size = "10Gi" 52 | secondary_db_volume_size = "10Gi" 53 | secondary_db_replica_count = 2 54 | store_password_to_secret_manager = local.store_password_to_secret_manager 55 | } 56 | mysqldb_custom_credentials_enabled = local.mysqldb_custom_credentials_enabled 57 | mysqldb_custom_credentials_config = local.mysqldb_custom_credentials_config 58 | root_password = local.mysqldb_custom_credentials_enabled ? "" : module.gcp.root_password 59 | metric_exporter_pasword = local.mysqldb_custom_credentials_enabled ? "" : module.gcp.metric_exporter_pasword 60 | mysqldb_replication_user_password = local.mysqldb_custom_credentials_enabled ? "" : module.gcp.mysqldb_replication_user_password 61 | custom_user_password = local.mysqldb_custom_credentials_enabled ? "" : module.gcp.custom_user_password 62 | bucket_provider_type = "gcs" 63 | service_account_backup = module.gcp.service_account_backup 64 | service_account_restore = module.gcp.service_account_restore 65 | mysqldb_backup_enabled = true 66 | mysqldb_backup_config = { 67 | bucket_uri = "gs://mysql-backup-skaf" 68 | s3_bucket_region = "" 69 | cron_for_full_backup = "*/5 * * * *" 70 | } 71 | mysqldb_restore_enabled = true 72 | mysqldb_restore_config = { 73 | bucket_uri = "gs://mysql-backup-skaf/mysqldump_20230710_120501.zip" 74 | file_name = "mysqldump_20230710_120501.zip" 75 | s3_bucket_region = "" 76 | } 77 | mysqldb_exporter_enabled = true 78 | } 79 | -------------------------------------------------------------------------------- /examples/complete/aws/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | name = "mysql" 3 | region = "us-east-2" 4 | environment = "prod" 5 | additional_tags = { 6 | Owner = "organization_name" 7 | Expires = "Never" 8 | Department = "Engineering" 9 | } 10 | create_namespace = false 11 | namespace = "mysql" 12 | store_password_to_secret_manager = false 13 | mysqldb_custom_credentials_enabled = true 14 | mysqldb_custom_credentials_config = { 15 | root_user = "root" 16 | root_password = "RJDRIFsYC8ZS1WQuV0ps" 17 | custom_username = "admin" 18 | custom_user_password = "NCPFUKEMd7rrWuvMAa73" 19 | replication_user = "replicator" 20 | replication_password = "nvAHhm1uGQNYWVw6ZyAH" 21 | exporter_user = "mysqld_exporter" 22 | exporter_password = "ZawhvpueAehRdKFlbjaq" 23 | } 24 | custom_user_username = "custom" 25 | } 26 | 27 | module "aws" { 28 | source = "saturnops/mysql/kubernetes//modules/resources/aws" 29 | cluster_name = "cluster-name" 30 | environment = local.environment 31 | name = local.name 32 | namespace = local.namespace 33 | store_password_to_secret_manager = local.store_password_to_secret_manager 34 | mysqldb_custom_credentials_enabled = local.mysqldb_custom_credentials_enabled 35 | mysqldb_custom_credentials_config = local.mysqldb_custom_credentials_config 36 | custom_user_username = local.mysqldb_custom_credentials_enabled ? "" : local.custom_user_username 37 | } 38 | 39 | module "mysql" { 40 | source = "saturnops/mysql/kubernetes" 41 | create_namespace = local.create_namespace 42 | namespace = local.namespace 43 | mysqldb_config = { 44 | name = local.name 45 | values_yaml = file("./helm/values.yaml") 46 | app_version = "8.0.29-debian-11-r9" 47 | environment = local.environment 48 | architecture = "replication" 49 | custom_database = "test_db" 50 | storage_class_name = "gp2" 51 | custom_user_username = local.mysqldb_custom_credentials_enabled ? "" : local.custom_user_username 52 | primary_db_volume_size = "10Gi" 53 | secondary_db_volume_size = "10Gi" 54 | secondary_db_replica_count = 2 55 | store_password_to_secret_manager = local.store_password_to_secret_manager 56 | } 57 | mysqldb_custom_credentials_enabled = local.mysqldb_custom_credentials_enabled 58 | mysqldb_custom_credentials_config = local.mysqldb_custom_credentials_config 59 | root_password = local.mysqldb_custom_credentials_enabled ? "" : module.aws.root_password 60 | metric_exporter_pasword = local.mysqldb_custom_credentials_enabled ? "" : module.aws.metric_exporter_pasword 61 | mysqldb_replication_user_password = local.mysqldb_custom_credentials_enabled ? "" : module.aws.mysqldb_replication_user_password 62 | custom_user_password = local.mysqldb_custom_credentials_enabled ? "" : module.aws.custom_user_password 63 | bucket_provider_type = "s3" 64 | iam_role_arn_backup = module.aws.iam_role_arn_backup 65 | mysqldb_backup_enabled = true 66 | mysqldb_backup_config = { 67 | mysql_database_name = "" 68 | bucket_uri = "s3://bucket_name/" 69 | s3_bucket_region = "" 70 | cron_for_full_backup = "*/5 * * * *" 71 | } 72 | mysqldb_restore_enabled = true 73 | iam_role_arn_restore = module.aws.iam_role_arn_restore 74 | mysqldb_restore_config = { 75 | bucket_uri = "s3://bucket_name/mysqldump_20230710_120501.zip" 76 | file_name = "mysqldump_20230710_120501.zip" 77 | s3_bucket_region = "" 78 | } 79 | mysqldb_exporter_enabled = true 80 | } 81 | -------------------------------------------------------------------------------- /examples/complete/azure/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | name = "mysql" 3 | region = "eastus" 4 | environment = "prod" 5 | additional_tags = { 6 | Owner = "organization_name" 7 | Expires = "Never" 8 | Department = "Engineering" 9 | } 10 | create_namespace = true 11 | namespace = "mysql" 12 | store_password_to_secret_manager = true 13 | mysqldb_custom_credentials_enabled = false 14 | mysqldb_custom_credentials_config = { 15 | root_user = "root" 16 | root_password = "RJDRIFsYC8ZS1WQuV0ps" 17 | custom_username = "admin" 18 | custom_user_password = "NCPFUKEMd7rrWuvMAa73" 19 | replication_user = "replicator" 20 | replication_password = "nvAHhm1uGQNYWVw6ZyAH" 21 | exporter_user = "mysqld_exporter" 22 | exporter_password = "ZawhvpueAehRdKFlbjaq" 23 | } 24 | custom_user_username = "custom" 25 | azure_storage_account_name = "" 26 | azure_container_name = "" 27 | } 28 | 29 | module "azure" { 30 | source = "saturnops/mysql/kubernetes//modules/resources/azure" 31 | cluster_name = "" 32 | resource_group_name = "" 33 | resource_group_location = "" 34 | environment = local.environment 35 | name = local.name 36 | store_password_to_secret_manager = local.store_password_to_secret_manager 37 | mysqldb_custom_credentials_enabled = local.mysqldb_custom_credentials_enabled 38 | mysqldb_custom_credentials_config = local.mysqldb_custom_credentials_config 39 | custom_user_username = local.mysqldb_custom_credentials_enabled ? "" : local.custom_user_username 40 | storage_resource_group_name = "" 41 | storage_account_name = "" 42 | } 43 | 44 | module "mysql" { 45 | source = "saturnops/mysql/kubernetes" 46 | create_namespace = local.create_namespace 47 | namespace = local.namespace 48 | mysqldb_config = { 49 | name = local.name 50 | values_yaml = file("./helm/values.yaml") 51 | environment = local.environment 52 | app_version = "8.0.29-debian-11-r9" 53 | architecture = "replication" 54 | custom_database = "test_db" 55 | storage_class_name = "infra-service-sc" 56 | custom_user_username = local.mysqldb_custom_credentials_enabled ? "" : local.custom_user_username 57 | primary_db_volume_size = "10Gi" 58 | secondary_db_volume_size = "10Gi" 59 | secondary_db_replica_count = 2 60 | store_password_to_secret_manager = local.store_password_to_secret_manager 61 | } 62 | mysqldb_custom_credentials_enabled = local.mysqldb_custom_credentials_enabled 63 | mysqldb_custom_credentials_config = local.mysqldb_custom_credentials_config 64 | root_password = local.mysqldb_custom_credentials_enabled ? "" : module.azure.root_password 65 | metric_exporter_pasword = local.mysqldb_custom_credentials_enabled ? "" : module.azure.metric_exporter_pasword 66 | mysqldb_replication_user_password = local.mysqldb_custom_credentials_enabled ? "" : module.azure.mysqldb_replication_user_password 67 | custom_user_password = local.mysqldb_custom_credentials_enabled ? "" : module.azure.custom_user_password 68 | bucket_provider_type = "azure" 69 | mysqldb_backup_enabled = false 70 | mysqldb_backup_config = { 71 | bucket_uri = "https://${local.azure_storage_account_name}.blob.core.windows.net/${local.azure_container_name}" 72 | azure_storage_account_name = local.azure_storage_account_name 73 | azure_container_name = local.azure_container_name 74 | cron_for_full_backup = "* * 1 * *" 75 | } 76 | mysqldb_restore_enabled = false 77 | mysqldb_restore_config = { 78 | bucket_uri = "https://${local.azure_storage_account_name}.blob.core.windows.net/${local.azure_container_name}" 79 | azure_storage_account_name = local.azure_storage_account_name 80 | azure_container_name = local.azure_container_name 81 | file_name = "mongodumpfull_20230710_132301.gz" 82 | } 83 | mysqldb_exporter_enabled = true 84 | } 85 | -------------------------------------------------------------------------------- /modules/resources/gcp/main.tf: -------------------------------------------------------------------------------- 1 | resource "random_password" "mysqldb_root_password" { 2 | count = var.mysqldb_custom_credentials_enabled ? 0 : 1 3 | length = 20 4 | special = false 5 | } 6 | 7 | resource "random_password" "mysqldb_custom_user_password" { 8 | count = var.mysqldb_custom_credentials_enabled ? 0 : 1 9 | length = 20 10 | special = false 11 | } 12 | 13 | resource "random_password" "mysqldb_replication_user_password" { 14 | count = var.mysqldb_custom_credentials_enabled ? 0 : 1 15 | length = 20 16 | special = false 17 | } 18 | 19 | resource "random_password" "mysqldb_exporter_user_password" { 20 | count = var.mysqldb_custom_credentials_enabled ? 0 : 1 21 | length = 20 22 | special = false 23 | } 24 | 25 | resource "google_secret_manager_secret" "mysql-secret" { 26 | count = var.store_password_to_secret_manager ? 1 : 0 27 | project = var.project_id 28 | secret_id = format("%s-%s-%s", var.environment, var.name, "mysql") 29 | 30 | replication { 31 | automatic = true 32 | } 33 | } 34 | 35 | resource "google_secret_manager_secret_version" "mysql-secret" { 36 | count = var.store_password_to_secret_manager ? 1 : 0 37 | secret = google_secret_manager_secret.mysql-secret[0].id 38 | secret_data = var.mysqldb_custom_credentials_enabled ? jsonencode( 39 | { 40 | "root_user" : "${var.mysqldb_custom_credentials_config.root_user}", 41 | "root_password" : "${var.mysqldb_custom_credentials_config.root_password}", 42 | "custom_username" : "${var.mysqldb_custom_credentials_config.custom_username}", 43 | "custom_user_password" : "${var.mysqldb_custom_credentials_config.custom_user_password}", 44 | "replication_user" : "${var.mysqldb_custom_credentials_config.replication_user}", 45 | "replication_password" : "${var.mysqldb_custom_credentials_config.replication_password}", 46 | "exporter_user" : "${var.mysqldb_custom_credentials_config.exporter_user}", 47 | "exporter_password" : "${var.mysqldb_custom_credentials_config.exporter_password}" 48 | }) : jsonencode( 49 | { 50 | "root_user" : "root", 51 | "root_password" : "${random_password.mysqldb_root_password[0].result}", 52 | "custom_username" : "${var.custom_user_username}", 53 | "custom_user_password" : "${random_password.mysqldb_custom_user_password[0].result}", 54 | "replication_user" : "replicator", 55 | "replication_password" : "${random_password.mysqldb_replication_user_password[0].result}", 56 | "exporter_user" : "mysqld_exporter", 57 | "exporter_password" : "${random_password.mysqldb_exporter_user_password[0].result}" 58 | }) 59 | } 60 | 61 | resource "google_service_account" "mysql_backup" { 62 | project = var.project_id 63 | account_id = format("%s-%s-%s", var.environment, var.gcp_gsa_backup_name, var.name) 64 | display_name = "Service Account for Mysql Backup" 65 | } 66 | 67 | resource "google_project_iam_member" "secretadmin_backup" { 68 | project = var.project_id 69 | role = "roles/storage.objectAdmin" 70 | member = "serviceAccount:${google_service_account.mysql_backup.email}" 71 | } 72 | 73 | resource "google_project_iam_member" "service_account_token_creator_backup" { 74 | project = var.project_id 75 | role = "roles/iam.serviceAccountTokenCreator" 76 | member = "serviceAccount:${google_service_account.mysql_backup.email}" 77 | } 78 | 79 | resource "google_service_account_iam_member" "pod_identity_backup" { 80 | role = "roles/iam.workloadIdentityUser" 81 | member = "serviceAccount:${var.project_id}.svc.id.goog[mysqldb/${var.gcp_ksa_backup_name}]" 82 | service_account_id = google_service_account.mysql_backup.name 83 | } 84 | 85 | resource "google_service_account" "mysql_restore" { 86 | project = var.project_id 87 | account_id = format("%s-%s-%s", var.environment, var.gcp_gsa_restore_name, var.name) 88 | display_name = "Service Account for Mysql restore" 89 | } 90 | 91 | resource "google_project_iam_member" "secretadmin_restore" { 92 | project = var.project_id 93 | role = "roles/storage.objectAdmin" 94 | member = "serviceAccount:${google_service_account.mysql_restore.email}" 95 | } 96 | 97 | resource "google_project_iam_member" "service_account_token_creator_restore" { 98 | project = var.project_id 99 | role = "roles/iam.serviceAccountTokenCreator" 100 | member = "serviceAccount:${google_service_account.mysql_restore.email}" 101 | } 102 | 103 | resource "google_service_account_iam_member" "pod_identity_restore" { 104 | role = "roles/iam.workloadIdentityUser" 105 | member = "serviceAccount:${var.project_id}.svc.id.goog[mysqldb/${var.gcp_ksa_restore_name}]" 106 | service_account_id = google_service_account.mysql_restore.name 107 | } 108 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | resource "kubernetes_namespace" "mysqldb" { 2 | count = var.create_namespace ? 1 : 0 3 | metadata { 4 | annotations = {} 5 | name = var.namespace 6 | } 7 | } 8 | 9 | resource "helm_release" "mysqldb" { 10 | depends_on = [kubernetes_namespace.mysqldb] 11 | name = "mysqldb" 12 | chart = "mysql" 13 | version = var.chart_version 14 | timeout = 600 15 | namespace = var.namespace 16 | repository = "https://charts.bitnami.com/bitnami" 17 | values = [ 18 | templatefile("${path.module}/helm/values/mysqldb/values.yaml", { 19 | app_version = var.app_version, 20 | architecture = var.mysqldb_config.architecture, 21 | custom_database = var.mysqldb_config.custom_database, 22 | primary_pod_size = var.mysqldb_config.primary_db_volume_size, 23 | secondary_pod_size = var.mysqldb_config.secondary_db_volume_size, 24 | storage_class_name = var.mysqldb_config.storage_class_name, 25 | custom_user_username = var.mysqldb_custom_credentials_enabled ? var.mysqldb_custom_credentials_config.custom_username : var.mysqldb_config.custom_user_username, 26 | custom_user_password = var.mysqldb_custom_credentials_enabled ? var.mysqldb_custom_credentials_config.custom_user_password : var.custom_user_password, 27 | replication_password = var.mysqldb_custom_credentials_enabled ? var.mysqldb_custom_credentials_config.replication_password : var.mysqldb_replication_user_password, 28 | mysqldb_root_password = var.mysqldb_custom_credentials_enabled ? var.mysqldb_custom_credentials_config.root_password : var.root_password, 29 | mysqldb_exporter_enabled = var.mysqldb_exporter_enabled, 30 | service_monitor_namespace = var.namespace, 31 | metrics_exporter_password = var.mysqldb_custom_credentials_enabled ? var.mysqldb_custom_credentials_config.exporter_password : var.metric_exporter_pasword, 32 | secondary_pod_replica_count = var.mysqldb_config.secondary_db_replica_count 33 | }), 34 | var.mysqldb_config.values_yaml 35 | ] 36 | } 37 | 38 | resource "helm_release" "mysqldb_backup" { 39 | depends_on = [helm_release.mysqldb] 40 | count = var.mysqldb_backup_enabled ? 1 : 0 41 | name = "mysqldb-backup" 42 | chart = "${path.module}/modules/backup" 43 | timeout = 600 44 | namespace = var.namespace 45 | values = [ 46 | templatefile("${path.module}/helm/values/backup/values.yaml", { 47 | bucket_uri = var.mysqldb_backup_config.bucket_uri, 48 | mysql_database_name = var.bucket_provider_type == "s3" ? var.mysqldb_backup_config.mysql_database_name : "", 49 | s3_bucket_region = var.bucket_provider_type == "s3" ? var.mysqldb_backup_config.s3_bucket_region : "", 50 | cron_for_full_backup = var.mysqldb_backup_config.cron_for_full_backup, 51 | custom_user_username = "root", 52 | bucket_provider_type = var.bucket_provider_type, 53 | azure_storage_account_name = var.bucket_provider_type == "azure" ? var.azure_storage_account_name : "" 54 | azure_storage_account_key = var.bucket_provider_type == "azure" ? var.azure_storage_account_key : "" 55 | azure_container_name = var.bucket_provider_type == "azure" ? var.azure_container_name : "" 56 | annotations = var.bucket_provider_type == "s3" ? "eks.amazonaws.com/role-arn: ${var.iam_role_arn_backup}" : "iam.gke.io/gcp-service-account: ${var.service_account_backup}" 57 | }), 58 | var.mysqldb_config.values_yaml 59 | ] 60 | } 61 | 62 | 63 | ## DB dump restore 64 | resource "helm_release" "mysqldb_restore" { 65 | depends_on = [helm_release.mysqldb] 66 | count = var.mysqldb_restore_enabled ? 1 : 0 67 | name = "mysqldb-restore" 68 | chart = "${path.module}/modules/restore" 69 | timeout = 600 70 | namespace = var.namespace 71 | values = [ 72 | templatefile("${path.module}/helm/values/restore/values.yaml", { 73 | bucket_uri = var.mysqldb_restore_config.bucket_uri, 74 | file_name = var.mysqldb_restore_config.file_name, 75 | s3_bucket_region = var.bucket_provider_type == "s3" ? var.mysqldb_restore_config.s3_bucket_region : "", 76 | custom_user_username = "root", 77 | bucket_provider_type = var.bucket_provider_type, 78 | azure_storage_account_name = var.bucket_provider_type == "azure" ? var.azure_storage_account_name : "" 79 | azure_storage_account_key = var.bucket_provider_type == "azure" ? var.azure_storage_account_key : "" 80 | azure_container_name = var.bucket_provider_type == "azure" ? var.azure_container_name : "" 81 | annotations = var.bucket_provider_type == "s3" ? "eks.amazonaws.com/role-arn: ${var.iam_role_arn_restore}" : "iam.gke.io/gcp-service-account: ${var.service_account_restore}" 82 | }), 83 | var.mysqldb_config.values_yaml 84 | ] 85 | } 86 | -------------------------------------------------------------------------------- /modules/resources/aws/README.md: -------------------------------------------------------------------------------- 1 | # aws 2 | 3 | 4 | ## Requirements 5 | 6 | No requirements. 7 | 8 | ## Providers 9 | 10 | | Name | Version | 11 | |------|---------| 12 | | [aws](#provider\_aws) | n/a | 13 | | [random](#provider\_random) | n/a | 14 | 15 | ## Modules 16 | 17 | No modules. 18 | 19 | ## Resources 20 | 21 | | Name | Type | 22 | |------|------| 23 | | [aws_iam_role.mysql_backup_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | 24 | | [aws_iam_role.mysql_restore_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | 25 | | [aws_secretsmanager_secret.mysql_user_password](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource | 26 | | [aws_secretsmanager_secret_version.mysql_user_password](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource | 27 | | [random_password.mysqldb_custom_user_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 28 | | [random_password.mysqldb_exporter_user_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 29 | | [random_password.mysqldb_replication_user_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 30 | | [random_password.mysqldb_root_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 31 | | [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | 32 | | [aws_eks_cluster.kubernetes_cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster) | data source | 33 | 34 | ## Inputs 35 | 36 | | Name | Description | Type | Default | Required | 37 | |------|-------------|------|---------|:--------:| 38 | | [cluster\_name](#input\_cluster\_name) | Specifies the name of the EKS cluster to deploy the MySQL application on. | `string` | `""` | no | 39 | | [custom\_user\_username](#input\_custom\_user\_username) | n/a | `string` | `""` | no | 40 | | [environment](#input\_environment) | Environment in which the infrastructure is being deployed (e.g., production, staging, development) | `string` | `"test"` | no | 41 | | [mysqldb\_custom\_credentials\_config](#input\_mysqldb\_custom\_credentials\_config) | Specify the configuration settings for MySQL to pass custom credentials during creation | `any` |
{
"custom_user_password": "",
"custom_username": "",
"exporter_password": "",
"exporter_user": "",
"replication_password": "",
"replication_user": "",
"root_password": "",
"root_user": ""
}
| no | 42 | | [mysqldb\_custom\_credentials\_enabled](#input\_mysqldb\_custom\_credentials\_enabled) | Specifies whether to enable custom credentials for MySQL database. | `bool` | `false` | no | 43 | | [name](#input\_name) | Name identifier for module to be added as suffix to resources | `string` | `"test"` | no | 44 | | [namespace](#input\_namespace) | Name of the Kubernetes namespace where the MYSQL deployment will be deployed. | `string` | `"mysqldb"` | no | 45 | | [recovery\_window\_aws\_secret](#input\_recovery\_window\_aws\_secret) | Number of days that AWS Secrets Manager will wait before deleting a secret. This value can be set to 0 to force immediate deletion, or to a value between 7 and 30 days to allow for recovery. | `number` | `0` | no | 46 | | [store\_password\_to\_secret\_manager](#input\_store\_password\_to\_secret\_manager) | Specifies whether to store the credentials in GCP secret manager. | `bool` | `false` | no | 47 | 48 | ## Outputs 49 | 50 | | Name | Description | 51 | |------|-------------| 52 | | [custom\_user\_password](#output\_custom\_user\_password) | custom user's password of mysqldb | 53 | | [iam\_role\_arn\_backup](#output\_iam\_role\_arn\_backup) | IAM role arn for mysql backup | 54 | | [iam\_role\_arn\_restore](#output\_iam\_role\_arn\_restore) | IAM role arn for mysql restore | 55 | | [metric\_exporter\_pasword](#output\_metric\_exporter\_pasword) | mysqldb\_exporter user's password of mysqldb | 56 | | [mysqldb\_replication\_user\_password](#output\_mysqldb\_replication\_user\_password) | replicator user's password of mysqldb | 57 | | [root\_password](#output\_root\_password) | Root user's password of mysqldb | 58 | 59 | -------------------------------------------------------------------------------- /modules/resources/aws/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | oidc_provider = replace( 3 | data.aws_eks_cluster.kubernetes_cluster.identity[0].oidc[0].issuer, 4 | "/^https:///", 5 | "" 6 | ) 7 | } 8 | 9 | data "aws_caller_identity" "current" {} 10 | 11 | data "aws_eks_cluster" "kubernetes_cluster" { 12 | name = var.cluster_name 13 | } 14 | 15 | resource "random_password" "mysqldb_root_password" { 16 | count = var.mysqldb_custom_credentials_enabled ? 0 : 1 17 | length = 20 18 | special = false 19 | } 20 | 21 | resource "random_password" "mysqldb_custom_user_password" { 22 | count = var.mysqldb_custom_credentials_enabled ? 0 : 1 23 | length = 20 24 | special = false 25 | } 26 | 27 | resource "random_password" "mysqldb_replication_user_password" { 28 | count = var.mysqldb_custom_credentials_enabled ? 0 : 1 29 | length = 20 30 | special = false 31 | } 32 | 33 | resource "random_password" "mysqldb_exporter_user_password" { 34 | count = var.mysqldb_custom_credentials_enabled ? 0 : 1 35 | length = 20 36 | special = false 37 | } 38 | 39 | 40 | resource "aws_secretsmanager_secret" "mysql_user_password" { 41 | count = var.store_password_to_secret_manager ? 1 : 0 42 | name = format("%s/%s/%s", var.environment, var.name, "mysql") 43 | recovery_window_in_days = var.recovery_window_aws_secret 44 | } 45 | 46 | resource "aws_secretsmanager_secret_version" "mysql_user_password" { 47 | count = var.store_password_to_secret_manager ? 1 : 0 48 | secret_id = aws_secretsmanager_secret.mysql_user_password[0].id 49 | secret_string = var.mysqldb_custom_credentials_enabled ? jsonencode( 50 | { 51 | "root_user" : "${var.mysqldb_custom_credentials_config.root_user}", 52 | "root_password" : "${var.mysqldb_custom_credentials_config.root_password}", 53 | "custom_username" : "${var.mysqldb_custom_credentials_config.custom_username}", 54 | "custom_user_password" : "${var.mysqldb_custom_credentials_config.custom_user_password}", 55 | "replication_user" : "${var.mysqldb_custom_credentials_config.replication_user}", 56 | "replication_password" : "${var.mysqldb_custom_credentials_config.replication_password}", 57 | "exporter_user" : "${var.mysqldb_custom_credentials_config.exporter_user}", 58 | "exporter_password" : "${var.mysqldb_custom_credentials_config.exporter_password}" 59 | }) : jsonencode( 60 | { 61 | "root_user" : "root", 62 | "root_password" : "${random_password.mysqldb_root_password[0].result}", 63 | "custom_username" : "${var.custom_user_username}", 64 | "custom_user_password" : "${random_password.mysqldb_custom_user_password[0].result}", 65 | "replication_user" : "replicator", 66 | "replication_password" : "${random_password.mysqldb_replication_user_password[0].result}", 67 | "exporter_user" : "mysqld_exporter", 68 | "exporter_password" : "${random_password.mysqldb_exporter_user_password[0].result}" 69 | }) 70 | } 71 | 72 | resource "aws_iam_role" "mysql_backup_role" { 73 | name = format("%s-%s-%s", var.cluster_name, var.name, "mysql-backup") 74 | assume_role_policy = jsonencode({ 75 | Version = "2012-10-17", 76 | Statement = [ 77 | { 78 | Effect = "Allow", 79 | Principal = { 80 | Federated = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/${local.oidc_provider}" 81 | }, 82 | Action = "sts:AssumeRoleWithWebIdentity", 83 | Condition = { 84 | StringEquals = { 85 | "${local.oidc_provider}:aud" = "sts.amazonaws.com", 86 | "${local.oidc_provider}:sub" = "system:serviceaccount:${var.namespace}:sa-mysql-backup" 87 | } 88 | } 89 | } 90 | ] 91 | }) 92 | inline_policy { 93 | name = "AllowS3PutObject" 94 | policy = jsonencode({ 95 | Version = "2012-10-17" 96 | Statement = [ 97 | { 98 | Action = [ 99 | "s3:GetObject", 100 | "s3:PutObject", 101 | "s3:DeleteObject", 102 | "s3:ListBucket", 103 | "s3:AbortMultipartUpload", 104 | "s3:ListMultipartUploadParts" 105 | ] 106 | Effect = "Allow" 107 | Resource = "*" 108 | } 109 | ] 110 | }) 111 | } 112 | } 113 | 114 | 115 | resource "aws_iam_role" "mysql_restore_role" { 116 | name = format("%s-%s-%s", var.cluster_name, var.name, "mysql-restore") 117 | assume_role_policy = jsonencode({ 118 | Version = "2012-10-17", 119 | Statement = [ 120 | { 121 | Effect = "Allow", 122 | Principal = { 123 | Federated = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/${local.oidc_provider}" 124 | }, 125 | Action = "sts:AssumeRoleWithWebIdentity", 126 | Condition = { 127 | StringEquals = { 128 | "${local.oidc_provider}:aud" = "sts.amazonaws.com", 129 | "${local.oidc_provider}:sub" = "system:serviceaccount:${var.namespace}:sa-mysql-restore" 130 | } 131 | } 132 | } 133 | ] 134 | }) 135 | inline_policy { 136 | name = "AllowS3PutObject" 137 | policy = jsonencode({ 138 | Version = "2012-10-17" 139 | Statement = [ 140 | { 141 | Action = [ 142 | "s3:GetObject", 143 | "s3:PutObject", 144 | "s3:DeleteObject", 145 | "s3:ListBucket", 146 | "s3:AbortMultipartUpload", 147 | "s3:ListMultipartUploadParts" 148 | ] 149 | Effect = "Allow" 150 | Resource = "*" 151 | } 152 | ] 153 | }) 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /modules/resources/gcp/README.md: -------------------------------------------------------------------------------- 1 | # gcp 2 | 3 | 4 | ## Requirements 5 | 6 | No requirements. 7 | 8 | ## Providers 9 | 10 | | Name | Version | 11 | |------|---------| 12 | | [google](#provider\_google) | n/a | 13 | | [random](#provider\_random) | n/a | 14 | 15 | ## Modules 16 | 17 | No modules. 18 | 19 | ## Resources 20 | 21 | | Name | Type | 22 | |------|------| 23 | | [google_project_iam_member.secretadmin_backup](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_member) | resource | 24 | | [google_project_iam_member.secretadmin_restore](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_member) | resource | 25 | | [google_project_iam_member.service_account_token_creator_backup](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_member) | resource | 26 | | [google_project_iam_member.service_account_token_creator_restore](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_member) | resource | 27 | | [google_secret_manager_secret.mysql-secret](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/secret_manager_secret) | resource | 28 | | [google_secret_manager_secret_version.mysql-secret](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/secret_manager_secret_version) | resource | 29 | | [google_service_account.mysql_backup](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource | 30 | | [google_service_account.mysql_restore](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource | 31 | | [google_service_account_iam_member.pod_identity_backup](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_iam_member) | resource | 32 | | [google_service_account_iam_member.pod_identity_restore](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_iam_member) | resource | 33 | | [random_password.mysqldb_custom_user_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 34 | | [random_password.mysqldb_exporter_user_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 35 | | [random_password.mysqldb_replication_user_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 36 | | [random_password.mysqldb_root_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 37 | 38 | ## Inputs 39 | 40 | | Name | Description | Type | Default | Required | 41 | |------|-------------|------|---------|:--------:| 42 | | [custom\_user\_username](#input\_custom\_user\_username) | n/a | `string` | `""` | no | 43 | | [environment](#input\_environment) | Environment in which the infrastructure is being deployed (e.g., production, staging, development) | `string` | `"test"` | no | 44 | | [gcp\_gsa\_backup\_name](#input\_gcp\_gsa\_backup\_name) | Google Cloud Service Account name for backup | `string` | `"mysql-backup"` | no | 45 | | [gcp\_gsa\_restore\_name](#input\_gcp\_gsa\_restore\_name) | Google Cloud Service Account name for restore | `string` | `"mysql-restore"` | no | 46 | | [gcp\_ksa\_backup\_name](#input\_gcp\_ksa\_backup\_name) | Google Kubernetes Service Account name for backup | `string` | `"sa-mysql-backup"` | no | 47 | | [gcp\_ksa\_restore\_name](#input\_gcp\_ksa\_restore\_name) | Google Kubernetes Service Account name for restore | `string` | `"sa-mysql-restore"` | no | 48 | | [mysqldb\_custom\_credentials\_config](#input\_mysqldb\_custom\_credentials\_config) | Specify the configuration settings for MySQL to pass custom credentials during creation | `any` |
{
"custom_user_password": "",
"custom_username": "",
"exporter_password": "",
"exporter_user": "",
"replication_password": "",
"replication_user": "",
"root_password": "",
"root_user": ""
}
| no | 49 | | [mysqldb\_custom\_credentials\_enabled](#input\_mysqldb\_custom\_credentials\_enabled) | Specifies whether to enable custom credentials for MySQL database. | `bool` | `false` | no | 50 | | [name](#input\_name) | Name identifier for module to be added as suffix to resources | `string` | `"test"` | no | 51 | | [project\_id](#input\_project\_id) | Google Cloud project ID | `string` | `""` | no | 52 | | [store\_password\_to\_secret\_manager](#input\_store\_password\_to\_secret\_manager) | Specifies whether to store the credentials in GCP secret manager. | `bool` | `false` | no | 53 | 54 | ## Outputs 55 | 56 | | Name | Description | 57 | |------|-------------| 58 | | [custom\_user\_password](#output\_custom\_user\_password) | custom user's password of mysqldb | 59 | | [metric\_exporter\_pasword](#output\_metric\_exporter\_pasword) | mysqldb\_exporter user's password of mysqldb | 60 | | [mysqldb\_replication\_user\_password](#output\_mysqldb\_replication\_user\_password) | replicator user's password of mysqldb | 61 | | [root\_password](#output\_root\_password) | Root user's password of mysqldb | 62 | | [service\_account\_backup](#output\_service\_account\_backup) | Google Cloud Service Account name for backup | 63 | | [service\_account\_restore](#output\_service\_account\_restore) | Google Cloud Service Account name for restore | 64 | 65 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "mysqldb_config" { 2 | type = any 3 | default = { 4 | name = "" 5 | environment = "" 6 | values_yaml = "" 7 | architecture = "" 8 | custom_database = "" 9 | storage_class_name = "" 10 | custom_user_username = "" 11 | primary_db_volume_size = "" 12 | secondary_db_volume_size = "" 13 | secondary_db_replica_count = 1 14 | store_password_to_secret_manager = true 15 | } 16 | description = "Specify the configuration settings for MySQL, including the name, environment, storage options, replication settings, and custom YAML values." 17 | } 18 | 19 | variable "mysqldb_custom_credentials_enabled" { 20 | type = bool 21 | default = false 22 | description = "Specifies whether to enable custom credentials for MySQL database." 23 | } 24 | 25 | variable "mysqldb_custom_credentials_config" { 26 | type = any 27 | default = { 28 | root_user = "" 29 | root_password = "" 30 | custom_username = "" 31 | custom_user_password = "" 32 | replication_user = "" 33 | replication_password = "" 34 | exporter_user = "" 35 | exporter_password = "" 36 | } 37 | description = "Specify the configuration settings for MySQL to pass custom credentials during creation" 38 | } 39 | 40 | variable "app_version" { 41 | type = string 42 | default = "8.0.29-debian-11-r9" 43 | description = "Version of the MySQL application that will be deployed." 44 | } 45 | 46 | variable "chart_version" { 47 | type = string 48 | default = "9.2.0" 49 | description = "Version of the Mysql chart that will be used to deploy MySQL application." 50 | } 51 | 52 | variable "namespace" { 53 | type = string 54 | default = "mysqldb" 55 | description = "Name of the Kubernetes namespace where the MYSQL deployment will be deployed." 56 | } 57 | variable "mysqldb_backup_enabled" { 58 | type = bool 59 | default = false 60 | description = "Specifies whether to enable backups for MySQL database." 61 | } 62 | 63 | variable "mysqldb_backup_config" { 64 | type = any 65 | default = { 66 | bucket_uri = "" 67 | s3_bucket_region = "" 68 | cron_for_full_backup = "" 69 | mysql_database_name = "" 70 | } 71 | description = "configuration options for MySQL database backups. It includes properties such as the S3 bucket URI, the S3 bucket region, cron expression for full backups and the database name to take backup of particular database or if send empty it backup whole database " 72 | } 73 | 74 | variable "mysqldb_exporter_enabled" { 75 | type = bool 76 | default = false 77 | description = "Specify whether or not to deploy Mysql exporter to collect Mysql metrics for monitoring in Grafana." 78 | } 79 | 80 | variable "recovery_window_aws_secret" { 81 | type = number 82 | default = 0 83 | description = "Number of days that AWS Secrets Manager will wait before deleting a secret. This value can be set to 0 to force immediate deletion, or to a value between 7 and 30 days to allow for recovery." 84 | } 85 | 86 | variable "cluster_name" { 87 | type = string 88 | default = "" 89 | description = "Specifies the name of the EKS cluster to deploy the MySQL application on." 90 | } 91 | 92 | variable "create_namespace" { 93 | type = string 94 | description = "Specify whether or not to create the namespace if it does not already exist. Set it to true to create the namespace." 95 | default = true 96 | } 97 | 98 | variable "mysqldb_restore_enabled" { 99 | type = bool 100 | default = false 101 | description = "Specifies whether to enable restoring dump to the MySQL database." 102 | } 103 | 104 | variable "mysqldb_restore_config" { 105 | type = any 106 | default = { 107 | bucket_uri = "" 108 | file_name = "" 109 | s3_bucket_region = "" 110 | } 111 | description = "Configuration options for restoring dump to the MySQL database." 112 | } 113 | 114 | variable "bucket_provider_type" { 115 | type = string 116 | default = "gcs" 117 | description = "Choose what type of provider you want (s3, gcs)" 118 | } 119 | 120 | 121 | variable "project_id" { 122 | description = "Google Cloud project ID" 123 | type = string 124 | default = "" 125 | } 126 | 127 | variable "iam_role_arn_backup" { 128 | description = "IAM role ARN for backup (AWS)" 129 | type = string 130 | default = "" 131 | } 132 | 133 | variable "service_account_backup" { 134 | description = "Service account for backup (GCP)" 135 | type = string 136 | default = "" 137 | } 138 | 139 | variable "iam_role_arn_restore" { 140 | description = "IAM role ARN for restore (AWS)" 141 | type = string 142 | default = "" 143 | } 144 | 145 | variable "service_account_restore" { 146 | description = "Service account for restore (GCP)" 147 | type = string 148 | default = "" 149 | } 150 | 151 | variable "root_password" { 152 | description = "Root password for MongoDB" 153 | type = string 154 | default = "" 155 | } 156 | 157 | variable "metric_exporter_pasword" { 158 | description = "Metric exporter password for MongoDB" 159 | type = string 160 | default = "" 161 | } 162 | 163 | variable "custom_user_password" { 164 | description = "custom user password for MongoDB" 165 | type = string 166 | default = "" 167 | } 168 | 169 | variable "mysqldb_replication_user_password" { 170 | description = "Replicator password for MongoDB" 171 | type = string 172 | default = "" 173 | } 174 | 175 | variable "resource_group_name" { 176 | description = "Azure Resource Group name" 177 | type = string 178 | default = "" 179 | } 180 | 181 | variable "resource_group_location" { 182 | description = "Azure region" 183 | type = string 184 | default = "East US" 185 | } 186 | variable "azure_storage_account_name" { 187 | description = "Azure storage account name" 188 | type = string 189 | default = "" 190 | } 191 | 192 | variable "azure_storage_account_key" { 193 | description = "Azure storage account key" 194 | type = string 195 | default = "" 196 | } 197 | 198 | variable "azure_container_name" { 199 | description = "Azure container name" 200 | type = string 201 | default = "" 202 | } 203 | -------------------------------------------------------------------------------- /modules/resources/azure/main.tf: -------------------------------------------------------------------------------- 1 | data "azurerm_client_config" "current" {} 2 | 3 | data "azurerm_subscription" "current" {} 4 | 5 | resource "random_password" "mysqldb_root_password" { 6 | count = var.mysqldb_custom_credentials_enabled ? 0 : 1 7 | length = 20 8 | special = false 9 | } 10 | 11 | resource "random_password" "mysqldb_custom_user_password" { 12 | count = var.mysqldb_custom_credentials_enabled ? 0 : 1 13 | length = 20 14 | special = false 15 | } 16 | 17 | resource "random_password" "mysqldb_replication_user_password" { 18 | count = var.mysqldb_custom_credentials_enabled ? 0 : 1 19 | length = 20 20 | special = false 21 | } 22 | 23 | resource "random_password" "mysqldb_exporter_user_password" { 24 | count = var.mysqldb_custom_credentials_enabled ? 0 : 1 25 | length = 20 26 | special = false 27 | } 28 | 29 | resource "azurerm_key_vault" "mysql-secret" { 30 | count = var.store_password_to_secret_manager ? 1 : 0 31 | name = format("%s-%s-%s", var.environment, var.name, "mysql") 32 | resource_group_name = var.resource_group_name 33 | location = var.resource_group_location 34 | sku_name = "standard" 35 | tenant_id = data.azurerm_client_config.current.tenant_id 36 | enabled_for_disk_encryption = true 37 | soft_delete_retention_days = 7 38 | 39 | access_policy { 40 | tenant_id = data.azurerm_client_config.current.tenant_id 41 | object_id = data.azurerm_client_config.current.object_id 42 | key_permissions = [ 43 | "Get", 44 | "List", 45 | ] 46 | secret_permissions = [ 47 | "Set", 48 | "Get", 49 | "List", 50 | "Delete", 51 | "Purge", 52 | ] 53 | } 54 | } 55 | 56 | resource "azurerm_key_vault_secret" "mysql-secret" { 57 | count = var.store_password_to_secret_manager ? 1 : 0 58 | depends_on = [azurerm_key_vault.mysql-secret[0]] 59 | name = format("%s-%s-%s", var.environment, var.name, "secret") 60 | value = var.mysqldb_custom_credentials_enabled ? jsonencode( 61 | { 62 | "root_user" : "${var.mysqldb_custom_credentials_config.root_user}", 63 | "root_password" : "${var.mysqldb_custom_credentials_config.root_password}", 64 | "custom_username" : "${var.mysqldb_custom_credentials_config.custom_username}", 65 | "custom_user_password" : "${var.mysqldb_custom_credentials_config.custom_user_password}", 66 | "replication_user" : "${var.mysqldb_custom_credentials_config.replication_user}", 67 | "replication_password" : "${var.mysqldb_custom_credentials_config.replication_password}", 68 | "exporter_user" : "${var.mysqldb_custom_credentials_config.exporter_user}", 69 | "exporter_password" : "${var.mysqldb_custom_credentials_config.exporter_password}" 70 | }) : jsonencode( 71 | { 72 | "root_user" : "root", 73 | "root_password" : "${random_password.mysqldb_root_password[0].result}", 74 | "custom_username" : "${var.custom_user_username}", 75 | "custom_user_password" : "${random_password.mysqldb_custom_user_password[0].result}", 76 | "replication_user" : "replicator", 77 | "replication_password" : "${random_password.mysqldb_replication_user_password[0].result}", 78 | "exporter_user" : "mysqld_exporter", 79 | "exporter_password" : "${random_password.mysqldb_exporter_user_password[0].result}" 80 | }) 81 | content_type = "application/json" 82 | key_vault_id = azurerm_key_vault.mysql-secret[0].id 83 | } 84 | 85 | # Create a service principal for MySQL backup 86 | resource "azurerm_user_assigned_identity" "mysql_backup_identity" { 87 | name = format("%s-%s-%s", var.environment, var.name, "mysql_backup_identity") 88 | resource_group_name = var.resource_group_name 89 | location = var.resource_group_location 90 | } 91 | 92 | # Grant the storage blob contributor role to the backup service principal 93 | resource "azurerm_role_assignment" "secretadmin_backup" { 94 | principal_id = azurerm_user_assigned_identity.mysql_backup_identity.principal_id 95 | role_definition_name = "Storage Blob Data Contributor" 96 | scope = "/subscriptions/${data.azurerm_subscription.current.subscription_id}/resourceGroups/${var.storage_resource_group_name}/providers/Microsoft.Storage/storageAccounts/${var.storage_account_name}" 97 | } 98 | 99 | # Grant the "Managed Identity Token Creator" role to the backup service principal 100 | resource "azurerm_role_assignment" "service_account_token_creator_backup" { 101 | principal_id = azurerm_user_assigned_identity.mysql_backup_identity.principal_id 102 | role_definition_name = "Managed Identity Token Creator" 103 | scope = "/subscriptions/${data.azurerm_subscription.current.subscription_id}/resourceGroups/${var.storage_resource_group_name}" 104 | } 105 | 106 | # Create a service principal for MySQL restore 107 | resource "azurerm_user_assigned_identity" "mysql_restore_identity" { 108 | name = format("%s-%s-%s", var.environment, var.name, "mysql_restore_identity") 109 | resource_group_name = var.resource_group_name 110 | location = var.resource_group_location 111 | } 112 | 113 | # Grant the storage blob contributor role to the restore service principal 114 | resource "azurerm_role_assignment" "secretadmin_restore" { 115 | principal_id = azurerm_user_assigned_identity.mysql_restore_identity.principal_id 116 | role_definition_name = "Storage Blob Data Contributor" 117 | scope = "/subscriptions/${data.azurerm_subscription.current.subscription_id}/resourceGroups/${var.storage_resource_group_name}/providers/Microsoft.Storage/storageAccounts/${var.storage_account_name}" 118 | } 119 | 120 | # Grant the "Managed Identity Token Creator" role to the restore service principal 121 | resource "azurerm_role_assignment" "service_account_token_creator_restore" { 122 | principal_id = azurerm_user_assigned_identity.mysql_restore_identity.principal_id 123 | role_definition_name = "Managed Identity Token Creator" 124 | scope = "/subscriptions/${data.azurerm_subscription.current.subscription_id}/resourceGroups/${var.storage_resource_group_name}" 125 | } 126 | 127 | # Configure workload identity for MySQL backup 128 | resource "azurerm_user_assigned_identity" "pod_identity_backup" { 129 | name = format("%s-%s-%s", var.environment, var.name, "pod_identity_backup") 130 | resource_group_name = var.resource_group_name 131 | location = var.resource_group_location 132 | } 133 | 134 | resource "azurerm_role_assignment" "pod_identity_assignment_backup" { 135 | principal_id = azurerm_user_assigned_identity.pod_identity_backup.principal_id 136 | role_definition_name = "Managed Identity Operator" 137 | scope = "/subscriptions/${data.azurerm_subscription.current.subscription_id}/resourceGroups/${var.storage_resource_group_name}" 138 | } 139 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2023 SaturnOps Technologies 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /modules/resources/azure/README.md: -------------------------------------------------------------------------------- 1 | # Azure Provider Module 2 | 3 | ## Requirements 4 | 5 | No requirements. 6 | 7 | ## Providers 8 | 9 | | Name | Version | 10 | |------|---------| 11 | | [azurerm](#provider\_azurerm) | n/a | 12 | | [random](#provider\_random) | n/a | 13 | 14 | ## Modules 15 | 16 | No modules. 17 | 18 | ## Resources 19 | 20 | | Name | Type | 21 | |------|------| 22 | | [azurerm_key_vault.mysql-secret](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault) | resource | 23 | | [azurerm_key_vault_secret.mysql-secret](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) | resource | 24 | | [azurerm_role_assignment.pod_identity_assignment_backup](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 25 | | [azurerm_role_assignment.secretadmin_backup](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 26 | | [azurerm_role_assignment.secretadmin_restore](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 27 | | [azurerm_role_assignment.service_account_token_creator_backup](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 28 | | [azurerm_role_assignment.service_account_token_creator_restore](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 29 | | [azurerm_user_assigned_identity.mysql_backup_identity](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource | 30 | | [azurerm_user_assigned_identity.mysql_restore_identity](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource | 31 | | [azurerm_user_assigned_identity.pod_identity_backup](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource | 32 | | [random_password.mysqldb_custom_user_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 33 | | [random_password.mysqldb_exporter_user_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 34 | | [random_password.mysqldb_replication_user_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 35 | | [random_password.mysqldb_root_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 36 | | [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) | data source | 37 | | [azurerm_subscription.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source | 38 | 39 | ## Inputs 40 | 41 | | Name | Description | Type | Default | Required | 42 | |------|-------------|------|---------|:--------:| 43 | | [cluster\_name](#input\_cluster\_name) | Name of the Azure AKS cluster | `string` | `""` | no | 44 | | [custom\_user\_username](#input\_custom\_user\_username) | n/a | `string` | `""` | no | 45 | | [environment](#input\_environment) | Environment in which the infrastructure is being deployed (e.g., production, staging, development) | `string` | `"test"` | no | 46 | | [mysqldb\_custom\_credentials\_config](#input\_mysqldb\_custom\_credentials\_config) | Specify the configuration settings for MySQL to pass custom credentials during creation | `any` |
{
"custom_user_password": "",
"custom_username": "",
"exporter_password": "",
"exporter_user": "",
"replication_password": "",
"replication_user": "",
"root_password": "",
"root_user": ""
}
| no | 47 | | [mysqldb\_custom\_credentials\_enabled](#input\_mysqldb\_custom\_credentials\_enabled) | Specifies whether to enable custom credentials for MySQL database. | `bool` | `false` | no | 48 | | [name](#input\_name) | Name identifier for module to be added as suffix to resources | `string` | `"test"` | no | 49 | | [resource\_group\_location](#input\_resource\_group\_location) | Azure region | `string` | `"East US"` | no | 50 | | [resource\_group\_name](#input\_resource\_group\_name) | Azure Resource Group name | `string` | `""` | no | 51 | | [storage\_account\_name](#input\_storage\_account\_name) | n/a | `string` | `""` | no | 52 | | [storage\_resource\_group\_name](#input\_storage\_resource\_group\_name) | Azure Storage account Resource Group name | `string` | `""` | no | 53 | | [store\_password\_to\_secret\_manager](#input\_store\_password\_to\_secret\_manager) | Specifies whether to store the credentials in GCP secret manager. | `bool` | `false` | no | 54 | 55 | ## Outputs 56 | 57 | | Name | Description | 58 | |------|-------------| 59 | | [custom\_user\_password](#output\_custom\_user\_password) | custom user's password of mysqldb | 60 | | [metric\_exporter\_pasword](#output\_metric\_exporter\_pasword) | mysqldb\_exporter user's password of mysqldb | 61 | | [mysqldb\_replication\_user\_password](#output\_mysqldb\_replication\_user\_password) | replicator user's password of mysqldb | 62 | | [root\_password](#output\_root\_password) | Root user's password of mysqldb | 63 | 64 | ## Requirements 65 | 66 | No requirements. 67 | 68 | ## Providers 69 | 70 | | Name | Version | 71 | |------|---------| 72 | | [azurerm](#provider\_azurerm) | n/a | 73 | | [random](#provider\_random) | n/a | 74 | 75 | ## Modules 76 | 77 | No modules. 78 | 79 | ## Resources 80 | 81 | | Name | Type | 82 | |------|------| 83 | | [azurerm_key_vault.mysql-secret](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault) | resource | 84 | | [azurerm_key_vault_secret.mysql-secret](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) | resource | 85 | | [azurerm_role_assignment.pod_identity_assignment_backup](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 86 | | [azurerm_role_assignment.secretadmin_backup](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 87 | | [azurerm_role_assignment.secretadmin_restore](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 88 | | [azurerm_role_assignment.service_account_token_creator_backup](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 89 | | [azurerm_role_assignment.service_account_token_creator_restore](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 90 | | [azurerm_user_assigned_identity.mysql_backup_identity](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource | 91 | | [azurerm_user_assigned_identity.mysql_restore_identity](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource | 92 | | [azurerm_user_assigned_identity.pod_identity_backup](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource | 93 | | [random_password.mysqldb_custom_user_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 94 | | [random_password.mysqldb_exporter_user_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 95 | | [random_password.mysqldb_replication_user_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 96 | | [random_password.mysqldb_root_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 97 | | [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) | data source | 98 | | [azurerm_subscription.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source | 99 | 100 | ## Inputs 101 | 102 | | Name | Description | Type | Default | Required | 103 | |------|-------------|------|---------|:--------:| 104 | | [cluster\_name](#input\_cluster\_name) | Name of the Azure AKS cluster | `string` | `""` | no | 105 | | [custom\_user\_username](#input\_custom\_user\_username) | n/a | `string` | `""` | no | 106 | | [environment](#input\_environment) | Environment in which the infrastructure is being deployed (e.g., production, staging, development) | `string` | `"test"` | no | 107 | | [mysqldb\_custom\_credentials\_config](#input\_mysqldb\_custom\_credentials\_config) | Specify the configuration settings for MySQL to pass custom credentials during creation | `any` |
{
"custom_user_password": "",
"custom_username": "",
"exporter_password": "",
"exporter_user": "",
"replication_password": "",
"replication_user": "",
"root_password": "",
"root_user": ""
}
| no | 108 | | [mysqldb\_custom\_credentials\_enabled](#input\_mysqldb\_custom\_credentials\_enabled) | Specifies whether to enable custom credentials for MySQL database. | `bool` | `false` | no | 109 | | [name](#input\_name) | Name identifier for module to be added as suffix to resources | `string` | `"test"` | no | 110 | | [resource\_group\_location](#input\_resource\_group\_location) | Azure region | `string` | `"East US"` | no | 111 | | [resource\_group\_name](#input\_resource\_group\_name) | Azure Resource Group name | `string` | `""` | no | 112 | | [storage\_account\_name](#input\_storage\_account\_name) | n/a | `string` | `""` | no | 113 | | [storage\_resource\_group\_name](#input\_storage\_resource\_group\_name) | Azure Storage account Resource Group name | `string` | `""` | no | 114 | | [store\_password\_to\_secret\_manager](#input\_store\_password\_to\_secret\_manager) | Specifies whether to store the credentials in GCP secret manager. | `bool` | `false` | no | 115 | 116 | ## Outputs 117 | 118 | | Name | Description | 119 | |------|-------------| 120 | | [custom\_user\_password](#output\_custom\_user\_password) | custom user's password of mysqldb | 121 | | [metric\_exporter\_pasword](#output\_metric\_exporter\_pasword) | mysqldb\_exporter user's password of mysqldb | 122 | | [mysqldb\_replication\_user\_password](#output\_mysqldb\_replication\_user\_password) | replicator user's password of mysqldb | 123 | | [root\_password](#output\_root\_password) | Root user's password of mysqldb | 124 | 125 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## MySQL DB Terraform Module 2 | 3 | 4 |
5 | This module simplifies deploying a MySQL database on Kubernetes with flexible configuration options, including storage class, volume sizes, and architecture. It supports backups, restores, and deploying exporters for Grafana metrics.

It can create namespaces and configure recovery windows for AWS Secrets Manager, Azure Key Vault, and GCP Secrets Manager. This module enables easy deployment of highly available MySQL databases on AWS EKS, Azure AKS, and GCP GKE with extensive customization options. 6 | 7 | ## Supported Versions: 8 | 9 | | MysqlDB Helm Chart Version | K8s supported version (EKS, AKS & GKE) | 10 | | :-----: | :--- | 11 | | **9.2.0** | **1.23,1.24,1.25,1.26,1.27** | 12 | 13 | 14 | ## Usage Example 15 | 16 | ```hcl 17 | locals { 18 | name = "mysql" 19 | region = "us-east-2" 20 | environment = "prod" 21 | additional_tags = { 22 | Owner = "organization_name" 23 | Expires = "Never" 24 | Department = "Engineering" 25 | } 26 | create_namespace = true 27 | namespace = "mysql" 28 | store_password_to_secret_manager = false 29 | mysqldb_custom_credentials_enabled = true 30 | mysqldb_custom_credentials_config = { 31 | root_user = "root" 32 | root_password = "RJDRIFsYC8ZS1WQuV0ps" 33 | custom_username = "admin" 34 | custom_user_password = "NCPFUKEMd7rrWuvMAa73" 35 | replication_user = "replicator" 36 | replication_password = "nvAHhm1uGQNYWVw6ZyAH" 37 | exporter_user = "mysqld_exporter" 38 | exporter_password = "ZawhvpueAehRdKFlbjaq" 39 | } 40 | custom_user_username = "custom" 41 | } 42 | 43 | module "aws" { 44 | source = "saturnops/mysql/kubernetes//modules/resources/aws" 45 | cluster_name = "prod-eks" 46 | environment = "prod" 47 | name = "mysql" 48 | namespace = local.namespace 49 | store_password_to_secret_manager = true 50 | mysqldb_custom_credentials_enabled = true 51 | mysqldb_custom_credentials_config = { 52 | root_user = "root" 53 | root_password = "RJDRIFsYC8ZS1WQuV0ps" 54 | custom_username = "admin" 55 | custom_user_password = "NCPFUKEMd7rrWuvMAa73" 56 | replication_user = "replicator" 57 | replication_password = "nvAHhm1uGQNYWVw6ZyAH" 58 | exporter_user = "mysqld_exporter" 59 | exporter_password = "ZawhvpueAehRdKFlbjaq" 60 | } 61 | custom_user_username = mysqldb_custom_credentials_enabled ? "" : "custome_username" 62 | } 63 | 64 | module "mysql" { 65 | source = "saturnops/mysql/kubernetes" 66 | create_namespace = local.create_namespace 67 | namespace = local.namespace 68 | mysqldb_config = { 69 | name = "mysql" 70 | app_version = "8.0.29-debian-11-r9" 71 | environment = "prod" 72 | values_yaml = "" 73 | architecture = "replication" 74 | custom_database = "test_db" 75 | storage_class_name = "gp2" 76 | custom_user_username = local.mysqldb_custom_credentials_enabled ? "" : local.custom_user_username 77 | primary_db_volume_size = "10Gi" 78 | secondary_db_volume_size = "10Gi" 79 | secondary_db_replica_count = 2 80 | store_password_to_secret_manager = true 81 | } 82 | mysqldb_custom_credentials_enabled = local.mysqldb_custom_credentials_enabled 83 | mysqldb_custom_credentials_config = local.mysqldb_custom_credentials_config 84 | root_password = local.mysqldb_custom_credentials_enabled ? "" : module.aws.root_password 85 | metric_exporter_pasword = local.mysqldb_custom_credentials_enabled ? "" : module.aws.metric_exporter_pasword 86 | mysqldb_replication_user_password = local.mysqldb_custom_credentials_enabled ? "" : module.aws.mysqldb_replication_user_password 87 | custom_user_password = local.mysqldb_custom_credentials_enabled ? "" : module.aws.custom_user_password 88 | bucket_provider_type = "s3" 89 | iam_role_arn_backup = module.aws.iam_role_arn_backup 90 | mysqldb_backup_enabled = true 91 | mysqldb_backup_config = { 92 | mysql_database_name = "" 93 | bucket_uri = "s3://bucket_name" 94 | s3_bucket_region = "" 95 | cron_for_full_backup = "*/5 * * * *" 96 | } 97 | mysqldb_restore_enabled = true 98 | iam_role_arn_restore = module.aws.iam_role_arn_restore 99 | mysqldb_restore_config = { 100 | bucket_uri = "s3://bucket_name/mysqldump_20230710_120501.zip" 101 | file_name = "mysqldump_20230710_120501.zip" 102 | s3_bucket_region = "" 103 | } 104 | mysqldb_exporter_enabled = true 105 | } 106 | 107 | 108 | ``` 109 | - Refer [AWS examples](https://github.com/saturnops/terraform-kubernetes-mysql/tree/main/examples/complete/aws) for more details. 110 | - Refer [Azure examples](https://github.com/saturnops/terraform-kubernetes-mysql/tree/main/examples/complete/azure) for more details. 111 | - Refer [GCP examples](https://github.com/saturnops/terraform-kubernetes-mysql/tree/main/examples/complete/gcp) for more details. 112 | 113 | ## IAM Permissions 114 | The required IAM permissions to create resources from this module can be found [here](https://github.com/saturnops/terraform-kubernetes-mysql/blob/main/IAM.md) 115 | 116 | ## MySQL Backup and Restore 117 | This module provides functionality to automate the backup and restore process for MySQL databases using AWS S3 buckets. It allows users to easily schedule backups, restore databases from backups stored in S3, and manage access permissions using AWS IAM roles. 118 | Features 119 | ### Backup 120 | - Users can schedule full backups. 121 | - upports specifying individual database names for backup or backing up all databases except system databases. 122 | - Backups are stored in specified S3 buckets. 123 | ### Restore 124 | - Users can restore MySQL databases from backups stored in S3 buckets. 125 | - Supports specifying the backup file to restore from and the target S3 bucket region. 126 | ### IAM Role for Permissions 127 | - Users need to provide an IAM role for the module to access the specified S3 bucket and perform backup and restore operations. 128 | ## Module Inputs 129 | ### Backup Configuration 130 | - command using to do backup: 131 | ``` 132 | mysqldump -h$HOST -u$USER -p$PASSWORD --databases db_name > full-backup.sql 133 | ``` 134 | - mysql_database_name: The name of the MySQL database to backup. Leave blank to backup all databases except system databases. 135 | - bucket_uri: The URI of the S3 bucket where backups will be stored. 136 | - s3_bucket_region: The region of the S3 bucket. 137 | - cron_for_full_backup: The cron expression for scheduling full backups. 138 | ### Restore Configuration 139 | - mysqldb_restore_config: Configuration for restoring databases.bucket_uri: The URI of the S3 bucket containing the backup file. 140 | - file_name: The name of the backup file to restore. 141 | - s3_bucket_region: The region of the S3 bucket containing the backup file. 142 | ## Important Notes 143 | 1. In order to enable the exporter, it is required to deploy Prometheus/Grafana first. 144 | 2. The exporter is a tool that extracts metrics data from an application or system and makes it available to be scraped by Prometheus. 145 | 3. Prometheus is a monitoring system that collects metrics data from various sources, including exporters, and stores it in a time-series database. 146 | 4. Grafana is a data visualization and dashboard tool that works with Prometheus and other data sources to display the collected metrics in a user-friendly way. 147 | 5. To deploy Prometheus/Grafana, please follow the installation instructions for each tool in their respective documentation. 148 | 6. Once Prometheus and Grafana are deployed, the exporter can be configured to scrape metrics data from your application or system and send it to Prometheus. 149 | 7. Finally, you can use Grafana to create custom dashboards and visualize the metrics data collected by Prometheus. 150 | 8. This module is compatible with EKS, AKS & GKE which is great news for users deploying the module on an AWS, Azure & GCP cloud. Review the module's documentation, meet specific configuration requirements, and test thoroughly after deployment to ensure everything works as expected. 151 | 152 | ## Requirements 153 | 154 | No requirements. 155 | 156 | ## Providers 157 | 158 | | Name | Version | 159 | |------|---------| 160 | | [helm](#provider\_helm) | n/a | 161 | | [kubernetes](#provider\_kubernetes) | n/a | 162 | 163 | ## Modules 164 | 165 | No modules. 166 | 167 | ## Resources 168 | 169 | | Name | Type | 170 | |------|------| 171 | | [helm_release.mysqldb](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | 172 | | [helm_release.mysqldb_backup](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | 173 | | [helm_release.mysqldb_restore](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | 174 | | [kubernetes_namespace.mysqldb](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource | 175 | 176 | ## Inputs 177 | 178 | | Name | Description | Type | Default | Required | 179 | |------|-------------|------|---------|:--------:| 180 | | [app\_version](#input\_app\_version) | Version of the MySQL application that will be deployed. | `string` | `"8.0.29-debian-11-r9"` | no | 181 | | [azure\_container\_name](#input\_azure\_container\_name) | Azure container name | `string` | `""` | no | 182 | | [azure\_storage\_account\_key](#input\_azure\_storage\_account\_key) | Azure storage account key | `string` | `""` | no | 183 | | [azure\_storage\_account\_name](#input\_azure\_storage\_account\_name) | Azure storage account name | `string` | `""` | no | 184 | | [bucket\_provider\_type](#input\_bucket\_provider\_type) | Choose what type of provider you want (s3, gcs) | `string` | `"gcs"` | no | 185 | | [chart\_version](#input\_chart\_version) | Version of the Mysql chart that will be used to deploy MySQL application. | `string` | `"9.2.0"` | no | 186 | | [cluster\_name](#input\_cluster\_name) | Specifies the name of the EKS cluster to deploy the MySQL application on. | `string` | `""` | no | 187 | | [create\_namespace](#input\_create\_namespace) | Specify whether or not to create the namespace if it does not already exist. Set it to true to create the namespace. | `string` | `true` | no | 188 | | [custom\_user\_password](#input\_custom\_user\_password) | custom user password for MongoDB | `string` | `""` | no | 189 | | [iam\_role\_arn\_backup](#input\_iam\_role\_arn\_backup) | IAM role ARN for backup (AWS) | `string` | `""` | no | 190 | | [iam\_role\_arn\_restore](#input\_iam\_role\_arn\_restore) | IAM role ARN for restore (AWS) | `string` | `""` | no | 191 | | [metric\_exporter\_pasword](#input\_metric\_exporter\_pasword) | Metric exporter password for MongoDB | `string` | `""` | no | 192 | | [mysqldb\_backup\_config](#input\_mysqldb\_backup\_config) | configuration options for MySQL database backups. It includes properties such as the S3 bucket URI, the S3 bucket region, cron expression for full backups and the database name to take backup of particular database or if send empty it backup whole database | `any` |
{
"bucket_uri": "",
"cron_for_full_backup": "",
"mysql_database_name": "",
"s3_bucket_region": ""
}
| no | 193 | | [mysqldb\_backup\_enabled](#input\_mysqldb\_backup\_enabled) | Specifies whether to enable backups for MySQL database. | `bool` | `false` | no | 194 | | [mysqldb\_config](#input\_mysqldb\_config) | Specify the configuration settings for MySQL, including the name, environment, storage options, replication settings, and custom YAML values. | `any` |
{
"architecture": "",
"custom_database": "",
"custom_user_username": "",
"environment": "",
"name": "",
"primary_db_volume_size": "",
"secondary_db_replica_count": 1,
"secondary_db_volume_size": "",
"storage_class_name": "",
"store_password_to_secret_manager": true,
"values_yaml": ""
}
| no | 195 | | [mysqldb\_custom\_credentials\_config](#input\_mysqldb\_custom\_credentials\_config) | Specify the configuration settings for MySQL to pass custom credentials during creation | `any` |
{
"custom_user_password": "",
"custom_username": "",
"exporter_password": "",
"exporter_user": "",
"replication_password": "",
"replication_user": "",
"root_password": "",
"root_user": ""
}
| no | 196 | | [mysqldb\_custom\_credentials\_enabled](#input\_mysqldb\_custom\_credentials\_enabled) | Specifies whether to enable custom credentials for MySQL database. | `bool` | `false` | no | 197 | | [mysqldb\_exporter\_enabled](#input\_mysqldb\_exporter\_enabled) | Specify whether or not to deploy Mysql exporter to collect Mysql metrics for monitoring in Grafana. | `bool` | `false` | no | 198 | | [mysqldb\_replication\_user\_password](#input\_mysqldb\_replication\_user\_password) | Replicator password for MongoDB | `string` | `""` | no | 199 | | [mysqldb\_restore\_config](#input\_mysqldb\_restore\_config) | Configuration options for restoring dump to the MySQL database. | `any` |
{
"bucket_uri": "",
"file_name": "",
"s3_bucket_region": ""
}
| no | 200 | | [mysqldb\_restore\_enabled](#input\_mysqldb\_restore\_enabled) | Specifies whether to enable restoring dump to the MySQL database. | `bool` | `false` | no | 201 | | [namespace](#input\_namespace) | Name of the Kubernetes namespace where the MYSQL deployment will be deployed. | `string` | `"mysqldb"` | no | 202 | | [project\_id](#input\_project\_id) | Google Cloud project ID | `string` | `""` | no | 203 | | [recovery\_window\_aws\_secret](#input\_recovery\_window\_aws\_secret) | Number of days that AWS Secrets Manager will wait before deleting a secret. This value can be set to 0 to force immediate deletion, or to a value between 7 and 30 days to allow for recovery. | `number` | `0` | no | 204 | | [resource\_group\_location](#input\_resource\_group\_location) | Azure region | `string` | `"East US"` | no | 205 | | [resource\_group\_name](#input\_resource\_group\_name) | Azure Resource Group name | `string` | `""` | no | 206 | | [root\_password](#input\_root\_password) | Root password for MongoDB | `string` | `""` | no | 207 | | [service\_account\_backup](#input\_service\_account\_backup) | Service account for backup (GCP) | `string` | `""` | no | 208 | | [service\_account\_restore](#input\_service\_account\_restore) | Service account for restore (GCP) | `string` | `""` | no | 209 | 210 | ## Outputs 211 | 212 | | Name | Description | 213 | |------|-------------| 214 | | [mysqldb\_credential](#output\_mysqldb\_credential) | MySQL credentials used for accessing the MySQL database. | 215 | | [mysqldb\_endpoints](#output\_mysqldb\_endpoints) | MySQL endpoints in the Kubernetes cluster. | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | ## 224 | 225 | 226 | 227 | 228 | 229 | Please give our GitHub repository a ⭐️ to show your support and increase its visibility. 230 | 231 | 232 | 233 | 234 | 235 | -------------------------------------------------------------------------------- /helm/values/mysqldb/values.yaml: -------------------------------------------------------------------------------- 1 | ## @section Global parameters 2 | ## Global Docker image parameters 3 | ## Please, note that this will override the image parameters, including dependencies, configured to use the global value 4 | ## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass 5 | 6 | ## @param global.imageRegistry Global Docker image registry 7 | ## @param global.imagePullSecrets Global Docker registry secret names as an array 8 | ## @param global.storageClass Global StorageClass for Persistent Volume(s) 9 | ## 10 | global: 11 | imageRegistry: "" 12 | ## E.g. 13 | ## imagePullSecrets: 14 | ## - myRegistryKeySecretName 15 | ## 16 | imagePullSecrets: [] 17 | storageClass: "${storage_class_name}" 18 | 19 | mysql_metrics_exporter: 20 | password: ${metrics_exporter_password} 21 | 22 | ## @section Common parameters 23 | 24 | ## @param kubeVersion Force target Kubernetes version (using Helm capabilities if not set) 25 | ## 26 | kubeVersion: "" 27 | ## @param nameOverride String to partially override common.names.fullname template (will maintain the release name) 28 | ## 29 | nameOverride: "" 30 | ## @param fullnameOverride String to fully override common.names.fullname template 31 | ## 32 | fullnameOverride: "" 33 | ## @param namespaceOverride String to fully override common.names.namespace 34 | ## 35 | namespaceOverride: "" 36 | ## @param clusterDomain Cluster domain 37 | ## 38 | clusterDomain: cluster.loterrcal 39 | ## @param commonAnnotations Common annotations to add to all MySQL resources (sub-charts are not considered). Evaluated as a template 40 | ## 41 | commonAnnotations: 42 | co.elastic.logs/enabled: "true" 43 | co.elastic.logs/module: mysql 44 | ## @param commonLabels Common labels to add to all MySQL resources (sub-charts are not considered). Evaluated as a template 45 | ## 46 | commonLabels: 47 | co.elastic.logs/module: "mysql" 48 | ## @param extraDeploy Array with extra yaml to deploy with the chart. Evaluated as a template 49 | ## 50 | extraDeploy: [] 51 | 52 | ## Enable diagnostic mode in the deployment 53 | ## 54 | diagnosticMode: 55 | ## @param diagnosticMode.enabled Enable diagnostic mode (all probes will be disabled and the command will be overridden) 56 | ## 57 | enabled: false 58 | ## @param diagnosticMode.command Command to override all containers in the deployment 59 | ## 60 | command: 61 | - sleep 62 | ## @param diagnosticMode.args Args to override all containers in the deployment 63 | ## 64 | args: 65 | - infinity 66 | 67 | ## @section MySQL common parameters 68 | 69 | ## Bitnami MySQL image 70 | ## ref: https://hub.docker.com/r/bitnami/mysql/tags/ 71 | ## @param image.registry MySQL image registry 72 | ## @param image.repository MySQL image repository 73 | ## @param image.tag MySQL image tag (immutable tags are recommended) 74 | ## @param image.pullPolicy MySQL image pull policy 75 | ## @param image.pullSecrets Specify docker-registry secret names as an array 76 | ## @param image.debug Specify if debug logs should be enabled 77 | ## 78 | image: 79 | registry: docker.io 80 | repository: bitnami/mysql 81 | tag: ${app_version} 82 | ## Specify a imagePullPolicy 83 | ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' 84 | ## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images 85 | ## 86 | pullPolicy: IfNotPresent 87 | ## Optionally specify an array of imagePullSecrets (secrets must be manually created in the namespace) 88 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ 89 | ## Example: 90 | ## pullSecrets: 91 | ## - myRegistryKeySecretName 92 | ## 93 | pullSecrets: [] 94 | ## Set to true if you would like to see extra information on logs 95 | ## It turns BASH and/or NAMI debugging in the image 96 | ## 97 | debug: false 98 | ## @param architecture MySQL architecture (`standalone` or `replication`) 99 | ## 100 | architecture: ${architecture} 101 | ## MySQL Authentication parameters 102 | ## 103 | auth: 104 | ## @param auth.rootPassword Password for the `root` user. Ignored if existing secret is provided 105 | ## ref: https://github.com/bitnami/bitnami-docker-mysql#setting-the-root-password-on-first-run 106 | ## 107 | rootPassword: "${mysqldb_root_password}" 108 | ## @param auth.createDatabase Wheter to create the .Values.auth.database or not 109 | ## ref: https://github.com/bitnami/bitnami-docker-mysql/blob/master/README.md#creating-a-database-on-first-run 110 | ## 111 | createDatabase: true 112 | ## @param auth.database Name for a custom database to create 113 | ## ref: https://github.com/bitnami/bitnami-docker-mysql/blob/master/README.md#creating-a-database-on-first-run 114 | ## 115 | database: ${custom_database} 116 | ## @param auth.username Name for a custom user to create 117 | ## ref: https://github.com/bitnami/bitnami-docker-mysql/blob/master/README.md#creating-a-database-user-on-first-run 118 | ## 119 | username: "${custom_user_username}" 120 | ## @param auth.password Password for the new user. Ignored if existing secret is provided 121 | ## 122 | password: "${custom_user_password}" 123 | ## @param auth.replicationUser MySQL replication user 124 | ## ref: https://github.com/bitnami/bitnami-docker-mysql#setting-up-a-replication-cluster 125 | ## 126 | replicationUser: replicator 127 | ## @param auth.replicationPassword MySQL replication user password. Ignored if existing secret is provided 128 | ## 129 | replicationPassword: "${replication_password}" 130 | ## @param auth.existingSecret Use existing secret for password details. The secret has to contain the keys `mysql-root-password`, `mysql-replication-password` and `mysql-password` 131 | ## NOTE: When it's set the auth.rootPassword, auth.password, auth.replicationPassword are ignored. 132 | ## 133 | existingSecret: "" 134 | ## @param auth.usePasswordFiles Mount credentials as files instead of using an environment variable 135 | ## 136 | usePasswordFiles: false 137 | ## @param auth.customPasswordFiles Use custom password files when `auth.usePasswordFiles` is set to `true`. Define path for keys `root` and `user`, also define `replicator` if `architecture` is set to `replication` 138 | ## Example: 139 | ## customPasswordFiles: 140 | ## root: /vault/secrets/mysql-root 141 | ## user: /vault/secrets/mysql-user 142 | ## replicator: /vault/secrets/mysql-replicator 143 | ## 144 | customPasswordFiles: {} 145 | ## @param initdbScripts Dictionary of initdb scripts 146 | ## Specify dictionary of scripts to be run at first boot 147 | ## Example: 148 | ## initdbScripts: 149 | ## my_init_script.sh: | 150 | ## #!/bin/bash 151 | ## echo "Do something." 152 | ## 153 | initdbScripts: {} 154 | # init.sql: | 155 | # CREATE DATABASE ratings DEFAULT CHARACTER SET 'utf8'; 156 | # USE ratings; 157 | # CREATE TABLE ratings (sku varchar(80) NOT NULL, 158 | # avg_rating DECIMAL(3, 2) NOT NULL, 159 | # rating_count INT NOT NULL, 160 | # PRIMARY KEY (sku) 161 | # ) ENGINE=InnoDB; 162 | ## @param initdbScriptsConfigMap ConfigMap with the initdb scripts (Note: Overrides `initdbScripts`) 163 | ## 164 | initdbScriptsConfigMap: "" 165 | 166 | ## @section MySQL Primary parameters 167 | 168 | primary: 169 | ## @param primary.command Override default container command on MySQL Primary container(s) (useful when using custom images) 170 | ## 171 | command: [] 172 | ## @param primary.args Override default container args on MySQL Primary container(s) (useful when using custom images) 173 | ## 174 | args: [] 175 | ## @param primary.lifecycleHooks for the MySQL Primary container(s) to automate configuration before or after startup 176 | ## 177 | lifecycleHooks: {} 178 | ## @param primary.hostAliases Deployment pod host aliases 179 | ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ 180 | ## 181 | hostAliases: [] 182 | ## @param primary.configuration [string] Configure MySQL Primary with a custom my.cnf file 183 | ## ref: https://mysql.com/kb/en/mysql/configuring-mysql-with-mycnf/#example-of-configuration-file 184 | ## 185 | configuration: |- 186 | [mysqld] 187 | default_authentication_plugin=mysql_native_password 188 | skip-name-resolve 189 | explicit_defaults_for_timestamp 190 | basedir=/opt/bitnami/mysql 191 | plugin_dir=/opt/bitnami/mysql/lib/plugin 192 | port=3306 193 | socket=/opt/bitnami/mysql/tmp/mysql.sock 194 | datadir=/bitnami/mysql/data 195 | tmpdir=/opt/bitnami/mysql/tmp 196 | max_allowed_packet=16M 197 | bind-address=0.0.0.0 198 | pid-file=/opt/bitnami/mysql/tmp/mysqld.pid 199 | log_error=/opt/bitnami/mysql/logs/mysqld.log 200 | character-set-server=UTF8 201 | collation-server=utf8_general_ci 202 | slow_query_log=1 203 | slow_query_log_file=/bitnami/mysql/slow-log.log 204 | long_query_time=10.0 205 | 206 | [client] 207 | port=3306 208 | socket=/opt/bitnami/mysql/tmp/mysql.sock 209 | default-character-set=UTF8 210 | plugin_dir=/opt/bitnami/mysql/lib/plugin 211 | 212 | [manager] 213 | port=3306 214 | socket=/opt/bitnami/mysql/tmp/mysql.sock 215 | pid-file=/opt/bitnami/mysql/tmp/mysqld.pid 216 | ## @param primary.existingConfigmap Name of existing ConfigMap with MySQL Primary configuration. 217 | ## NOTE: When it's set the 'configuration' parameter is ignored 218 | ## 219 | existingConfigmap: "" 220 | ## @param primary.updateStrategy.type Update strategy type for the MySQL primary statefulset 221 | ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies 222 | ## 223 | updateStrategy: 224 | type: RollingUpdate 225 | ## @param primary.podAnnotations Additional pod annotations for MySQL primary pods 226 | ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ 227 | ## 228 | podAnnotations: 229 | co.elastic.logs/enabled: "true" 230 | co.elastic.logs/module: mysql 231 | ## @param primary.podAffinityPreset MySQL primary pod affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` 232 | ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity 233 | ## 234 | podAffinityPreset: "" 235 | ## @param primary.podAntiAffinityPreset MySQL primary pod anti-affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` 236 | ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity 237 | ## 238 | podAntiAffinityPreset: soft 239 | ## MySQL Primary node affinity preset 240 | ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity 241 | ## 242 | nodeAffinityPreset: 243 | ## @param primary.nodeAffinityPreset.type MySQL primary node affinity preset type. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` 244 | ## 245 | type: "" 246 | ## @param primary.nodeAffinityPreset.key MySQL primary node label key to match Ignored if `primary.affinity` is set. 247 | ## E.g. 248 | ## key: "kubernetes.io/e2e-az-name" 249 | ## 250 | key: "" 251 | ## @param primary.nodeAffinityPreset.values MySQL primary node label values to match. Ignored if `primary.affinity` is set. 252 | ## E.g. 253 | ## values: 254 | ## - e2e-az1 255 | ## - e2e-az2 256 | ## 257 | values: [] 258 | ## @param primary.affinity Affinity for MySQL primary pods assignment 259 | ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity 260 | ## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set 261 | ## 262 | affinity: {} 263 | # nodeAffinity: 264 | # requiredDuringSchedulingIgnoredDuringExecution: 265 | # nodeSelectorTerms: 266 | # - matchExpressions: 267 | # - key: "App-On-Demand" 268 | # operator: In 269 | # values: 270 | # - "true" 271 | ## @param primary.nodeSelector Node labels for MySQL primary pods assignment 272 | ## ref: https://kubernetes.io/docs/user-guide/node-selection/ 273 | ## 274 | nodeSelector: {} 275 | ## @param primary.tolerations Tolerations for MySQL primary pods assignment 276 | ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ 277 | ## 278 | tolerations: [] 279 | ## @param primary.priorityClassName MySQL primary pods' priorityClassName 280 | ## 281 | priorityClassName: "" 282 | ## @param primary.schedulerName Name of the k8s scheduler (other than default) 283 | ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ 284 | ## 285 | schedulerName: "" 286 | ## @param primary.terminationGracePeriodSeconds In seconds, time the given to the MySQL primary pod needs to terminate gracefully 287 | ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods 288 | ## 289 | terminationGracePeriodSeconds: "" 290 | ## @param primary.topologySpreadConstraints Topology Spread Constraints for pod assignment 291 | ## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ 292 | ## The value is evaluated as a template 293 | ## 294 | topologySpreadConstraints: [] 295 | ## @param primary.podManagementPolicy podManagementPolicy to manage scaling operation of MySQL primary pods 296 | ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies 297 | ## 298 | podManagementPolicy: "" 299 | ## MySQL primary Pod security context 300 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod 301 | ## @param primary.podSecurityContext.enabled Enable security context for MySQL primary pods 302 | ## @param primary.podSecurityContext.fsGroup Group ID for the mounted volumes' filesystem 303 | ## 304 | podSecurityContext: 305 | enabled: true 306 | fsGroup: 1001 307 | ## MySQL primary container security context 308 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container 309 | ## @param primary.containerSecurityContext.enabled MySQL primary container securityContext 310 | ## @param primary.containerSecurityContext.runAsUser User ID for the MySQL primary container 311 | ## @param primary.containerSecurityContext.runAsNonRoot Set MySQL primary container's Security Context runAsNonRoot 312 | ## 313 | containerSecurityContext: 314 | enabled: true 315 | runAsUser: 1001 316 | runAsNonRoot: true 317 | ## MySQL primary container's resource requests and limits 318 | ## ref: https://kubernetes.io/docs/user-guide/compute-resources/ 319 | ## We usually recommend not to specify default resources and to leave this as a conscious 320 | ## choice for the user. This also increases chances charts run on environments with little 321 | ## resources, such as Minikube. If you do want to specify resources, uncomment the following 322 | ## lines, adjust them as necessary, and remove the curly braces after 'resources:'. 323 | ## @param primary.resources.limits The resources limits for MySQL primary containers 324 | ## @param primary.resources.requests The requested resources for MySQL primary containers 325 | ## 326 | resources: 327 | ## Example: 328 | ## limits: 329 | ## cpu: 250m 330 | ## memory: 256Mi 331 | limits: 332 | cpu: 250m 333 | memory: 750Mi 334 | ## Examples: 335 | ## requests: 336 | ## cpu: 250m 337 | ## memory: 256Mi 338 | requests: 339 | cpu: 100m 340 | memory: 500Mi 341 | ## Configure extra options for liveness probe 342 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes 343 | ## @param primary.livenessProbe.enabled Enable livenessProbe 344 | ## @param primary.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe 345 | ## @param primary.livenessProbe.periodSeconds Period seconds for livenessProbe 346 | ## @param primary.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe 347 | ## @param primary.livenessProbe.failureThreshold Failure threshold for livenessProbe 348 | ## @param primary.livenessProbe.successThreshold Success threshold for livenessProbe 349 | ## 350 | livenessProbe: 351 | enabled: true 352 | initialDelaySeconds: 5 353 | periodSeconds: 10 354 | timeoutSeconds: 1 355 | failureThreshold: 3 356 | successThreshold: 1 357 | ## Configure extra options for readiness probe 358 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes 359 | ## @param primary.readinessProbe.enabled Enable readinessProbe 360 | ## @param primary.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe 361 | ## @param primary.readinessProbe.periodSeconds Period seconds for readinessProbe 362 | ## @param primary.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe 363 | ## @param primary.readinessProbe.failureThreshold Failure threshold for readinessProbe 364 | ## @param primary.readinessProbe.successThreshold Success threshold for readinessProbe 365 | ## 366 | readinessProbe: 367 | enabled: true 368 | initialDelaySeconds: 5 369 | periodSeconds: 10 370 | timeoutSeconds: 1 371 | failureThreshold: 3 372 | successThreshold: 1 373 | ## Configure extra options for startupProbe probe 374 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes 375 | ## @param primary.startupProbe.enabled Enable startupProbe 376 | ## @param primary.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe 377 | ## @param primary.startupProbe.periodSeconds Period seconds for startupProbe 378 | ## @param primary.startupProbe.timeoutSeconds Timeout seconds for startupProbe 379 | ## @param primary.startupProbe.failureThreshold Failure threshold for startupProbe 380 | ## @param primary.startupProbe.successThreshold Success threshold for startupProbe 381 | ## 382 | startupProbe: 383 | enabled: true 384 | initialDelaySeconds: 15 385 | periodSeconds: 10 386 | timeoutSeconds: 1 387 | failureThreshold: 10 388 | successThreshold: 1 389 | ## @param primary.customLivenessProbe Override default liveness probe for MySQL primary containers 390 | ## 391 | customLivenessProbe: {} 392 | ## @param primary.customReadinessProbe Override default readiness probe for MySQL primary containers 393 | ## 394 | customReadinessProbe: {} 395 | ## @param primary.customStartupProbe Override default startup probe for MySQL primary containers 396 | ## 397 | customStartupProbe: {} 398 | ## @param primary.extraFlags MySQL primary additional command line flags 399 | ## Can be used to specify command line flags, for example: 400 | ## E.g. 401 | ## extraFlags: "--max-connect-errors=1000 --max_connections=155" 402 | ## 403 | extraFlags: "" 404 | ## @param primary.extraEnvVars Extra environment variables to be set on MySQL primary containers 405 | ## E.g. 406 | ## extraEnvVars: 407 | ## - name: TZ 408 | ## value: "Europe/Paris" 409 | ## 410 | extraEnvVars: [] 411 | ## @param primary.extraEnvVarsCM Name of existing ConfigMap containing extra env vars for MySQL primary containers 412 | ## 413 | extraEnvVarsCM: "" 414 | ## @param primary.extraEnvVarsSecret Name of existing Secret containing extra env vars for MySQL primary containers 415 | ## 416 | extraEnvVarsSecret: "" 417 | ## Enable persistence using Persistent Volume Claims 418 | ## ref: https://kubernetes.io/docs/user-guide/persistent-volumes/ 419 | ## 420 | persistence: 421 | ## @param primary.persistence.enabled Enable persistence on MySQL primary replicas using a `PersistentVolumeClaim`. If false, use emptyDir 422 | ## 423 | enabled: true 424 | ## @param primary.persistence.existingClaim Name of an existing `PersistentVolumeClaim` for MySQL primary replicas 425 | ## NOTE: When it's set the rest of persistence parameters are ignored 426 | ## 427 | existingClaim: "" 428 | ## @param primary.persistence.storageClass MySQL primary persistent volume storage Class 429 | ## If defined, storageClassName: 430 | ## If set to "-", storageClassName: "", which disables dynamic provisioning 431 | ## If undefined (the default) or set to null, no storageClassName spec is 432 | ## set, choosing the default provisioner. (gp2 on AWS, standard on 433 | ## GKE, AWS & OpenStack) 434 | ## 435 | storageClass: "${storage_class_name}" 436 | ## @param primary.persistence.annotations MySQL primary persistent volume claim annotations 437 | ## 438 | annotations: {} 439 | ## @param primary.persistence.accessModes MySQL primary persistent volume access Modes 440 | ## 441 | accessModes: 442 | - ReadWriteOnce 443 | ## @param primary.persistence.size MySQL primary persistent volume size 444 | ## 445 | size: ${primary_pod_size} 446 | ## @param primary.persistence.selector Selector to match an existing Persistent Volume 447 | ## selector: 448 | ## matchLabels: 449 | ## app: my-app 450 | ## 451 | selector: {} 452 | ## @param primary.extraVolumes Optionally specify extra list of additional volumes to the MySQL Primary pod(s) 453 | ## 454 | extraVolumes: [] 455 | ## @param primary.extraVolumeMounts Optionally specify extra list of additional volumeMounts for the MySQL Primary container(s) 456 | ## 457 | extraVolumeMounts: [] 458 | ## @param primary.initContainers Add additional init containers for the MySQL Primary pod(s) 459 | ## 460 | initContainers: [] 461 | ## @param primary.sidecars Add additional sidecar containers for the MySQL Primary pod(s) 462 | ## 463 | sidecars: 464 | - name: slow-log 465 | image: busybox:1.28 466 | args: [/bin/sh, -c, 'tail -n+1 -F /bitnami/mysql/slow-log.log'] 467 | volumeMounts: 468 | - name: data 469 | mountPath: /bitnami/mysql 470 | resources: 471 | ## Example: 472 | ## limits: 473 | ## cpu: 100m 474 | ## memory: 256Mi 475 | limits: {} 476 | ## Examples: 477 | ## requests: 478 | ## cpu: 100m 479 | ## memory: 256Mi 480 | requests: {} 481 | 482 | 483 | ## MySQL Primary Service parameters 484 | ## 485 | service: 486 | ## @param primary.service.type MySQL Primary K8s service type 487 | ## 488 | type: ClusterIP 489 | ## @param primary.service.ports.mysql MySQL Primary K8s service port 490 | ## 491 | ports: 492 | mysql: 3306 493 | ## @param primary.service.nodePorts.mysql MySQL Primary K8s service node port 494 | ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport 495 | ## 496 | nodePorts: 497 | mysql: "" 498 | ## @param primary.service.clusterIP MySQL Primary K8s service clusterIP IP 499 | ## e.g: 500 | ## clusterIP: None 501 | ## 502 | clusterIP: "" 503 | ## @param primary.service.loadBalancerIP MySQL Primary loadBalancerIP if service type is `LoadBalancer` 504 | ## Set the LoadBalancer service type to internal only 505 | ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer 506 | ## 507 | loadBalancerIP: "" 508 | ## @param primary.service.externalTrafficPolicy Enable client source IP preservation 509 | ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip 510 | ## 511 | externalTrafficPolicy: Cluster 512 | ## @param primary.service.loadBalancerSourceRanges Addresses that are allowed when MySQL Primary service is LoadBalancer 513 | ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service 514 | ## E.g. 515 | ## loadBalancerSourceRanges: 516 | ## - 10.10.10.0/24 517 | ## 518 | loadBalancerSourceRanges: [] 519 | ## @param primary.service.extraPorts Extra ports to expose (normally used with the `sidecar` value) 520 | ## 521 | extraPorts: [] 522 | ## @param primary.service.annotations Additional custom annotations for MySQL primary service 523 | ## 524 | annotations: {} 525 | ## @param primary.service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" 526 | ## If "ClientIP", consecutive client requests will be directed to the same Pod 527 | ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies 528 | ## 529 | sessionAffinity: None 530 | ## @param primary.service.sessionAffinityConfig Additional settings for the sessionAffinity 531 | ## sessionAffinityConfig: 532 | ## clientIP: 533 | ## timeoutSeconds: 300 534 | ## 535 | sessionAffinityConfig: {} 536 | ## MySQL primary Pod Disruption Budget configuration 537 | ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ 538 | ## 539 | pdb: 540 | ## @param primary.pdb.create Enable/disable a Pod Disruption Budget creation for MySQL primary pods 541 | ## 542 | create: false 543 | ## @param primary.pdb.minAvailable Minimum number/percentage of MySQL primary pods that should remain scheduled 544 | ## 545 | minAvailable: 1 546 | ## @param primary.pdb.maxUnavailable Maximum number/percentage of MySQL primary pods that may be made unavailable 547 | ## 548 | maxUnavailable: "" 549 | ## @param primary.podLabels MySQL Primary pod label. If labels are same as commonLabels , this will take precedence 550 | ## 551 | podLabels: {} 552 | 553 | ## @section MySQL Secondary parameters 554 | 555 | secondary: 556 | ## @param secondary.replicaCount Number of MySQL secondary replicas 557 | ## 558 | replicaCount: ${secondary_pod_replica_count} 559 | ## @param secondary.hostAliases Deployment pod host aliases 560 | ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ 561 | ## 562 | hostAliases: [] 563 | ## @param secondary.command Override default container command on MySQL Secondary container(s) (useful when using custom images) 564 | ## 565 | command: [] 566 | ## @param secondary.args Override default container args on MySQL Secondary container(s) (useful when using custom images) 567 | ## 568 | args: [] 569 | ## @param secondary.lifecycleHooks for the MySQL Secondary container(s) to automate configuration before or after startup 570 | ## 571 | lifecycleHooks: {} 572 | ## @param secondary.configuration [string] Configure MySQL Secondary with a custom my.cnf file 573 | ## ref: https://mysql.com/kb/en/mysql/configuring-mysql-with-mycnf/#example-of-configuration-file 574 | ## 575 | configuration: |- 576 | [mysqld] 577 | default_authentication_plugin=mysql_native_password 578 | skip-name-resolve 579 | explicit_defaults_for_timestamp 580 | basedir=/opt/bitnami/mysql 581 | plugin_dir=/opt/bitnami/mysql/lib/plugin 582 | port=3306 583 | socket=/opt/bitnami/mysql/tmp/mysql.sock 584 | datadir=/bitnami/mysql/data 585 | tmpdir=/opt/bitnami/mysql/tmp 586 | max_allowed_packet=16M 587 | bind-address=0.0.0.0 588 | pid-file=/opt/bitnami/mysql/tmp/mysqld.pid 589 | log_error=/opt/bitnami/mysql/logs/mysqld.log 590 | character-set-server=UTF8 591 | collation-server=utf8_general_ci 592 | slow_query_log=1 593 | slow_query_log_file=/bitnami/mysql/slow-log.log 594 | long_query_time=10.0 595 | 596 | [client] 597 | port=3306 598 | socket=/opt/bitnami/mysql/tmp/mysql.sock 599 | default-character-set=UTF8 600 | plugin_dir=/opt/bitnami/mysql/lib/plugin 601 | 602 | [manager] 603 | port=3306 604 | socket=/opt/bitnami/mysql/tmp/mysql.sock 605 | pid-file=/opt/bitnami/mysql/tmp/mysqld.pid 606 | ## @param secondary.existingConfigmap Name of existing ConfigMap with MySQL Secondary configuration. 607 | ## NOTE: When it's set the 'configuration' parameter is ignored 608 | ## 609 | existingConfigmap: "" 610 | ## @param secondary.updateStrategy.type Update strategy type for the MySQL secondary statefulset 611 | ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies 612 | ## 613 | updateStrategy: 614 | type: RollingUpdate 615 | ## @param secondary.podAnnotations Additional pod annotations for MySQL secondary pods 616 | ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ 617 | ## 618 | podAnnotations: 619 | co.elastic.logs/enabled: "true" 620 | co.elastic.logs/module: mysql 621 | ## @param secondary.podAffinityPreset MySQL secondary pod affinity preset. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` 622 | ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity 623 | ## 624 | podAffinityPreset: "" 625 | ## @param secondary.podAntiAffinityPreset MySQL secondary pod anti-affinity preset. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` 626 | ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity 627 | ## Allowed values: soft, hard 628 | ## 629 | podAntiAffinityPreset: soft 630 | ## MySQL Secondary node affinity preset 631 | ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity 632 | ## 633 | nodeAffinityPreset: 634 | ## @param secondary.nodeAffinityPreset.type MySQL secondary node affinity preset type. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` 635 | ## 636 | type: "" 637 | ## @param secondary.nodeAffinityPreset.key MySQL secondary node label key to match Ignored if `secondary.affinity` is set. 638 | ## E.g. 639 | ## key: "kubernetes.io/e2e-az-name" 640 | ## 641 | key: "" 642 | ## @param secondary.nodeAffinityPreset.values MySQL secondary node label values to match. Ignored if `secondary.affinity` is set. 643 | ## E.g. 644 | ## values: 645 | ## - e2e-az1 646 | ## - e2e-az2 647 | ## 648 | values: [] 649 | ## @param secondary.affinity Affinity for MySQL secondary pods assignment 650 | ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity 651 | ## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set 652 | ## 653 | affinity: {} 654 | # nodeAffinity: 655 | # requiredDuringSchedulingIgnoredDuringExecution: 656 | # nodeSelectorTerms: 657 | # - matchExpressions: 658 | # - key: "App-On-Demand" 659 | # operator: In 660 | # values: 661 | # - "true" 662 | ## @param secondary.nodeSelector Node labels for MySQL secondary pods assignment 663 | ## ref: https://kubernetes.io/docs/user-guide/node-selection/ 664 | ## 665 | nodeSelector: {} 666 | ## @param secondary.tolerations Tolerations for MySQL secondary pods assignment 667 | ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ 668 | ## 669 | tolerations: [] 670 | ## @param secondary.priorityClassName MySQL secondary pods' priorityClassName 671 | ## 672 | priorityClassName: "" 673 | ## @param secondary.schedulerName Name of the k8s scheduler (other than default) 674 | ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ 675 | ## 676 | schedulerName: "" 677 | ## @param secondary.terminationGracePeriodSeconds In seconds, time the given to the MySQL secondary pod needs to terminate gracefully 678 | ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods 679 | ## 680 | terminationGracePeriodSeconds: "" 681 | ## @param secondary.topologySpreadConstraints Topology Spread Constraints for pod assignment 682 | ## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ 683 | ## The value is evaluated as a template 684 | ## 685 | topologySpreadConstraints: [] 686 | ## @param secondary.podManagementPolicy podManagementPolicy to manage scaling operation of MySQL secondary pods 687 | ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies 688 | ## 689 | podManagementPolicy: "" 690 | ## MySQL secondary Pod security context 691 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod 692 | ## @param secondary.podSecurityContext.enabled Enable security context for MySQL secondary pods 693 | ## @param secondary.podSecurityContext.fsGroup Group ID for the mounted volumes' filesystem 694 | ## 695 | podSecurityContext: 696 | enabled: true 697 | fsGroup: 1001 698 | ## MySQL secondary container security context 699 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container 700 | ## @param secondary.containerSecurityContext.enabled MySQL secondary container securityContext 701 | ## @param secondary.containerSecurityContext.runAsUser User ID for the MySQL secondary container 702 | ## @param secondary.containerSecurityContext.runAsNonRoot Set MySQL secondary container's Security Context runAsNonRoot 703 | ## 704 | containerSecurityContext: 705 | enabled: true 706 | runAsUser: 1001 707 | runAsNonRoot: true 708 | ## MySQL secondary container's resource requests and limits 709 | ## ref: https://kubernetes.io/docs/user-guide/compute-resources/ 710 | ## We usually recommend not to specify default resources and to leave this as a conscious 711 | ## choice for the user. This also increases chances charts run on environments with little 712 | ## resources, such as Minikube. If you do want to specify resources, uncomment the following 713 | ## lines, adjust them as necessary, and remove the curly braces after 'resources:'. 714 | ## @param secondary.resources.limits The resources limits for MySQL secondary containers 715 | ## @param secondary.resources.requests The requested resources for MySQL secondary containers 716 | ## 717 | resources: 718 | ## Example: 719 | ## limits: 720 | ## cpu: 250m 721 | ## memory: 256Mi 722 | limits: 723 | cpu: 500m 724 | memory: 1Gi 725 | ## Examples: 726 | ## requests: 727 | ## cpu: 250m 728 | ## memory: 256Mi 729 | requests: 730 | cpu: 250m 731 | memory: 500Mi 732 | ## Configure extra options for liveness probe 733 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes 734 | ## @param secondary.livenessProbe.enabled Enable livenessProbe 735 | ## @param secondary.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe 736 | ## @param secondary.livenessProbe.periodSeconds Period seconds for livenessProbe 737 | ## @param secondary.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe 738 | ## @param secondary.livenessProbe.failureThreshold Failure threshold for livenessProbe 739 | ## @param secondary.livenessProbe.successThreshold Success threshold for livenessProbe 740 | ## 741 | livenessProbe: 742 | enabled: true 743 | initialDelaySeconds: 5 744 | periodSeconds: 10 745 | timeoutSeconds: 1 746 | failureThreshold: 3 747 | successThreshold: 1 748 | ## Configure extra options for readiness probe 749 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes 750 | ## @param secondary.readinessProbe.enabled Enable readinessProbe 751 | ## @param secondary.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe 752 | ## @param secondary.readinessProbe.periodSeconds Period seconds for readinessProbe 753 | ## @param secondary.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe 754 | ## @param secondary.readinessProbe.failureThreshold Failure threshold for readinessProbe 755 | ## @param secondary.readinessProbe.successThreshold Success threshold for readinessProbe 756 | ## 757 | readinessProbe: 758 | enabled: true 759 | initialDelaySeconds: 5 760 | periodSeconds: 10 761 | timeoutSeconds: 1 762 | failureThreshold: 3 763 | successThreshold: 1 764 | ## Configure extra options for startupProbe probe 765 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes 766 | ## @param secondary.startupProbe.enabled Enable startupProbe 767 | ## @param secondary.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe 768 | ## @param secondary.startupProbe.periodSeconds Period seconds for startupProbe 769 | ## @param secondary.startupProbe.timeoutSeconds Timeout seconds for startupProbe 770 | ## @param secondary.startupProbe.failureThreshold Failure threshold for startupProbe 771 | ## @param secondary.startupProbe.successThreshold Success threshold for startupProbe 772 | ## 773 | startupProbe: 774 | enabled: true 775 | initialDelaySeconds: 15 776 | periodSeconds: 10 777 | timeoutSeconds: 1 778 | failureThreshold: 15 779 | successThreshold: 1 780 | ## @param secondary.customLivenessProbe Override default liveness probe for MySQL secondary containers 781 | ## 782 | customLivenessProbe: {} 783 | ## @param secondary.customReadinessProbe Override default readiness probe for MySQL secondary containers 784 | ## 785 | customReadinessProbe: {} 786 | ## @param secondary.customStartupProbe Override default startup probe for MySQL secondary containers 787 | ## 788 | customStartupProbe: {} 789 | ## @param secondary.extraFlags MySQL secondary additional command line flags 790 | ## Can be used to specify command line flags, for example: 791 | ## E.g. 792 | ## extraFlags: "--max-connect-errors=1000 --max_connections=155" 793 | ## 794 | extraFlags: "" 795 | ## @param secondary.extraEnvVars An array to add extra environment variables on MySQL secondary containers 796 | ## E.g. 797 | ## extraEnvVars: 798 | ## - name: TZ 799 | ## value: "Europe/Paris" 800 | ## 801 | extraEnvVars: [] 802 | ## @param secondary.extraEnvVarsCM Name of existing ConfigMap containing extra env vars for MySQL secondary containers 803 | ## 804 | extraEnvVarsCM: "" 805 | ## @param secondary.extraEnvVarsSecret Name of existing Secret containing extra env vars for MySQL secondary containers 806 | ## 807 | extraEnvVarsSecret: "" 808 | ## Enable persistence using Persistent Volume Claims 809 | ## ref: https://kubernetes.io/docs/user-guide/persistent-volumes/ 810 | ## 811 | persistence: 812 | ## @param secondary.persistence.enabled Enable persistence on MySQL secondary replicas using a `PersistentVolumeClaim` 813 | ## 814 | enabled: true 815 | ## @param secondary.persistence.storageClass MySQL secondary persistent volume storage Class 816 | ## If defined, storageClassName: 817 | ## If set to "-", storageClassName: "", which disables dynamic provisioning 818 | ## If undefined (the default) or set to null, no storageClassName spec is 819 | ## set, choosing the default provisioner. (gp2 on AWS, standard on 820 | ## GKE, AWS & OpenStack) 821 | ## 822 | storageClass: "${storage_class_name}" 823 | ## @param secondary.persistence.annotations MySQL secondary persistent volume claim annotations 824 | ## 825 | annotations: {} 826 | ## @param secondary.persistence.accessModes MySQL secondary persistent volume access Modes 827 | ## 828 | accessModes: 829 | - ReadWriteOnce 830 | ## @param secondary.persistence.size MySQL secondary persistent volume size 831 | ## 832 | size: ${secondary_pod_size} 833 | ## @param secondary.persistence.selector Selector to match an existing Persistent Volume 834 | ## selector: 835 | ## matchLabels: 836 | ## app: my-app 837 | ## 838 | selector: {} 839 | ## @param secondary.extraVolumes Optionally specify extra list of additional volumes to the MySQL secondary pod(s) 840 | ## 841 | extraVolumes: [] 842 | ## @param secondary.extraVolumeMounts Optionally specify extra list of additional volumeMounts for the MySQL secondary container(s) 843 | ## 844 | extraVolumeMounts: [] 845 | ## @param secondary.initContainers Add additional init containers for the MySQL secondary pod(s) 846 | ## 847 | initContainers: [] 848 | ## @param secondary.sidecars Add additional sidecar containers for the MySQL secondary pod(s) 849 | ## 850 | sidecars: 851 | - name: slow-log 852 | image: busybox:1.28 853 | args: [/bin/sh, -c, 'tail -n+1 -F /bitnami/mysql/slow-log.log'] 854 | volumeMounts: 855 | - name: data 856 | mountPath: /bitnami/mysql 857 | resources: 858 | ## Example: 859 | ## limits: 860 | ## cpu: 100m 861 | ## memory: 256Mi 862 | limits: {} 863 | ## Examples: 864 | ## requests: 865 | ## cpu: 100m 866 | ## memory: 256Mi 867 | requests: {} 868 | ## MySQL Secondary Service parameters 869 | ## 870 | service: 871 | ## @param secondary.service.type MySQL secondary Kubernetes service type 872 | ## 873 | type: ClusterIP 874 | ## @param secondary.service.ports.mysql MySQL secondary Kubernetes service port 875 | ## 876 | ports: 877 | mysql: 3306 878 | ## @param secondary.service.nodePorts.mysql MySQL secondary Kubernetes service node port 879 | ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport 880 | ## 881 | nodePorts: 882 | mysql: "" 883 | ## @param secondary.service.clusterIP MySQL secondary Kubernetes service clusterIP IP 884 | ## e.g: 885 | ## clusterIP: None 886 | ## 887 | clusterIP: "" 888 | ## @param secondary.service.loadBalancerIP MySQL secondary loadBalancerIP if service type is `LoadBalancer` 889 | ## Set the LoadBalancer service type to internal only 890 | ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer 891 | ## 892 | loadBalancerIP: "" 893 | ## @param secondary.service.externalTrafficPolicy Enable client source IP preservation 894 | ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip 895 | ## 896 | externalTrafficPolicy: Cluster 897 | ## @param secondary.service.loadBalancerSourceRanges Addresses that are allowed when MySQL secondary service is LoadBalancer 898 | ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service 899 | ## E.g. 900 | ## loadBalancerSourceRanges: 901 | ## - 10.10.10.0/24 902 | ## 903 | loadBalancerSourceRanges: [] 904 | ## @param secondary.service.extraPorts Extra ports to expose (normally used with the `sidecar` value) 905 | ## 906 | extraPorts: [] 907 | ## @param secondary.service.annotations Additional custom annotations for MySQL secondary service 908 | ## 909 | annotations: {} 910 | ## @param secondary.service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" 911 | ## If "ClientIP", consecutive client requests will be directed to the same Pod 912 | ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies 913 | ## 914 | sessionAffinity: None 915 | ## @param secondary.service.sessionAffinityConfig Additional settings for the sessionAffinity 916 | ## sessionAffinityConfig: 917 | ## clientIP: 918 | ## timeoutSeconds: 300 919 | ## 920 | sessionAffinityConfig: {} 921 | ## MySQL secondary Pod Disruption Budget configuration 922 | ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ 923 | ## 924 | pdb: 925 | ## @param secondary.pdb.create Enable/disable a Pod Disruption Budget creation for MySQL secondary pods 926 | ## 927 | create: false 928 | ## @param secondary.pdb.minAvailable Minimum number/percentage of MySQL secondary pods that should remain scheduled 929 | ## 930 | minAvailable: 1 931 | ## @param secondary.pdb.maxUnavailable Maximum number/percentage of MySQL secondary pods that may be made unavailable 932 | ## 933 | maxUnavailable: "" 934 | ## @param secondary.podLabels Additional pod labels for MySQL secondary pods 935 | ## 936 | podLabels: {} 937 | 938 | ## @section RBAC parameters 939 | 940 | ## MySQL pods ServiceAccount 941 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ 942 | ## 943 | serviceAccount: 944 | ## @param serviceAccount.create Enable the creation of a ServiceAccount for MySQL pods 945 | ## 946 | create: true 947 | ## @param serviceAccount.name Name of the created ServiceAccount 948 | ## If not set and create is true, a name is generated using the mysql.fullname template 949 | ## 950 | name: "" 951 | ## @param serviceAccount.annotations Annotations for MySQL Service Account 952 | ## 953 | annotations: {} 954 | ## @param serviceAccount.automountServiceAccountToken Automount service account token for the server service account 955 | ## 956 | automountServiceAccountToken: true 957 | 958 | ## Role Based Access 959 | ## ref: https://kubernetes.io/docs/admin/authorization/rbac/ 960 | ## 961 | rbac: 962 | ## @param rbac.create Whether to create & use RBAC resources or not 963 | ## 964 | create: false 965 | ## @param rbac.rules Custom RBAC rules to set 966 | ## e.g: 967 | ## rules: 968 | ## - apiGroups: 969 | ## - "" 970 | ## resources: 971 | ## - pods 972 | ## verbs: 973 | ## - get 974 | ## - list 975 | ## 976 | rules: [] 977 | 978 | ## @section Network Policy 979 | 980 | ## MySQL Nework Policy configuration 981 | ## 982 | networkPolicy: 983 | ## @param networkPolicy.enabled Enable creation of NetworkPolicy resources 984 | ## 985 | enabled: false 986 | ## @param networkPolicy.allowExternal The Policy model to apply. 987 | ## When set to false, only pods with the correct 988 | ## client label will have network access to the port MySQL is listening 989 | ## on. When true, MySQL will accept connections from any source 990 | ## (with the correct destination port). 991 | ## 992 | allowExternal: true 993 | ## @param networkPolicy.explicitNamespacesSelector A Kubernetes LabelSelector to explicitly select namespaces from which ingress traffic could be allowed to MySQL 994 | ## If explicitNamespacesSelector is missing or set to {}, only client Pods that are in the networkPolicy's namespace 995 | ## and that match other criteria, the ones that have the good label, can reach the DB. 996 | ## But sometimes, we want the DB to be accessible to clients from other namespaces, in this case, we can use this 997 | ## LabelSelector to select these namespaces, note that the networkPolicy's namespace should also be explicitly added. 998 | ## 999 | ## Example: 1000 | ## explicitNamespacesSelector: 1001 | ## matchLabels: 1002 | ## role: frontend 1003 | ## matchExpressions: 1004 | ## - {key: role, operator: In, values: [frontend]} 1005 | ## 1006 | explicitNamespacesSelector: {} 1007 | 1008 | ## @section Volume Permissions parameters 1009 | 1010 | ## Init containers parameters: 1011 | ## volumePermissions: Change the owner and group of the persistent volume mountpoint to runAsUser:fsGroup values from the securityContext section. 1012 | ## 1013 | volumePermissions: 1014 | ## @param volumePermissions.enabled Enable init container that changes the owner and group of the persistent volume(s) mountpoint to `runAsUser:fsGroup` 1015 | ## 1016 | enabled: false 1017 | ## @param volumePermissions.image.registry Init container volume-permissions image registry 1018 | ## @param volumePermissions.image.repository Init container volume-permissions image repository 1019 | ## @param volumePermissions.image.tag Init container volume-permissions image tag (immutable tags are recommended) 1020 | ## @param volumePermissions.image.pullPolicy Init container volume-permissions image pull policy 1021 | ## @param volumePermissions.image.pullSecrets Specify docker-registry secret names as an array 1022 | ## 1023 | image: 1024 | registry: docker.io 1025 | repository: bitnami/bitnami-shell 1026 | tag: 11-debian-11-r10 1027 | pullPolicy: IfNotPresent 1028 | ## Optionally specify an array of imagePullSecrets. 1029 | ## Secrets must be manually created in the namespace. 1030 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ 1031 | ## e.g: 1032 | ## pullSecrets: 1033 | ## - myRegistryKeySecretName 1034 | ## 1035 | pullSecrets: [] 1036 | ## @param volumePermissions.resources Init container volume-permissions resources 1037 | ## 1038 | resources: {} 1039 | 1040 | ## @section Metrics parameters 1041 | 1042 | ## Mysqld Prometheus exporter parameters 1043 | ## 1044 | metrics: 1045 | ## @param metrics.enabled Start a side-car prometheus exporter 1046 | ## 1047 | enabled: ${mysqldb_exporter_enabled} 1048 | ## @param metrics.image.registry Exporter image registry 1049 | ## @param metrics.image.repository Exporter image repository 1050 | ## @param metrics.image.tag Exporter image tag (immutable tags are recommended) 1051 | ## @param metrics.image.pullPolicy Exporter image pull policy 1052 | ## @param metrics.image.pullSecrets Specify docker-registry secret names as an array 1053 | ## 1054 | image: 1055 | registry: docker.io 1056 | repository: bitnami/mysqld-exporter 1057 | tag: 0.14.0-debian-11-r9 1058 | pullPolicy: IfNotPresent 1059 | ## Optionally specify an array of imagePullSecrets. 1060 | ## Secrets must be manually created in the namespace. 1061 | ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ 1062 | ## e.g: 1063 | ## pullSecrets: 1064 | ## - myRegistryKeySecretName 1065 | ## 1066 | pullSecrets: [] 1067 | ## MySQL Prometheus exporter service parameters 1068 | ## Mysqld Prometheus exporter liveness and readiness probes 1069 | ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes 1070 | ## @param metrics.service.type Kubernetes service type for MySQL Prometheus Exporter 1071 | ## @param metrics.service.port MySQL Prometheus Exporter service port 1072 | ## @param metrics.service.annotations [object] Prometheus exporter service annotations 1073 | ## 1074 | service: 1075 | type: ClusterIP 1076 | port: 9104 1077 | annotations: 1078 | prometheus.io/scrape: "true" 1079 | prometheus.io/path: "/metrics" 1080 | prometheus.io/port: "{{ .Values.metrics.service.port }}" 1081 | ## @param metrics.extraArgs.primary Extra args to be passed to mysqld_exporter on Primary pods 1082 | ## @param metrics.extraArgs.secondary Extra args to be passed to mysqld_exporter on Secondary pods 1083 | ## ref: https://github.com/prometheus/mysqld_exporter/ 1084 | ## E.g. 1085 | ## - --collect.auto_increment.columns 1086 | ## - --collect.binlog_size 1087 | ## - --collect.engine_innodb_status 1088 | ## - --collect.engine_tokudb_status 1089 | ## - --collect.global_status 1090 | ## - --collect.global_variables 1091 | ## - --collect.info_schema.clientstats 1092 | ## - --collect.info_schema.innodb_metrics 1093 | ## - --collect.info_schema.innodb_tablespaces 1094 | ## - --collect.info_schema.innodb_cmp 1095 | ## - --collect.info_schema.innodb_cmpmem 1096 | ## - --collect.info_schema.processlist 1097 | ## - --collect.info_schema.processlist.min_time 1098 | ## - --collect.info_schema.query_response_time 1099 | ## - --collect.info_schema.tables 1100 | ## - --collect.info_schema.tables.databases 1101 | ## - --collect.info_schema.tablestats 1102 | ## - --collect.info_schema.userstats 1103 | ## - --collect.perf_schema.eventsstatements 1104 | ## - --collect.perf_schema.eventsstatements.digest_text_limit 1105 | ## - --collect.perf_schema.eventsstatements.limit 1106 | ## - --collect.perf_schema.eventsstatements.timelimit 1107 | ## - --collect.perf_schema.eventswaits 1108 | ## - --collect.perf_schema.file_events 1109 | ## - --collect.perf_schema.file_instances 1110 | ## - --collect.perf_schema.indexiowaits 1111 | ## - --collect.perf_schema.tableiowaits 1112 | ## - --collect.perf_schema.tablelocks 1113 | ## - --collect.perf_schema.replication_group_member_stats 1114 | ## - --collect.slave_status 1115 | ## - --collect.slave_hosts 1116 | ## - --collect.heartbeat 1117 | ## - --collect.heartbeat.database 1118 | ## - --collect.heartbeat.table 1119 | ## 1120 | extraArgs: 1121 | primary: 1122 | - --collect.auto_increment.columns 1123 | - --collect.binlog_size 1124 | - --collect.engine_innodb_status 1125 | - --collect.global_status 1126 | - --collect.global_variables 1127 | - --collect.info_schema.clientstats 1128 | - --collect.info_schema.innodb_metrics 1129 | - --collect.info_schema.innodb_tablespaces 1130 | - --collect.info_schema.innodb_cmp 1131 | - --collect.info_schema.innodb_cmpmem 1132 | - --collect.info_schema.processlist 1133 | - --collect.info_schema.processlist.min_time=0 1134 | - --collect.info_schema.query_response_time 1135 | - --collect.info_schema.tables 1136 | - --collect.info_schema.tables.databases=* 1137 | - --collect.info_schema.tablestats 1138 | - --collect.info_schema.userstats 1139 | - --collect.perf_schema.eventsstatements 1140 | - --collect.perf_schema.eventsstatements.digest_text_limit=120 1141 | # - --collect.perf_schema.eventsstatements.limit=250 1142 | - --collect.perf_schema.eventsstatements.timelimit=86400 1143 | - --collect.perf_schema.eventswaits 1144 | - --collect.perf_schema.file_events 1145 | - --collect.perf_schema.file_instances 1146 | - --collect.perf_schema.indexiowaits 1147 | - --collect.perf_schema.tableiowaits 1148 | - --collect.perf_schema.tablelocks 1149 | - --collect.perf_schema.replication_group_member_stats 1150 | - --collect.slave_status 1151 | secondary: 1152 | - --collect.auto_increment.columns 1153 | - --collect.binlog_size 1154 | - --collect.engine_innodb_status 1155 | - --collect.global_status 1156 | - --collect.global_variables 1157 | - --collect.info_schema.clientstats 1158 | - --collect.info_schema.innodb_metrics 1159 | - --collect.info_schema.innodb_tablespaces 1160 | - --collect.info_schema.innodb_cmp 1161 | - --collect.info_schema.innodb_cmpmem 1162 | - --collect.info_schema.processlist 1163 | - --collect.info_schema.processlist.min_time=0 1164 | - --collect.info_schema.query_response_time 1165 | - --collect.info_schema.tables 1166 | - --collect.info_schema.tables.databases=* 1167 | - --collect.info_schema.tablestats 1168 | - --collect.info_schema.userstats 1169 | - --collect.perf_schema.eventsstatements 1170 | - --collect.perf_schema.eventsstatements.digest_text_limit=120 1171 | # - --collect.perf_schema.eventsstatements.limit=250 1172 | - --collect.perf_schema.eventsstatements.timelimit=86400 1173 | - --collect.perf_schema.eventswaits 1174 | - --collect.perf_schema.file_events 1175 | - --collect.perf_schema.file_instances 1176 | - --collect.perf_schema.indexiowaits 1177 | - --collect.perf_schema.tableiowaits 1178 | - --collect.perf_schema.tablelocks 1179 | - --collect.perf_schema.replication_group_member_stats 1180 | - --collect.slave_status 1181 | ## Mysqld Prometheus exporter resource requests and limits 1182 | ## ref: https://kubernetes.io/docs/user-guide/compute-resources/ 1183 | ## We usually recommend not to specify default resources and to leave this as a conscious 1184 | ## choice for the user. This also increases chances charts run on environments with little 1185 | ## resources, such as Minikube. If you do want to specify resources, uncomment the following 1186 | ## lines, adjust them as necessary, and remove the curly braces after 'resources:'. 1187 | ## @param metrics.resources.limits The resources limits for MySQL prometheus exporter containers 1188 | ## @param metrics.resources.requests The requested resources for MySQL prometheus exporter containers 1189 | ## 1190 | resources: 1191 | ## Example: 1192 | ## limits: 1193 | ## cpu: 100m 1194 | ## memory: 256Mi 1195 | limits: {} 1196 | ## Examples: 1197 | ## requests: 1198 | ## cpu: 100m 1199 | ## memory: 256Mi 1200 | requests: {} 1201 | ## Mysqld Prometheus exporter liveness probe 1202 | ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes 1203 | ## @param metrics.livenessProbe.enabled Enable livenessProbe 1204 | ## @param metrics.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe 1205 | ## @param metrics.livenessProbe.periodSeconds Period seconds for livenessProbe 1206 | ## @param metrics.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe 1207 | ## @param metrics.livenessProbe.failureThreshold Failure threshold for livenessProbe 1208 | ## @param metrics.livenessProbe.successThreshold Success threshold for livenessProbe 1209 | ## 1210 | livenessProbe: 1211 | enabled: true 1212 | initialDelaySeconds: 120 1213 | periodSeconds: 10 1214 | timeoutSeconds: 1 1215 | successThreshold: 1 1216 | failureThreshold: 3 1217 | ## Mysqld Prometheus exporter readiness probe 1218 | ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes 1219 | ## @param metrics.readinessProbe.enabled Enable readinessProbe 1220 | ## @param metrics.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe 1221 | ## @param metrics.readinessProbe.periodSeconds Period seconds for readinessProbe 1222 | ## @param metrics.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe 1223 | ## @param metrics.readinessProbe.failureThreshold Failure threshold for readinessProbe 1224 | ## @param metrics.readinessProbe.successThreshold Success threshold for readinessProbe 1225 | ## 1226 | readinessProbe: 1227 | enabled: true 1228 | initialDelaySeconds: 30 1229 | periodSeconds: 10 1230 | timeoutSeconds: 1 1231 | successThreshold: 1 1232 | failureThreshold: 3 1233 | ## Prometheus Service Monitor 1234 | ## ref: https://github.com/coreos/prometheus-operator 1235 | ## 1236 | serviceMonitor: 1237 | ## @param metrics.serviceMonitor.enabled Create ServiceMonitor Resource for scraping metrics using PrometheusOperator 1238 | ## 1239 | enabled: true 1240 | ## @param metrics.serviceMonitor.namespace Specify the namespace in which the serviceMonitor resource will be created 1241 | ## 1242 | namespace: "${service_monitor_namespace}" 1243 | ## @param metrics.serviceMonitor.jobLabel The name of the label on the target service to use as the job name in prometheus. 1244 | ## 1245 | jobLabel: "" 1246 | ## @param metrics.serviceMonitor.interval Specify the interval at which metrics should be scraped 1247 | ## 1248 | interval: 30s 1249 | ## @param metrics.serviceMonitor.scrapeTimeout Specify the timeout after which the scrape is ended 1250 | ## e.g: 1251 | ## scrapeTimeout: 30s 1252 | ## 1253 | scrapeTimeout: "" 1254 | ## @param metrics.serviceMonitor.relabelings RelabelConfigs to apply to samples before scraping 1255 | ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#relabelconfig 1256 | ## 1257 | relabelings: [] 1258 | ## @param metrics.serviceMonitor.metricRelabelings MetricRelabelConfigs to apply to samples before ingestion 1259 | ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#relabelconfig 1260 | ## 1261 | metricRelabelings: [] 1262 | ## @param metrics.serviceMonitor.selector ServiceMonitor selector labels 1263 | ## ref: https://github.com/bitnami/charts/tree/master/bitnami/prometheus-operator#prometheus-configuration 1264 | ## 1265 | ## selector: 1266 | ## prometheus: my-prometheus 1267 | ## 1268 | selector: {} 1269 | ## @param metrics.serviceMonitor.honorLabels Specify honorLabels parameter to add the scrape endpoint 1270 | ## 1271 | honorLabels: false 1272 | ## @param metrics.serviceMonitor.labels Used to pass Labels that are used by the Prometheus installed in your cluster to select Service Monitors to work with 1273 | ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec 1274 | ## 1275 | labels: 1276 | release: prometheus-operator 1277 | ## @param metrics.serviceMonitor.annotations ServiceMonitor annotations 1278 | ## 1279 | annotations: {} 1280 | 1281 | ## Prometheus Operator prometheusRule configuration 1282 | ## 1283 | prometheusRule: 1284 | ## @param metrics.prometheusRule.enabled Creates a Prometheus Operator prometheusRule (also requires `metrics.enabled` to be `true` and `metrics.prometheusRule.rules`) 1285 | ## 1286 | enabled: false 1287 | ## @param metrics.prometheusRule.namespace Namespace for the prometheusRule Resource (defaults to the Release Namespace) 1288 | ## 1289 | namespace: "" 1290 | ## @param metrics.prometheusRule.additionalLabels Additional labels that can be used so prometheusRule will be discovered by Prometheus 1291 | ## 1292 | additionalLabels: {} 1293 | ## @param metrics.prometheusRule.rules Prometheus Rule definitions 1294 | ## - alert: Mysql-Down 1295 | ## expr: absent(up{job="mysql"} == 1) 1296 | ## for: 5m 1297 | ## labels: 1298 | ## severity: warning 1299 | ## service: mariadb 1300 | ## annotations: 1301 | ## message: 'MariaDB instance {{`{{`}} $labels.instance {{`}}`}} is down' 1302 | ## summary: MariaDB instance is down 1303 | ## 1304 | rules: [] 1305 | --------------------------------------------------------------------------------