diff --git a/.gitignore b/.gitignore index b24b7fc4e..71d304065 100644 --- a/.gitignore +++ b/.gitignore @@ -25,12 +25,15 @@ docs/_build/ /updatedFiles -deploy/kustomize/server-tls/certs/ -deploy/kustomize/server-remote-repo-scan/.ssh/ - # Go binary /bin +deploy/helm-charts/server/.ssh +deploy/helm-charts/server/data +deploy/helm-charts/webhook/data +deploy/kustomize/server-remote-repo-scan/.ssh +deploy/kustomize/server-tls/certs + .DS_Store vendor/ diff --git a/deploy/helm-charts/README.md b/deploy/helm-charts/README.md index aeaad67c9..3a1e756f9 100644 --- a/deploy/helm-charts/README.md +++ b/deploy/helm-charts/README.md @@ -1,26 +1,46 @@ -# Helm chart for deploying terrascan in server mode +# Helm charts for deploying terrascan -This chart deploys terrascan as a server within your kubernetes cluster. By default it runs just terrascan by itself, but, -user creates namespace and secrets. +This guide deploys terrascan as a server within your kubernetes cluster. Additionally, you can deploy a +Validating Webhook as well, that'll use the terrascan server as its backend. In server mode, terrascan will act both as an API server for performing remote scans of IAC, as well as a validating admission webhook for a Kubernetes cluster. Further details can be found in the [main documentation](https://docs.accurics.com/projects/accurics-terrascan/en/latest/). +There are two helm charts: + +1. In the `server/` directory : to deploy terrascan in server mode. +2. In the `webhook/` directory : to setup a validating webhook that uses the deployed terrascan server from step 1, as its backend. ## Usage ### Set up TLS certificates A requirement to run an admission controller is that communication happens over TLS. This helm chart expects to find the certificate -at `data/server.crt` and key at `data/server.key`. +at `server/data/server.crt` and key at `server/data/server.key`. +If you opt to deploy the webhook as well, please copy `server/data/server.crt` at `webhook/data/server.crt` + +### Set up SSH config for private remote repo scan +If you're opting to utilise the remote repo scan feature for ***private*** repositories, +terrascan will require ssh capabilities to do that. +This helm chart expects to find the your ssh private key at `.ssh/private_key`,and .ssh known_hosts file at `.ssh/known_hosts`. +Your ssh public key must setup at the code repository hosting service, such as github, bitbucket, etc. + +You can use the below content to create your `.ssh/known_hosts` file. + +```bash +# known_hosts +github.com,192.30.255.113 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== +bitbucket.org,104.192.141.1 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw== +gitlab.com,172.65.251.78 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY= +``` +**Note:** This is an optional feature and not a requirement. ### Persistent storage By default, this chart will deploy terrascan with a `emptyDir` volume - basically a temporary volume. If you intend to use the admission controller functionality, then you may want to store the admission controller database on a persistent volume. This chart -supports speciyfing a [persistent volume -claim](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) for +supports specifying a [persistent volume claim](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) for the database - as storage, PVs, and PVCs are a wide topic within Kubernetes ecosystem, the details of the PV/PVC creation are left to the individual. @@ -36,7 +56,7 @@ persistence: ### Terrascan configuration file This chart will look for a [terrascan configuration file](https://docs.accurics.com/projects/accurics-terrascan/en/latest/usage/#config-file) -at `data/config.toml`. If that file exists before running `helm +at `server/data/config.toml`. If that file exists before running `helm install`, it's contents will be loaded into a configMap and provided to the terrascan server. @@ -45,21 +65,49 @@ Once your TLS certificate is generated and the values in the `values.yaml` configuration file have been reviewed, you can install the chart with the following command: -``` -helm install . -``` -Where `` is the name you want to assign to this installed chart. This value will be used in various resources to make them both distinct and identifable. +1. Deploying Terrascan Server. + + *Ensure that your current working directory is `server/`.* + ``` + helm install . + ``` + Where `` is the name you want to assign to this installed chart. + This value will be used in various resources to make them both distinct and identifiable. + + This will use your current namespace unless `-n ` is specified + + #### Verification + + You can query for the pod using the following command. + ``` + kubectl get pod -n -w + ``` + Watch the pod until it attains the `Running` state. + + Verify the logs of the terrascan pod using the following command. + ``` + kubectl -n logs + ``` + If you see a log that goes like `server listening on port : `, the deployment went smooth. + +2. Deploying Validating Webhook. + + *Ensure that your current working directory is `webhook/`.* + ``` + helm install . + ``` + This will use your current namespace unless `-n ` is specified. + ***Ensure that you provide the exact same value as you did to deploy the `server/` chart in step 1.*** + -This will use your current namespace unless `-n ` is specified ## TODO: This chart is a WIP - we intend to add the following functionality in the near future: - [x] Storage support - volume for db - - [ ] Add a documention section for setting the validating-webhook up. - - [ ] Add secrets to add ssh capabilities in the container, to enable remote repo scan feature. + - [x] Add section for setting the validating-webhook up. + - [x] Add secrets to add ssh capabilities in the container, to enable remote repo scan feature. - [ ] Support more load balancer types - [ ] Support for ingress - [ ] Flag for UI enable/disable - [ ] Publish to Artifact hub - [ ] Support TLS certificate/key in existing secrets - diff --git a/deploy/helm-charts/Chart.yaml b/deploy/helm-charts/server/Chart.yaml similarity index 88% rename from deploy/helm-charts/Chart.yaml rename to deploy/helm-charts/server/Chart.yaml index 9d62eeb0c..b02663363 100644 --- a/deploy/helm-charts/Chart.yaml +++ b/deploy/helm-charts/server/Chart.yaml @@ -9,6 +9,10 @@ keywords: - terrascan - opa - security + - webhook + - validating-webhook + - admission-controller + - admission sources: - https://github.com/accurics/terrascan maintainers: diff --git a/deploy/helm-charts/templates/secret.yaml b/deploy/helm-charts/server/templates/cert-secret.yaml similarity index 84% rename from deploy/helm-charts/templates/secret.yaml rename to deploy/helm-charts/server/templates/cert-secret.yaml index 9a6b65229..ad3819762 100644 --- a/deploy/helm-charts/templates/secret.yaml +++ b/deploy/helm-charts/server/templates/cert-secret.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Secret metadata: - name: {{ .Values.secret_name }} + name: {{ .Values.cert_secret_name }} namespace: {{ .Release.Namespace }} type: Opaque data: diff --git a/deploy/helm-charts/templates/configmap.yaml b/deploy/helm-charts/server/templates/configmap.yaml similarity index 61% rename from deploy/helm-charts/templates/configmap.yaml rename to deploy/helm-charts/server/templates/configmap.yaml index 2b6d398f3..331fa2d9e 100644 --- a/deploy/helm-charts/templates/configmap.yaml +++ b/deploy/helm-charts/server/templates/configmap.yaml @@ -1,4 +1,4 @@ -{{- $globconfig := .Files.Glob "../data/config.toml" }} +{{- $globconfig := .Files.Glob "data/config.toml" }} {{- if $globconfig }} apiVersion: v1 kind: ConfigMap @@ -7,5 +7,5 @@ metadata: namespace: {{ .Release.Namespace }} data: terrascan-config: |- - {{ .Files.Get "../data/config.toml" | b64enc }} + {{ .Files.Get "data/config.toml" | b64enc }} {{- end }} diff --git a/deploy/helm-charts/templates/deployment.yaml b/deploy/helm-charts/server/templates/deployment.yaml similarity index 79% rename from deploy/helm-charts/templates/deployment.yaml rename to deploy/helm-charts/server/templates/deployment.yaml index c87fc3b70..7af7de0d4 100644 --- a/deploy/helm-charts/templates/deployment.yaml +++ b/deploy/helm-charts/server/templates/deployment.yaml @@ -43,34 +43,39 @@ spec: - "-l" - "debug" {{- end }} -{{- $globconfig := .Files.Glob "../data/config.toml" }} +{{- $globconfig := .Files.Glob "data/config.toml" }} {{- if $globconfig }} - "-c" - "/etc/config/terrascan-config" {{- end }} env: - name: "K8S_WEBHOOK_API_KEY" - value: {{ .Values.terrascan_api_key}} + value: {{ .Values.terrascan_webhook_key}} volumeMounts: - name: cert-volume mountPath: /etc/certs -{{- $globconfig := .Files.Glob "../data/config.toml" }} + - name: ssh-volume + mountPath: /home/terrascan/.ssh +{{- $globconfig := .Files.Glob "data/config.toml" }} {{- if $globconfig }} - name: config-volume mountPath: /etc/config {{- end }} - name: terrascan-data-sync mountPath: /home/terrascan/.terrascan - volumes: - name: cert-volume secret: - secretName: {{ .Values.secret_name }} -{{- $globconfig := .Files.Glob "../data/config.toml" }} + secretName: {{ .Values.cert_secret_name }} + - name: ssh-volume + secret: + secretName: {{ .Values.ssh_secret_name }} + optional: true +{{- $globconfig := .Files.Glob "data/config.toml" }} {{- if $globconfig }} - name: config-volume configMap: - configMapName: {{ .Values.configname }} + configMapName: {{ .Values.config_name }} {{- end }} {{- if and .Values.persistence.enabled .Values.persistence.existingClaim }} - name: terrascan-data-sync diff --git a/deploy/helm-charts/templates/service.yaml b/deploy/helm-charts/server/templates/service.yaml similarity index 100% rename from deploy/helm-charts/templates/service.yaml rename to deploy/helm-charts/server/templates/service.yaml diff --git a/deploy/helm-charts/server/templates/ssh-secret.yaml b/deploy/helm-charts/server/templates/ssh-secret.yaml new file mode 100644 index 000000000..f14ea7f8b --- /dev/null +++ b/deploy/helm-charts/server/templates/ssh-secret.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.ssh_secret_name }} + namespace: {{ .Release.Namespace }} +type: Opaque +data: + private-key: |- + {{ .Files.Get ".ssh/private_key" | b64enc }} + known-hosts: |- + {{ .Files.Get ".ssh/known_hosts" | b64enc }} diff --git a/deploy/helm-charts/values.yaml b/deploy/helm-charts/server/values.yaml similarity index 64% rename from deploy/helm-charts/values.yaml rename to deploy/helm-charts/server/values.yaml index 3202f1597..6ee736420 100644 --- a/deploy/helm-charts/values.yaml +++ b/deploy/helm-charts/server/values.yaml @@ -1,7 +1,8 @@ -terrascan_api_key: terrakey +terrascan_webhook_key: terrakey terrascan_container_image: accurics/terrascan:1.6.0 use_debug: true -secret_name: terrascancerts +cert_secret_name: terrascancerts +ssh_secret_name: terrascanssh config_name: terrascanconfig name: terrascan persistence: diff --git a/deploy/helm-charts/webhook/Chart.yaml b/deploy/helm-charts/webhook/Chart.yaml new file mode 100644 index 000000000..c94a4d63e --- /dev/null +++ b/deploy/helm-charts/webhook/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +name: terrascan +version: 1.0.0 +appVersion: v1.6.0 +description: A Helm chart for running terrascan in server mode +icon: https://raw.githubusercontent.com/accurics/terrascan/master/docs/img/terrascan-icon-white.png +home: https://github.com/accurics/terrascan +keywords: + - terrascan + - opa + - security +sources: + - https://github.com/accurics/terrascan +maintainers: + - name: jlk + email: jlk@accurics.com + - name: dev-gaur + email: devang.gaur@accurics.com diff --git a/deploy/helm-charts/webhook/templates/validating-webhook.yaml b/deploy/helm-charts/webhook/templates/validating-webhook.yaml new file mode 100644 index 000000000..4490fd774 --- /dev/null +++ b/deploy/helm-charts/webhook/templates/validating-webhook.yaml @@ -0,0 +1,59 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ .Values.name }} +webhooks: + - name: {{ .Values.webhook.name }} + admissionReviewVersions: + {{- range .Values.webhook.admissionReviewVersions }} + - {{ . | printf "%s" }} + {{ end }} + failurePolicy: {{ .Values.webhook.failurePolicy }} + sideEffects: {{ .Values.webhook.sideEffects }} + clientConfig: + service: + name: {{ .Values.name }} + namespace: {{ .Release.Namespace }} + path: {{ .Values.terrascan_webhook_key | printf "/v1/k8s/webhooks/%s/scan/validate" }} + caBundle: {{ .Files.Get "data/server.crt" | b64enc }} + rules: + - apiGroups: + {{- range .Values.webhook.apiGroups }} + {{- if eq . ""}} + - "" + {{- else if eq . "*" }} + - "*" + {{- else }} + - {{ . -}} + {{- end }} + {{- end }} + resources: + {{- range .Values.webhook.resources }} + {{- if eq . ""}} + - "" + {{- else if eq . "*" }} + - "*" + {{- else }} + - {{ . -}} + {{- end }} + {{- end }} + apiVersions: + {{- range .Values.webhook.apiVersions }} + {{- if eq . ""}} + - "" + {{- else if eq . "*" }} + - "*" + {{- else }} + - {{ . -}} + {{- end }} + {{- end }} + operations: + {{- range .Values.webhook.operations }} + {{- if eq . ""}} + - "" + {{- else if eq . "*" }} + - "*" + {{- else }} + - {{ . -}} + {{- end }} + {{- end }} diff --git a/deploy/helm-charts/webhook/values.yaml b/deploy/helm-charts/webhook/values.yaml new file mode 100644 index 000000000..618dca158 --- /dev/null +++ b/deploy/helm-charts/webhook/values.yaml @@ -0,0 +1,20 @@ +terrascan_webhook_key: terrakey +name: terrascan +webhook: + name: webhook.terrascan.io + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - "v1" + - "v1beta1" + apiGroups: + - "apps" + - "" + resources: + - "deployments" + - "pods" + apiVersions: + - "*" + operations: + - CREATE + - UPDATE