DEV Community

Cover image for Infisical - Open Source SecretOps - Kubernetes Setup
Unni P
Unni P

Posted on • Edited on • Originally published at iamunnip.hashnode.dev

Infisical - Open Source SecretOps - Kubernetes Setup

In this article, we will talk about Infisical, an open-source secret management tool and how we can setup on a local Kubernetes cluster

Introduction

  • An open-source, end-to-end secret management platform

  • Enables teams to easily manage and sync their environment variables, API keys, secrets and other configurations

Features

  • Intuitive dashboard

  • Client SDK's

  • Infisical CLI

  • Native platform integrations

  • Automatic Kubernetes deployment secret reloads

  • Complete control of data when hosted by ourself

  • Secret versioning

  • Point-in-Time recovery

  • Role-based access control

  • Secret scanning and leak prevention

  • Effortless on-premise deployment

Prerequisites

  • kubectl

    Check my article to install kubectl

    $ kubectl version --client --short Client Version: v1.27.4 Kustomize Version: v5.0.1 
  • Helm

    Check my article to install Helm

    $ helm version version.BuildInfo{Version:"v3.12.1", GitCommit:"f32a527a060157990e2aa86bf45010dfb3cc8b8d", GitTreeState:"clean", GoVersion:"go1.20.4"} 
  • Kubernetes cluster

    For this demo, I'm using Rancher Desktop on Windows

    $ kubectl get nodes NAME STATUS ROLES AGE VERSION rancher-desktop Ready control-plane,master 27s v1.27.4+k3s1 

Installation

  • Add the Infisical Helm repository

    $ helm repo add infisical-helm-charts 'https://dl.cloudsmith.io/public/infisical/helm-charts/helm/charts/' $ helm repo update 
  • Install Infisical using the below command.

    It will install all the necessary components in the infisical namespace and also install Nginx ingress controller

    $ helm install -n infisical infisical infisical-helm-charts/infisical --set ingress.nginx.enabled=true --create-namespace NAME: infisical LAST DEPLOYED: Thu Aug 17 19:43:06 2023 NAMESPACE: infisical STATUS: deployed REVISION: 1 TEST SUITE: None 
  • Check the status of the components and the load balancer service created by Nginx ingress controller

    Copy the Load Balancer IP, we will need it in the next step

    $ kubectl -n infisical get pods NAME READY STATUS RESTARTS AGE infisical-frontend-8588c9f65-sxz8d 1/1 Running 0 3m19s infisical-frontend-8588c9f65-nsnjr 1/1 Running 0 3m19s mongodb-0 1/1 Running 0 3m19s infisical-backend-6777b66f58-79d84 1/1 Running 0 3m19s infisical-backend-6777b66f58-g2fwb 1/1 Running 0 3m19s infisical-ingress-nginx-controller-7785998dc6-lqxgk 1/1 Running 0 3m19s 
```bash $ kubectl -n infisical get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE infisical-backend ClusterIP 10.43.203.3 <none> 4000/TCP 9m47s infisical-frontend ClusterIP 10.43.41.186 <none> 3000/TCP 9m47s infisical-ingress-nginx-controller-admission ClusterIP 10.43.42.222 <none> 443/TCP 9m47s mongodb ClusterIP 10.43.112.139 <none> 27017/TCP 9m47s infisical-ingress-nginx-controller LoadBalancer 10.43.63.38 172.31.134.241 80:30035/TCP,443:31538/TCP 9m47s ``` 
Enter fullscreen mode Exit fullscreen mode

Initial Setup

  • In our local setup, we are skipping SMTP configuration and accessing the dashboard via the LoadBalancer IP address http://172.31.134.241/signup
    You can also set up the hostname using ingress.hostName=<your-hostname> option during the installation

  • Create an account for the administrator by clicking the "Continue with Email" option

infisical-1

  • Enter your email id and click the "Get Started" option

infisical-2

  • Enter the details accordingly and click "Sign Up" option

infisical-3

  • Once you sign up, you will need to download "Emergency Kit" and save it somewhere safe. If you get locked out of your account, we can use this emergency kit to unlock it

infisical-4

  • Now we are redirected to the homepage of Infisical

infisical-5

Configuration

  • Create a new project by clicking the "Add New Project" button from the dashboard and name your project "MyApp"

infisical-6

  • Once our project is created, we will get an interface like below. Here we can see different environments like Development, Staging and Production. We are going to add the secrets in the Development environment by clicking the "Go to Development" option

infisical-7

  • We can copy secrets from other environments, upload env files etc. We can create a new secret by clicking the "Add a new secret" option

infisical-8

  • Add the required secrets and save the changes

infisical-9

Secrets Operator Setup

  • First, we need to generate a Service Token from our project settings

infisical-10

  • Select the "Create token" option and enter a name for the service token. Select the environment, secrets path, expiration and permissions according to your use case and click on "Create" option

infisical-11

  • Once the service token is created, copy and save it somewhere safe. We need this token to configure the secrets operator

infisical-12

  • Back in our Kubernetes cluster, we need to install and configure the Infisical secrets operator to sync our secrets to the cluster

    $ helm install -n infisical infisical-secrets-operator infisical-helm-charts/secrets-operator NAME: infisical-secrets-operator LAST DEPLOYED: Thu Aug 17 21:05:56 2023 NAMESPACE: infisical STATUS: deployed REVISION: 1 TEST SUITE: None 
  • Check the infisical namespace, we can see a secret controller manager pod is created and it's up and running

    $ kubectl -n infisical get pods NAME READY STATUS RESTARTS AGE infisical-frontend-8588c9f65-sxz8d 1/1 Running 0 84m infisical-frontend-8588c9f65-nsnjr 1/1 Running 0 84m mongodb-0 1/1 Running 0 84m infisical-backend-6777b66f58-79d84 1/1 Running 0 84m infisical-backend-6777b66f58-g2fwb 1/1 Running 0 84m infisical-ingress-nginx-controller-7785998dc6-lqxgk 1/1 Running 0 84m infisical-secre-controller-manager-56c6f9b6d-lqk2v 2/2 Running 0 100s 
  • Create a new namespace for our application

    $ kubectl create ns myapp namespace/myapp created 
  • Create a Kubernetes secret containing the Service Token

    $ kubectl -n myapp create secret generic myapp-service-token --from-literal=infisicalToken=st.64de3f83a96c27c805827382.a7acb98a535125353af9135009f9b974.3d41003562f52a730823347dd4a01f96 secret/myapp-service-token created 
```bash $ kubectl -n myapp get secrets NAME TYPE DATA AGE myapp-service-token Opaque 1 25s ``` 
Enter fullscreen mode Exit fullscreen mode
  • Now we can sync our secrets to our cluster by creating an InfisicalSecret CRD

    apiVersion: secrets.infisical.com/v1alpha1 kind: InfisicalSecret metadata: name: myapp-infisical-secret namespace: myapp spec: hostAPI: http://infisical-backend.infisical.svc.cluster.local:4000/api resyncInterval: 10 authentication: serviceToken: serviceTokenSecretReference: secretName: myapp-service-token secretNamespace: myapp secretsScope: envSlug: dev secretsPath: "/" managedSecretReference: secretName: myapp-managed-secret secretNamespace: myapp 
```bash $ kubectl apply -f myapp-infisical-secret.yml infisicalsecret.secrets.infisical.com/myapp-infisical-secret created ``` 
Enter fullscreen mode Exit fullscreen mode
  • Once it's created, check the status of the CRD

    From the status, we can see our secrets are synced to our cluster

    $ kubectl -n myapp get infisicalsecrets NAME AGE myapp-infisical-secret 42s 
```bash $ kubectl -n myapp describe infisicalsecrets myapp-infisical-secret Name: myapp-infisical-secret Namespace: myapp Labels: <none> Annotations: <none> API Version: secrets.infisical.com/v1alpha1 Kind: InfisicalSecret Metadata: Creation Timestamp: 2023-08-17T16:07:04Z Generation: 1 Resource Version: 4927 UID: bb156757-1528-4827-afe9-09916fcd4372 Spec: Authentication: Service Token: Secrets Scope: Env Slug: dev Secrets Path: / Service Token Secret Reference: Secret Name: myapp-service-token Secret Namespace: myapp Host API: http://infisical-backend.infisical.svc.cluster.local:4000/api Managed Secret Reference: Secret Name: myapp-managed-secret Secret Namespace: myapp Resync Interval: 10 Status: Conditions: Last Transition Time: 2023-08-17T16:07:04Z Message: Infisical controller has located the Infisical token in provided Kubernetes secret Reason: OK Status: True Type: secrets.infisical.com/LoadedInfisicalToken Last Transition Time: 2023-08-17T16:07:05Z Message: Infisical controller has started syncing your secrets Reason: OK Status: True Type: secrets.infisical.com/ReadyToSyncSecrets Last Transition Time: 2023-08-17T16:07:05Z Message: Infisical has found 0 deployments which are ready to be auto redeployed when secrets change Reason: OK Status: True Type: secrets.infisical.com/AutoRedeployReady Events: <none> ``` 
Enter fullscreen mode Exit fullscreen mode
  • We can verify the secrets have been synced to our cluster by checking the myapp-managed-secret

    $ kubectl -n myapp get secrets myapp-managed-secret NAME TYPE DATA AGE myapp-managed-secret Opaque 4 5m16s 
```bash $ kubectl -n myapp describe secrets myapp-managed-secret Name: myapp-managed-secret Namespace: myapp Labels: <none> Annotations: secrets.infisical.com/version: W/"a5a-hBx83Z5L+nuphYXlN17htm8jAjo" Type: Opaque Data ==== MYSQL_HOST: 9 bytes MYSQL_PASSWORD: 13 bytes MYSQL_PORT: 4 bytes MYSQL_DATABASE: 13 bytes ``` 
Enter fullscreen mode Exit fullscreen mode

Application Deployment

  • Deploy a sample Nginx application using the below manifest file

    The annotation secrets.infisical.com/auto-reload: "true" ensures that it automatically redeploys when managed secrets are changed

    apiVersion: apps/v1 kind: Deployment metadata: name: myapp namespace: myapp labels: app: myapp annotations: secrets.infisical.com/auto-reload: "true" spec: replicas: 1 selector: matchLabels: app: maypp template: metadata: labels: app: myapp spec: containers: - name: myapp image: nginx:1.25.2 envFrom: - secretRef: name: myapp-managed-secret ports: - containerPort: 80 
```bash $ kubectl apply -f .\myapp-deployment.yml deployment.apps/myapp created ``` 
Enter fullscreen mode Exit fullscreen mode
  • Once our application is up and running, exec into the pod and list the environment variables to view our secrets

    $ kubectl -n myapp get pods NAME READY STATUS RESTARTS AGE myapp-77c586c9ff-5xsxv 1/1 Running 0 48s 
```bash $ kubectl -n myapp exec -it myapp-77c586c9ff-5xsxv -- bash root@myapp-77c586c9ff-5xsxv:/# env | grep -i MYSQL MYSQL_PORT=3306 MYSQL_PASSWORD=mysqlPassword MYSQL_HOST=mysqlHost MYSQL_DATABASE=mysqlDatabase ``` 
Enter fullscreen mode Exit fullscreen mode
  • That's all for now

Reference

https://infisical.com/docs/integrations/platforms/kubernetes

https://docs.rancherdesktop.io/getting-started/installation/

Top comments (4)

Collapse
 
pratapaprasanna profile image
Goutham Pratapa • Edited

Hey @iamunnip ,

I read this article

dev.to/iamunnip/infisical-open-sou...

I really liked the article and I have a couple of questions around it .

  • Say, if i install infiscal and add a secrets like MYSQl_PASSWORD. will the secrets be shared across namespaces ?

  • How are the secrets stored in DB, will they be masked ? I am sure they are masked but just curious.

  • Can i have two versions of a secrets. more like a tagging

eg:

on 25-08-2023 I enter a secret MYSQL_PASSWORD=goutham which is used on a namespace goutham

on 30-08-2023 I have another namespace infisical which needs a different MYSQL_PASSWORD=infisical.

for this to happen should i create another infisical secret?

Collapse
 
maidul98 profile image
Maidul Islam • Edited

Hi @pratapaprasanna! To answer your questions:

  • Currently, the managed Kubernetes secret that is auto created for you by the InfisicalSecret CRD cannot be shared across different namespaces (due to built in restrictions of Kubernetes Secrets). What is your use case for wanting the same secrets in different namespaces?
  • Yes, the secrets will be fully encrypted in the DB. You can read more about the architecture here: infisical.com/docs/security/overview
  • We currently don't support multiple versions of a single key to be fetched. However, if you want to have two keys that are the same name but different value, I'd take a look into folders for better secret organization infisical.com/docs/documentation/p...
Collapse
 
pratapaprasanna profile image
Goutham Pratapa

Hey thank you for a quick response,
I understand the limitations with sharing secrets across namespaces wanted to know if there is any work-around in infisical.

Context:
We have 10-20 apps running with some set of basic configurations,secrets.I wanted to know if there is a way in infisical where we can define a infisical secret and that can be shared across different namespaces and users can add new configurations/secrets possibly with same name and ending with a tag on top it based on the necessity.

Thread Thread
 
maidul98 profile image
Maidul Islam

Currently the only way to get the same secrets into different name space is to define a new InfisicalSecret CRD in each name space. I understand that you have many namespaces so this is very tedious.

As a feature request, what we can do is allow you to list namespaces where you'd like the same managed secret to be created in. Would this be helpful for you? If so, can you please put a request for it here github.com/Infisical/infisical/issues