In the our helm repository, we have a ci/cd with github actions, when we change helm templates or values, then ci will package helm stuff and push it to GCR as an image. see it as following github actions.
name: STAGING-ci-helm
permissions:
contents: read
id-token: write
on:
push:
branches:
- staging
pull_request:
env:
CHART_NAME: aaaa
IMAGE_TAG: 0.0.1
jobs:
job:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: helm lint
run: |
helm lint -f aaaa/values-staging.yaml ./aaaa
- uses: google-github-actions/auth@v0
with:
workload_identity_provider: '${{ secrets.WI_POOL_PROVIDER_ID }}'
service_account: '${{ secrets.PACKAGER_GSA_ID }}'
token_format: 'access_token'
- uses: google-github-actions/setup-gcloud@v0
with:
version: latest
- name: login to artifact registry
run: |
gcloud auth configure-docker ${{ secrets.ARTIFACT_REGISTRY_HOST_NAME }} --quiet
- name: helm package
run: |
helm package ./aaaa --version $IMAGE_TAG --app-version $IMAGE_TAG
- name: helm push
if: ${{ github.event_name == 'push' }}
run: |
helm push aaaa-$IMAGE_TAG.tgz oci://${{ secrets.ARTIFACT_REGISTRY_HOST_NAME }}/${{ secrets.PROJECT_ID }}/${{ secrets.ARTIFACT_REGISTRY_REPOSITORY }}
Then in the our terraform repository, we can run a github actions workflow “Terraform Apply” to deploy our cluster with helm provider.
name: "Terraform Staging Apply"
on:
push:
branches:
- staging
pull_request:
types:
- closed
branches:
- staging
jobs:
terraform:
name: "Terraform Apply"
runs-on: ubuntu-latest
permissions: write-all
env:
AWS_ACCESS_KEY_ID: ${{ secrets.STAGING_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.STAGING_AWS_SECRET_ACCESS_KEY }}
defaults:
run:
working-directory: ./ci
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
with:
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
- name: Terraform Init
id: init
run: terraform init
- name: Terraform Apply
if: github.ref == 'refs/heads/staging' && github.event_name == 'push'
run: terraform apply -auto-approve -input=false -refresh=false
In order to combine terraform and helm, so we define 'resource “helm_release” ’ to glue terraform and helm, helm_release will refer to var.aaaa_repository and var.aaaa_version and retrieve our helm package.
resource "helm_release" "aaaa" {
count = var.install_aaaa_helm_release ? 1 : 0
# Chart information.
repository = var.aaaa_repository
version = var.aaaa_version
chart = "aaaa"
name = "aaaa"
namespace = var.k8s_namespace
create_namespace = !local.is_namespace_default
dependency_update = true
force_update = false
lint = true
recreate_pods = false
wait = false
values = [
local_file.helm_values.content
]
All the above works well.
Now I will make some changes to support helm secrets, we encrypts some stuff such as credentials with helm secrets (actually encrypted by sops), actually I can manually run “helm secrets install” at local, it works well, that means helm secrets works well.
However, because I change some stuff with encrypted stuff, I know “helm secrets install” or “helm secrets templates” works. Now in the above case, in the above ci/cd pipeline, we use “helm package”, then terraform call package, I am not sure how to make terraform to work with a helm package that has some stuff that has been encrypted by “helm secrets”?
An example as following, I use helm secrets (sops) to encrypt item dockerconfigjson
dockerconfigjson: ENC[AES256_GCM,data:hNWO6G/lMK2kf11kpQjW/VCs40KHWpLgha13cxQ==,iv:vIkA4FXh1iYBYVoH5Xtyp2SNo5XzPatiVlAxnfhcpSA=,tag:rNXGgovTC+VdkpwOkfUrjQ==,type:str]
sops:
kms:
- arn: arn:aws:kms:ca-central-1:88888888888:key/055555555-66666-7777-8888-xxxxxxxx
created_at: "2023-10-12T18:17:08Z"
enc: AQICAHhlPQ/aFcm7KLIoh1yCQAUgRDt67BhGjRw1f/mkc8yXaQFqweLYkq2dRjjmaUprSV7KAAAAfAgEQgDvYaldhb3vQrH5T4vOvdl6t4p+PHRFYCSo55YiEFWNeYTT1S3d1ufVeBvK9RLlq268FDDLul+FxA1pXfQ==
aws_profile: ""
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2023-10-12T20:35:14Z"
mac: ENC[AES256_GCM,data:lOcdqVQOxTJvYNoyHRZ2M4zcyoMZqAmO8bWLzlOiiezKGofC9s9+/sRVXONr4l8HcWo9pYGMfn3DM3YA9zE=,iv:Ht9i1ou+xJ0le2QqlNllKUPgMC3utKkKHPE2jibugrM=,tag:cz1R7TDbM39vMwuqsMFTuQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.0
Then in the a secret, we refer to that encrypted dockerconfigjson. When I use “helm secrets install”, it works well.
apiVersion: v1
kind: Secret
metadata:
name: dockercredential
namespace: {{ .Release.Namespace | quote }}
data:
.dockerconfigjson: {{ .Values.dockerconfigjson }}
type: kubernetes.io/dockerconfigjson
In short, now we are using “helm package” to package the helm stuff, some manifest (such as the above Secret dockercredential) in the helm template has been encrypted by helm secrets (sops), how to change terraform ‘resource “helm_release” “aaaa”’ stuff so that terraform can fit in encrypted stuff and deploy helm successfully?