diff --git a/CHANGELOG.md b/CHANGELOG.md index 80fd6dc..58704f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # spring-service +## 3.9.0 + +**Breaking Changes** + +> External Secrets Operator must be installed on cluster + +- Migrate from KES to external-secrets-operator + ## 3.8.0 - Configure SPRING_FLYWAY_URL to ensure RLS secured services work with tracing enabled @@ -119,6 +127,14 @@ # cronjob +## 1.5.0 + +**Breaking Changes** + +> External Secrets Operator must be installed on cluster + +- Migrate from KES to external-secrets-operator + ## 1.4.0 - Add support for service account diff --git a/charts/cronjob/Chart.yaml b/charts/cronjob/Chart.yaml index b1ad63a..f092036 100644 --- a/charts/cronjob/Chart.yaml +++ b/charts/cronjob/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v1 name: cronjob description: A generalized cronjob that can access secrets. -version: 1.4.0 +version: 1.5.0 diff --git a/charts/cronjob/templates/pre-deployment/secret.yaml b/charts/cronjob/templates/pre-deployment/secret.yaml index fab4a48..8ef9e92 100644 --- a/charts/cronjob/templates/pre-deployment/secret.yaml +++ b/charts/cronjob/templates/pre-deployment/secret.yaml @@ -1,15 +1,18 @@ {{- if .Values.env.fromSecret }} -apiVersion: "kubernetes-client.io/v1" +apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: namespace: {{ .Values.namespace }} name: {{ .Values.cronJobName }}-external-secret spec: - backendType: systemManager - roleArn: {{ required "secretsRoleArn must be set!" .Values.secretsRoleArn }} + refreshInterval: "5m" + secretStoreRef: + name: secret-store + kind: SecretStore data: {{- range $key, $value := .Values.env.fromSecret }} - - name: "{{ $key }}" - key: "/{{ $.Values.clusterName }}/{{ $value.parameterName }}" + - secretKey: "{{ $key }}" + remoteRef: + key: "/{{ $.Values.clusterName }}/{{ $value.parameterName }}" {{- end }} {{- end }} diff --git a/charts/cronjob/values.yaml b/charts/cronjob/values.yaml index fab6c34..84a937f 100644 --- a/charts/cronjob/values.yaml +++ b/charts/cronjob/values.yaml @@ -4,8 +4,6 @@ cronJobName: "" # namespace to use, typically team- namespace: "" -clusterName: "" # required, to be filled in by helm template argument [like image.tag] (example: staging) -secretsRoleArn: "" # required, to be filled in by .values.yaml (example: arn:aws:iam::1234567890:role/read-secrets-role-staging-team-superpower) # schedule to run in cronjob-format, see https://crontab.guru/ e.g. "25 1 * * */2" schedule: "" diff --git a/charts/spring-service/Chart.yaml b/charts/spring-service/Chart.yaml index 281feb0..12781cc 100644 --- a/charts/spring-service/Chart.yaml +++ b/charts/spring-service/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v1 name: spring-service description: A generalized deployment for Meisterplan Spring Boot services in Kubernetes. -version: 3.8.0 +version: 3.9.0 diff --git a/charts/spring-service/templates/pre-deployment/secret.yaml b/charts/spring-service/templates/pre-deployment/secret.yaml index b0c612b..6d79f96 100644 --- a/charts/spring-service/templates/pre-deployment/secret.yaml +++ b/charts/spring-service/templates/pre-deployment/secret.yaml @@ -1,53 +1,71 @@ {{- if and .Values.env.springDatasourceFromSecret .Values.env.springDatasourceFromSecretWithRLS }} {{ fail "You cannot set both springDatasourceFromSecret and springDatasourceFromSecretWithRLS at the same time" }} {{- end}} -apiVersion: "kubernetes-client.io/v1" +apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: namespace: {{ .Values.namespace }} name: {{ .Values.serviceName }}-external-secret spec: - backendType: systemManager - roleArn: {{ required "secretsRoleArn must be set!" .Values.secretsRoleArn }} + refreshInterval: "5m" + secretStoreRef: + name: secret-store + kind: SecretStore data: - - name: "SENTRY_DSN" - key: "/{{ required "clusterName must be set!" .Values.clusterName }}/sentry/dsn-{{ .Values.serviceName }}" - - name: "SERVICE_OAUTH2_PUBLIC_KEY" - key: "/{{ .Values.clusterName }}/authenticorn/public-key" + - secretKey: "SENTRY_DSN" + remoteRef: + key: "/{{ required "clusterName must be set!" .Values.clusterName }}/sentry/dsn-{{ .Values.serviceName }}" + - secretKey: "SERVICE_OAUTH2_PUBLIC_KEY" + remoteRef: + key: "/{{ .Values.clusterName }}/authenticorn/public-key" {{- if .Values.env.springDatasourceFromSecret }} - - name: "SPRING_DATASOURCE_URL" - key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecret }}/jdbc-url" - - name: "SPRING_DATASOURCE_USERNAME" - key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecret }}/username" - - name: "SPRING_DATASOURCE_PASSWORD" - key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecret }}/password" + - secretKey: "SPRING_DATASOURCE_URL" + remoteRef: + key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecret }}/jdbc-url" + - secretKey: "SPRING_DATASOURCE_USERNAME" + remoteRef: + key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecret }}/username" + - secretKey: "SPRING_DATASOURCE_PASSWORD" + remoteRef: + key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecret }}/password" {{- else if .Values.env.springDatasourceFromSecretWithRLS }} - - name: "SPRING_DATASOURCE_URL" - key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecretWithRLS }}/jdbc-url" - - name: "SPRING_DATASOURCE_USERNAME" - key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecretWithRLS }}/rls-username" - - name: "SPRING_DATASOURCE_PASSWORD" - key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecretWithRLS }}/rls-password" - - name: "SPRING_FLYWAY_USER" - key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecretWithRLS }}/username" - - name: "SPRING_FLYWAY_PASSWORD" - key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecretWithRLS }}/password" + - secretKey: "SPRING_DATASOURCE_URL" + remoteRef: + key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecretWithRLS }}/jdbc-url" + - secretKey: "SPRING_DATASOURCE_USERNAME" + remoteRef: + key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecretWithRLS }}/rls-username" + - secretKey: "SPRING_DATASOURCE_PASSWORD" + remoteRef: + key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecretWithRLS }}/rls-password" + - secretKey: "SPRING_FLYWAY_USER" + remoteRef: + key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecretWithRLS }}/username" + - secretKey: "SPRING_FLYWAY_PASSWORD" + remoteRef: + key: "/{{ .Values.clusterName }}/{{ .Values.env.springDatasourceFromSecretWithRLS }}/password" {{- end }} {{- if .Values.env.springRabbitMQSecret }} - - name: "SPRING_RABBITMQ_HOST" - key: "/{{ .Values.clusterName }}/rabbitmq/hostname" - - name: "SPRING_RABBITMQ_SSL_ENABLED" - key: "/{{ .Values.clusterName }}/rabbitmq/ssl" - - name: "SPRING_RABBITMQ_USERNAME" - key: "/{{ .Values.clusterName }}/rabbitmq/username" - - name: "SPRING_RABBITMQ_PASSWORD" - key: "/{{ .Values.clusterName }}/rabbitmq/password" + - secretKey: "SPRING_RABBITMQ_HOST" + remoteRef: + key: "/{{ .Values.clusterName }}/rabbitmq/hostname" + - secretKey: "SPRING_RABBITMQ_SSL_ENABLED" + remoteRef: + key: "/{{ .Values.clusterName }}/rabbitmq/ssl" + - secretKey: "SPRING_RABBITMQ_USERNAME" + remoteRef: + key: "/{{ .Values.clusterName }}/rabbitmq/username" + - secretKey: "SPRING_RABBITMQ_PASSWORD" + remoteRef: + key: "/{{ .Values.clusterName }}/rabbitmq/password" {{- end }} {{- if .Values.ingress.basicAuthSecretParameterName }} - - name: "auth" - key: "/{{ .Values.clusterName }}/{{ .Values.ingress.basicAuthSecretParameterName }}" + - secretKey: "auth" + remoteRef: + key: "/{{ .Values.clusterName }}/{{ .Values.ingress.basicAuthSecretParameterName }}" {{- end }} {{- range $key, $value := .Values.env.fromSecret }} - - name: "{{ $key }}" - key: "/{{ $.Values.clusterName }}/{{ $value.parameterName }}" + - secretKey: "{{ $key }}" + remoteRef: + key: "/{{ $.Values.clusterName }}/{{ $value.parameterName }}" {{- end }} diff --git a/charts/spring-service/values.yaml b/charts/spring-service/values.yaml index 83a5826..4986b37 100644 --- a/charts/spring-service/values.yaml +++ b/charts/spring-service/values.yaml @@ -5,7 +5,6 @@ serviceName: "" namespace: "" clusterName: "" # required, to be filled in by helm template argument [like image.tag] (example: staging) -secretsRoleArn: "" # required, to be filled in by .values.yaml (example: arn:aws:iam::1234567890:role/read-secrets-role-staging-team-superpower) # The podRoleArn variable will create a service account that is bound to the pods. # This will grant the pod to assume the configured role automatically. This is only @@ -45,7 +44,8 @@ timeouts: # progressDeadlineSeconds: ? # see https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#progress-deadline-seconds # Optional: Additional ports that can be reached by other services inside the cluster, but not by requests from the load balancer -internalPorts: {} +internalPorts: + {} # - name: ftp # port: 21 # exposed port inside the cluster for others # targetPort: 1221 # port to connect to at the running service diff --git a/tests/cronjob/service-account-cronjob/expected/cronjob/templates/pre-deployment/secret.yaml b/tests/cronjob/service-account-cronjob/expected/cronjob/templates/pre-deployment/secret.yaml index ffd4eee..96d014e 100644 --- a/tests/cronjob/service-account-cronjob/expected/cronjob/templates/pre-deployment/secret.yaml +++ b/tests/cronjob/service-account-cronjob/expected/cronjob/templates/pre-deployment/secret.yaml @@ -1,15 +1,19 @@ --- # Source: cronjob/templates/pre-deployment/secret.yaml -apiVersion: "kubernetes-client.io/v1" +apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: namespace: team-superpower name: simple-job-staging-external-secret spec: - backendType: systemManager - roleArn: arn:aws:iam::1234567890:role/read-secrets-role-staging-team-superpower + refreshInterval: "5m" + secretStoreRef: + name: secret-store + kind: SecretStore data: - - name: "AWS_ACCESS_KEY_ID" - key: "/staging/aws/access-key-id" - - name: "THIRD_PARTY_API_KEY" - key: "/staging/third-party/api-key" + - secretKey: "AWS_ACCESS_KEY_ID" + remoteRef: + key: "/staging/aws/access-key-id" + - secretKey: "THIRD_PARTY_API_KEY" + remoteRef: + key: "/staging/third-party/api-key" diff --git a/tests/cronjob/service-account-cronjob/values.yaml b/tests/cronjob/service-account-cronjob/values.yaml index 315f7c0..bae64a5 100644 --- a/tests/cronjob/service-account-cronjob/values.yaml +++ b/tests/cronjob/service-account-cronjob/values.yaml @@ -2,7 +2,6 @@ namespace: team-superpower cronJobName: save-the-world clusterName: staging -secretsRoleArn: arn:aws:iam::1234567890:role/read-secrets-role-staging-team-superpower schedule: "22 */5 * * *" diff --git a/tests/cronjob/simple-cronjob/expected/cronjob/templates/pre-deployment/secret.yaml b/tests/cronjob/simple-cronjob/expected/cronjob/templates/pre-deployment/secret.yaml index ffd4eee..96d014e 100644 --- a/tests/cronjob/simple-cronjob/expected/cronjob/templates/pre-deployment/secret.yaml +++ b/tests/cronjob/simple-cronjob/expected/cronjob/templates/pre-deployment/secret.yaml @@ -1,15 +1,19 @@ --- # Source: cronjob/templates/pre-deployment/secret.yaml -apiVersion: "kubernetes-client.io/v1" +apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: namespace: team-superpower name: simple-job-staging-external-secret spec: - backendType: systemManager - roleArn: arn:aws:iam::1234567890:role/read-secrets-role-staging-team-superpower + refreshInterval: "5m" + secretStoreRef: + name: secret-store + kind: SecretStore data: - - name: "AWS_ACCESS_KEY_ID" - key: "/staging/aws/access-key-id" - - name: "THIRD_PARTY_API_KEY" - key: "/staging/third-party/api-key" + - secretKey: "AWS_ACCESS_KEY_ID" + remoteRef: + key: "/staging/aws/access-key-id" + - secretKey: "THIRD_PARTY_API_KEY" + remoteRef: + key: "/staging/third-party/api-key" diff --git a/tests/cronjob/simple-cronjob/values.yaml b/tests/cronjob/simple-cronjob/values.yaml index 318a75c..99315c7 100644 --- a/tests/cronjob/simple-cronjob/values.yaml +++ b/tests/cronjob/simple-cronjob/values.yaml @@ -1,7 +1,6 @@ namespace: team-superpower clusterName: staging -secretsRoleArn: arn:aws:iam::1234567890:role/read-secrets-role-staging-team-superpower schedule: "22 */5 * * *" diff --git a/tests/spring-service/complex-service/expected/spring-service/templates/pre-deployment/secret.yaml b/tests/spring-service/complex-service/expected/spring-service/templates/pre-deployment/secret.yaml index 9a5fd16..3faa87b 100644 --- a/tests/spring-service/complex-service/expected/spring-service/templates/pre-deployment/secret.yaml +++ b/tests/spring-service/complex-service/expected/spring-service/templates/pre-deployment/secret.yaml @@ -1,35 +1,49 @@ --- # Source: spring-service/templates/pre-deployment/secret.yaml -apiVersion: "kubernetes-client.io/v1" +apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: namespace: team-supercool name: myservice-external-secret spec: - backendType: systemManager - roleArn: arn:aws:iam::1234567890:role/read-secrets-role-staging-team-superpower + refreshInterval: "5m" + secretStoreRef: + name: secret-store + kind: SecretStore data: - - name: "SENTRY_DSN" - key: "/staging/sentry/dsn-myservice" - - name: "SERVICE_OAUTH2_PUBLIC_KEY" - key: "/staging/authenticorn/public-key" - - name: "SPRING_DATASOURCE_URL" - key: "/staging/rds/myservice/jdbc-url" - - name: "SPRING_DATASOURCE_USERNAME" - key: "/staging/rds/myservice/rls-username" - - name: "SPRING_DATASOURCE_PASSWORD" - key: "/staging/rds/myservice/rls-password" - - name: "SPRING_FLYWAY_USER" - key: "/staging/rds/myservice/username" - - name: "SPRING_FLYWAY_PASSWORD" - key: "/staging/rds/myservice/password" - - name: "SPRING_RABBITMQ_HOST" - key: "/staging/rabbitmq/hostname" - - name: "SPRING_RABBITMQ_SSL_ENABLED" - key: "/staging/rabbitmq/ssl" - - name: "SPRING_RABBITMQ_USERNAME" - key: "/staging/rabbitmq/username" - - name: "SPRING_RABBITMQ_PASSWORD" - key: "/staging/rabbitmq/password" - - name: "auth" - key: "/staging/myservice/auth" + - secretKey: "SENTRY_DSN" + remoteRef: + key: "/staging/sentry/dsn-myservice" + - secretKey: "SERVICE_OAUTH2_PUBLIC_KEY" + remoteRef: + key: "/staging/authenticorn/public-key" + - secretKey: "SPRING_DATASOURCE_URL" + remoteRef: + key: "/staging/rds/myservice/jdbc-url" + - secretKey: "SPRING_DATASOURCE_USERNAME" + remoteRef: + key: "/staging/rds/myservice/rls-username" + - secretKey: "SPRING_DATASOURCE_PASSWORD" + remoteRef: + key: "/staging/rds/myservice/rls-password" + - secretKey: "SPRING_FLYWAY_USER" + remoteRef: + key: "/staging/rds/myservice/username" + - secretKey: "SPRING_FLYWAY_PASSWORD" + remoteRef: + key: "/staging/rds/myservice/password" + - secretKey: "SPRING_RABBITMQ_HOST" + remoteRef: + key: "/staging/rabbitmq/hostname" + - secretKey: "SPRING_RABBITMQ_SSL_ENABLED" + remoteRef: + key: "/staging/rabbitmq/ssl" + - secretKey: "SPRING_RABBITMQ_USERNAME" + remoteRef: + key: "/staging/rabbitmq/username" + - secretKey: "SPRING_RABBITMQ_PASSWORD" + remoteRef: + key: "/staging/rabbitmq/password" + - secretKey: "auth" + remoteRef: + key: "/staging/myservice/auth" diff --git a/tests/spring-service/complex-service/values.yaml b/tests/spring-service/complex-service/values.yaml index e9e97fd..7a807dc 100644 --- a/tests/spring-service/complex-service/values.yaml +++ b/tests/spring-service/complex-service/values.yaml @@ -2,7 +2,6 @@ serviceName: myservice namespace: team-supercool clusterName: staging -secretsRoleArn: arn:aws:iam::1234567890:role/read-secrets-role-staging-team-superpower podRoleArn: arn:aws:iam::1234567890:role/k8s-staging-myservice image: diff --git a/tests/spring-service/simple-service/expected/spring-service/templates/pre-deployment/secret.yaml b/tests/spring-service/simple-service/expected/spring-service/templates/pre-deployment/secret.yaml index 2811f4a..bfdc777 100644 --- a/tests/spring-service/simple-service/expected/spring-service/templates/pre-deployment/secret.yaml +++ b/tests/spring-service/simple-service/expected/spring-service/templates/pre-deployment/secret.yaml @@ -1,33 +1,46 @@ --- # Source: spring-service/templates/pre-deployment/secret.yaml -apiVersion: "kubernetes-client.io/v1" +apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: namespace: team-supercool name: myservice-external-secret spec: - backendType: systemManager - roleArn: arn:aws:iam::1234567890:role/read-secrets-role-staging-team-superpower + refreshInterval: "5m" + secretStoreRef: + name: secret-store + kind: SecretStore data: - - name: "SENTRY_DSN" - key: "/staging/sentry/dsn-myservice" - - name: "SERVICE_OAUTH2_PUBLIC_KEY" - key: "/staging/authenticorn/public-key" - - name: "SPRING_DATASOURCE_URL" - key: "/staging/rds/myservice/jdbc-url" - - name: "SPRING_DATASOURCE_USERNAME" - key: "/staging/rds/myservice/username" - - name: "SPRING_DATASOURCE_PASSWORD" - key: "/staging/rds/myservice/password" - - name: "SPRING_RABBITMQ_HOST" - key: "/staging/rabbitmq/hostname" - - name: "SPRING_RABBITMQ_SSL_ENABLED" - key: "/staging/rabbitmq/ssl" - - name: "SPRING_RABBITMQ_USERNAME" - key: "/staging/rabbitmq/username" - - name: "SPRING_RABBITMQ_PASSWORD" - key: "/staging/rabbitmq/password" - - name: "auth" - key: "/staging/myservice/auth" - - name: "SOME_SECRET" - key: "/staging/other-system/secret" + - secretKey: "SENTRY_DSN" + remoteRef: + key: "/staging/sentry/dsn-myservice" + - secretKey: "SERVICE_OAUTH2_PUBLIC_KEY" + remoteRef: + key: "/staging/authenticorn/public-key" + - secretKey: "SPRING_DATASOURCE_URL" + remoteRef: + key: "/staging/rds/myservice/jdbc-url" + - secretKey: "SPRING_DATASOURCE_USERNAME" + remoteRef: + key: "/staging/rds/myservice/username" + - secretKey: "SPRING_DATASOURCE_PASSWORD" + remoteRef: + key: "/staging/rds/myservice/password" + - secretKey: "SPRING_RABBITMQ_HOST" + remoteRef: + key: "/staging/rabbitmq/hostname" + - secretKey: "SPRING_RABBITMQ_SSL_ENABLED" + remoteRef: + key: "/staging/rabbitmq/ssl" + - secretKey: "SPRING_RABBITMQ_USERNAME" + remoteRef: + key: "/staging/rabbitmq/username" + - secretKey: "SPRING_RABBITMQ_PASSWORD" + remoteRef: + key: "/staging/rabbitmq/password" + - secretKey: "auth" + remoteRef: + key: "/staging/myservice/auth" + - secretKey: "SOME_SECRET" + remoteRef: + key: "/staging/other-system/secret" diff --git a/tests/spring-service/simple-service/values.yaml b/tests/spring-service/simple-service/values.yaml index 9bde3bb..59d95f0 100644 --- a/tests/spring-service/simple-service/values.yaml +++ b/tests/spring-service/simple-service/values.yaml @@ -2,7 +2,6 @@ serviceName: myservice namespace: team-supercool clusterName: staging -secretsRoleArn: arn:aws:iam::1234567890:role/read-secrets-role-staging-team-superpower image: repository: docker.pkg.github.com/my-company/myservice