> For the complete documentation index, see [llms.txt](https://asafahmadov.gitbook.io/hands-on-projects/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://asafahmadov.gitbook.io/hands-on-projects/ghost-app/release-and-deploy-phase.md).

# RELEASE and DEPLOY Phase

Deployment can be of infrastructure or application; however, we should scan our deployment files. We can also add a manual trigger where the pipeline waits for external user validation before proceeding to the next stage, or it can be an automated trigger.

#### Static scan of Kubernetes manifest file or Helm chart <a href="#id-51-static-scan-of-kubernete-manifest-file-or-helm-chart" id="id-51-static-scan-of-kubernete-manifest-file-or-helm-chart"></a>

It is always a good practice to scan your Kubernetes deployment or Helm chart before deploying. We can use [Checkov](https://github.com/bridgecrewio/checkov) to scans Kubernetes manifests and identifies security and configuration issues. It also supports Helm chart scanning. We can also use [terrascan](https://github.com/tenable/terrascan) and [kubeLinter](https://github.com/stackrox/kube-linter) to scan the Kubernetes manifest.

```
docker run -t -v $(pwd):/output bridgecrew/checkov -f /output/keycloak-deploy.yml -o json
# For Helm
docker run -t -v $(pwd):/output bridgecrew/checkov -d /output/ --framework helm -o json
```

#### Pre-deploy policy check Kubernete manifest YAML file <a href="#id-52-pre-deploy-policy-check-kubernete-manifest-yaml-file" id="id-52-pre-deploy-policy-check-kubernete-manifest-yaml-file"></a>

[Kyverno](https://github.com/kyverno/kyverno/) adds an extra layer of security where only the allowed type of manifest is deployed onto kubernetes, otherwise, it will reject or we can set `validationFailureAction` to audit which only logs the policy violation message for reporting. [Kubewarden](https://www.kubewarden.io/) and [Gatekeeper](https://github.com/open-policy-agent/gatekeeper) are alternative tools available to enforce policies on Kubernetes CRD.

Here is a simple [Kyverno policy](https://kyverno.io/policies/) to [disallow the image’s latest tag](https://kyverno.io/policies/best-practices/disallow-latest-tag/disallow-latest-tag/).

#### kube-bench for CIS scan <a href="#id-53-kube-bench-for-cis-scan" id="id-53-kube-bench-for-cis-scan"></a>

[kube-bench](https://github.com/aquasecurity/kube-bench) checks whether Kubernetes is deployed securely by running the checks documented in the CIS Kubernetes Benchmark. We can [deploy kube-bench](https://www.infracloud.io/blogs/securing-kubernetes-cluster-kubescape-kubebench/) as a Job that runs daily and consume its report in CI/CD to pass or fail the pipeline based on the level of severity.

```
kubectl apply -f eks-job.yaml
kubectl logs kube-bench-pod-name
```

#### IaC scanning: <a href="#id-54-iac-scanning" id="id-54-iac-scanning"></a>

* [Checkov](https://github.com/bridgecrewio/checkov), [Terrascan,](https://github.com/tenable/terrascan) and [Kics](https://github.com/Checkmarx/kics) can be used to scan our Infrastructure code. It supports Terraform, Cloudformation, and Azure ARM resources.
* [Terratest](https://github.com/gruntwork-io/terratest) can be used to test infrastructure in real-time.

```
terraform init
terraform plan -out tf.plan
terraform show -json tf.plan | jq '.' > tf.json
checkov -f tf.json
```

After scanning for Kubernetes deployment and kube-bench we can deploy our application.

{% code title="gitlab-ci.yaml" %}

```yaml
gcloud_deploy:
  stage: gkedeploy
  image: google/cloud-sdk
  script:
    - echo "$GCLOUD_SERVICE_KEY" | base64 -d > gcloud-service-key.json
    - gcloud auth activate-service-account --key-file gcloud-service-key.json
    - gcloud config set project mythical-cider-396513
    - gcloud config set container/cluster ghost-cluster
    - gcloud config set compute/zone asia-east1-a
    - gcloud container clusters get-credentials ghost-cluster --zone asia-east1-a --project mythical-cider-396513
    - kubectl apply -f k8s/ghost/ghost-dep.yaml
```

{% endcode %}

![](/files/kHKiSwCJeoDXqof6ZvZR)
