├── .gitignore ├── Images ├── 1.NodeJs.jpg ├── Devsecops-logo.jpg ├── Devsecops.png ├── Devsecops1.png ├── Devsecopspipeline.jpg ├── Grafana-App-Dashboard.jpg ├── Grafana-alert.jpg ├── Jenkins-status.jpg ├── Jenkins │ ├── Jenkins-access.jpg │ ├── Jenkins-create-user.jpg │ ├── plugins-1.jpg │ └── plugins.jpg ├── Scanners │ ├── tfsec-version.jpg │ └── trivy-version.jpg ├── Sonar │ ├── 10.sonar-update.jpg │ ├── 12.sonar-success.jpg │ ├── 14.sonarserver-add.jpg │ ├── 9.sonar.jpg │ ├── Jenkins-sonar-success.jpg │ ├── Sonarqube-passed.jpg │ ├── sonar-analysis.jpg │ ├── sonar-excuteshell.jpg │ ├── sonar-path.jpg │ ├── sonar-scanner-path.jpg │ └── sonar-token.jpg ├── ansible-version.jpg ├── docker-image-build.jpg ├── docker-status.jpg ├── dockerhub-success.jpg ├── git-path.jpg ├── git.jpg ├── grafana-1.jpg ├── grafana-dashboard.jpg ├── grafana-data-source.jpg ├── grafana-load-nodejs.jpg ├── grafana-nodejs-id.jpg ├── grafana-prebuild.jpg ├── grafana-prometheus-trivy.jpg ├── grafana-prometheus.jpg ├── grafana-trivy-query.jpg ├── grafana-trivy.jpg ├── java-version.jpg ├── jenkins-install-plugins-started.jpg ├── jenkins-url.jpg ├── jenkisn-suggested-pluggins.jpg ├── jennkins-credential.jpg ├── metrics.jpg ├── nexus-config.jpg ├── nexus-credentials-update.jpg ├── nexus-credentials.jpg ├── nexus-launch.jpg ├── nexus-url.jpg ├── nodejs-version.jpg ├── otel-config.jpg ├── otel-custom-metrics.jpg ├── otel-logo.png ├── otel-memory-bytes.jpg ├── otel-metrics.jpg ├── otel-process-cpu.jpg ├── otel-process-start.jpg ├── otel-success.jpg ├── otel-up.jpg ├── otel-version.jpg ├── port-change.jpg ├── prome.jpg ├── prometheus-config.jpg ├── prometheus-dashboard.jpg ├── prometheus.jpg ├── running-node-server.jpg ├── slack-plugin.jpg ├── snyk-token.jpg ├── snyk-version.jpg ├── sonarqube-container.jpg ├── sonarqube-version.jpg ├── terraform-path.jpg ├── terraform │ └── succesfull-installation .jpg ├── tf-metrics.jpg ├── tf.jpg ├── tfsec-config.jpg ├── tfsec-manual.jpg ├── tfsec-metrics-logs.jpg ├── tfsec-ouput.jpg ├── tfsec-query.jpg ├── tfsec-up.jpg ├── tfsec_vulnerabilities.jpg ├── trivy-config.jpg ├── trivy-metrics-logs.jpg ├── trivy-metrics.jpg ├── trivy-prometheus.jpg ├── trivy-succes.jpg ├── trivy-vulnerabilities.jpg ├── vault-job-success.jpg ├── vault-login.jpg ├── version-verification.jpg └── web.jpg ├── Jenkinsfile └── Jenkinsfile ├── Prometheus └── prometheus.yaml ├── Readme.md ├── ansible └── playbook.yml ├── src ├── .dockerignore ├── Dockerfile ├── jest.config.js ├── otel-collector-config.yaml ├── package.json ├── public │ ├── index.html │ ├── script.js │ └── style.css ├── server.js └── test │ ├── jest.config.js │ └── server.test.js └── terraform ├── .gitignore ├── main.tf ├── output.tf └── variables.tf /.gitignore: -------------------------------------------------------------------------------- 1 | demo.md -------------------------------------------------------------------------------- /Images/1.NodeJs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/1.NodeJs.jpg -------------------------------------------------------------------------------- /Images/Devsecops-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Devsecops-logo.jpg -------------------------------------------------------------------------------- /Images/Devsecops.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Devsecops.png -------------------------------------------------------------------------------- /Images/Devsecops1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Devsecops1.png -------------------------------------------------------------------------------- /Images/Devsecopspipeline.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Devsecopspipeline.jpg -------------------------------------------------------------------------------- /Images/Grafana-App-Dashboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Grafana-App-Dashboard.jpg -------------------------------------------------------------------------------- /Images/Grafana-alert.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Grafana-alert.jpg -------------------------------------------------------------------------------- /Images/Jenkins-status.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Jenkins-status.jpg -------------------------------------------------------------------------------- /Images/Jenkins/Jenkins-access.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Jenkins/Jenkins-access.jpg -------------------------------------------------------------------------------- /Images/Jenkins/Jenkins-create-user.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Jenkins/Jenkins-create-user.jpg -------------------------------------------------------------------------------- /Images/Jenkins/plugins-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Jenkins/plugins-1.jpg -------------------------------------------------------------------------------- /Images/Jenkins/plugins.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Jenkins/plugins.jpg -------------------------------------------------------------------------------- /Images/Scanners/tfsec-version.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Scanners/tfsec-version.jpg -------------------------------------------------------------------------------- /Images/Scanners/trivy-version.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Scanners/trivy-version.jpg -------------------------------------------------------------------------------- /Images/Sonar/10.sonar-update.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Sonar/10.sonar-update.jpg -------------------------------------------------------------------------------- /Images/Sonar/12.sonar-success.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Sonar/12.sonar-success.jpg -------------------------------------------------------------------------------- /Images/Sonar/14.sonarserver-add.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Sonar/14.sonarserver-add.jpg -------------------------------------------------------------------------------- /Images/Sonar/9.sonar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Sonar/9.sonar.jpg -------------------------------------------------------------------------------- /Images/Sonar/Jenkins-sonar-success.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Sonar/Jenkins-sonar-success.jpg -------------------------------------------------------------------------------- /Images/Sonar/Sonarqube-passed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Sonar/Sonarqube-passed.jpg -------------------------------------------------------------------------------- /Images/Sonar/sonar-analysis.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Sonar/sonar-analysis.jpg -------------------------------------------------------------------------------- /Images/Sonar/sonar-excuteshell.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Sonar/sonar-excuteshell.jpg -------------------------------------------------------------------------------- /Images/Sonar/sonar-path.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Sonar/sonar-path.jpg -------------------------------------------------------------------------------- /Images/Sonar/sonar-scanner-path.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Sonar/sonar-scanner-path.jpg -------------------------------------------------------------------------------- /Images/Sonar/sonar-token.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/Sonar/sonar-token.jpg -------------------------------------------------------------------------------- /Images/ansible-version.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/ansible-version.jpg -------------------------------------------------------------------------------- /Images/docker-image-build.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/docker-image-build.jpg -------------------------------------------------------------------------------- /Images/docker-status.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/docker-status.jpg -------------------------------------------------------------------------------- /Images/dockerhub-success.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/dockerhub-success.jpg -------------------------------------------------------------------------------- /Images/git-path.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/git-path.jpg -------------------------------------------------------------------------------- /Images/git.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/git.jpg -------------------------------------------------------------------------------- /Images/grafana-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/grafana-1.jpg -------------------------------------------------------------------------------- /Images/grafana-dashboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/grafana-dashboard.jpg -------------------------------------------------------------------------------- /Images/grafana-data-source.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/grafana-data-source.jpg -------------------------------------------------------------------------------- /Images/grafana-load-nodejs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/grafana-load-nodejs.jpg -------------------------------------------------------------------------------- /Images/grafana-nodejs-id.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/grafana-nodejs-id.jpg -------------------------------------------------------------------------------- /Images/grafana-prebuild.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/grafana-prebuild.jpg -------------------------------------------------------------------------------- /Images/grafana-prometheus-trivy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/grafana-prometheus-trivy.jpg -------------------------------------------------------------------------------- /Images/grafana-prometheus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/grafana-prometheus.jpg -------------------------------------------------------------------------------- /Images/grafana-trivy-query.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/grafana-trivy-query.jpg -------------------------------------------------------------------------------- /Images/grafana-trivy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/grafana-trivy.jpg -------------------------------------------------------------------------------- /Images/java-version.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/java-version.jpg -------------------------------------------------------------------------------- /Images/jenkins-install-plugins-started.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/jenkins-install-plugins-started.jpg -------------------------------------------------------------------------------- /Images/jenkins-url.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/jenkins-url.jpg -------------------------------------------------------------------------------- /Images/jenkisn-suggested-pluggins.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/jenkisn-suggested-pluggins.jpg -------------------------------------------------------------------------------- /Images/jennkins-credential.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/jennkins-credential.jpg -------------------------------------------------------------------------------- /Images/metrics.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/metrics.jpg -------------------------------------------------------------------------------- /Images/nexus-config.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/nexus-config.jpg -------------------------------------------------------------------------------- /Images/nexus-credentials-update.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/nexus-credentials-update.jpg -------------------------------------------------------------------------------- /Images/nexus-credentials.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/nexus-credentials.jpg -------------------------------------------------------------------------------- /Images/nexus-launch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/nexus-launch.jpg -------------------------------------------------------------------------------- /Images/nexus-url.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/nexus-url.jpg -------------------------------------------------------------------------------- /Images/nodejs-version.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/nodejs-version.jpg -------------------------------------------------------------------------------- /Images/otel-config.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/otel-config.jpg -------------------------------------------------------------------------------- /Images/otel-custom-metrics.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/otel-custom-metrics.jpg -------------------------------------------------------------------------------- /Images/otel-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/otel-logo.png -------------------------------------------------------------------------------- /Images/otel-memory-bytes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/otel-memory-bytes.jpg -------------------------------------------------------------------------------- /Images/otel-metrics.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/otel-metrics.jpg -------------------------------------------------------------------------------- /Images/otel-process-cpu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/otel-process-cpu.jpg -------------------------------------------------------------------------------- /Images/otel-process-start.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/otel-process-start.jpg -------------------------------------------------------------------------------- /Images/otel-success.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/otel-success.jpg -------------------------------------------------------------------------------- /Images/otel-up.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/otel-up.jpg -------------------------------------------------------------------------------- /Images/otel-version.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/otel-version.jpg -------------------------------------------------------------------------------- /Images/port-change.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/port-change.jpg -------------------------------------------------------------------------------- /Images/prome.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/prome.jpg -------------------------------------------------------------------------------- /Images/prometheus-config.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/prometheus-config.jpg -------------------------------------------------------------------------------- /Images/prometheus-dashboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/prometheus-dashboard.jpg -------------------------------------------------------------------------------- /Images/prometheus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/prometheus.jpg -------------------------------------------------------------------------------- /Images/running-node-server.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/running-node-server.jpg -------------------------------------------------------------------------------- /Images/slack-plugin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/slack-plugin.jpg -------------------------------------------------------------------------------- /Images/snyk-token.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/snyk-token.jpg -------------------------------------------------------------------------------- /Images/snyk-version.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/snyk-version.jpg -------------------------------------------------------------------------------- /Images/sonarqube-container.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/sonarqube-container.jpg -------------------------------------------------------------------------------- /Images/sonarqube-version.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/sonarqube-version.jpg -------------------------------------------------------------------------------- /Images/terraform-path.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/terraform-path.jpg -------------------------------------------------------------------------------- /Images/terraform/succesfull-installation .jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/terraform/succesfull-installation .jpg -------------------------------------------------------------------------------- /Images/tf-metrics.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/tf-metrics.jpg -------------------------------------------------------------------------------- /Images/tf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/tf.jpg -------------------------------------------------------------------------------- /Images/tfsec-config.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/tfsec-config.jpg -------------------------------------------------------------------------------- /Images/tfsec-manual.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/tfsec-manual.jpg -------------------------------------------------------------------------------- /Images/tfsec-metrics-logs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/tfsec-metrics-logs.jpg -------------------------------------------------------------------------------- /Images/tfsec-ouput.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/tfsec-ouput.jpg -------------------------------------------------------------------------------- /Images/tfsec-query.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/tfsec-query.jpg -------------------------------------------------------------------------------- /Images/tfsec-up.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/tfsec-up.jpg -------------------------------------------------------------------------------- /Images/tfsec_vulnerabilities.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/tfsec_vulnerabilities.jpg -------------------------------------------------------------------------------- /Images/trivy-config.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/trivy-config.jpg -------------------------------------------------------------------------------- /Images/trivy-metrics-logs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/trivy-metrics-logs.jpg -------------------------------------------------------------------------------- /Images/trivy-metrics.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/trivy-metrics.jpg -------------------------------------------------------------------------------- /Images/trivy-prometheus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/trivy-prometheus.jpg -------------------------------------------------------------------------------- /Images/trivy-succes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/trivy-succes.jpg -------------------------------------------------------------------------------- /Images/trivy-vulnerabilities.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/trivy-vulnerabilities.jpg -------------------------------------------------------------------------------- /Images/vault-job-success.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/vault-job-success.jpg -------------------------------------------------------------------------------- /Images/vault-login.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/vault-login.jpg -------------------------------------------------------------------------------- /Images/version-verification.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/version-verification.jpg -------------------------------------------------------------------------------- /Images/web.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevopsProjects05/DevSecOps-End-to-End-Project/41b859d7336af81816290195a2e2b4386b5f3221/Images/web.jpg -------------------------------------------------------------------------------- /Jenkinsfile/Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent any 3 | environment { 4 | VAULT_ADDR = credentials('VAULT_ADDR') 5 | VAULT_TOKEN = credentials('VAULT_TOKEN') 6 | PATH = "/opt/sonar-scanner/bin:$PATH" 7 | TERRAFORM_DIR = "terraform/" 8 | 9 | } 10 | stages { 11 | 12 | stage('Test Vault') { 13 | steps { 14 | sh ''' 15 | echo "Testing Vault Connection..." 16 | export VAULT_ADDR="${VAULT_ADDR}" 17 | export VAULT_TOKEN="${VAULT_TOKEN}" 18 | 19 | vault read -format=json aws/creds/dev-role > aws_creds.json || { echo "Vault read failed"; exit 1; } 20 | jq -r '.data.access_key' aws_creds.json > access_key.txt 21 | jq -r '.data.secret_key' aws_creds.json > secret_key.txt 22 | ''' 23 | } 24 | } 25 | 26 | stage('Run Node.js Tests') { 27 | steps { 28 | dir('src') { 29 | sh ''' 30 | echo "Running Node.js tests..." 31 | npm install || { echo "npm install failed"; exit 1; } 32 | ''' 33 | } 34 | } 35 | } 36 | 37 | stage('SonarQube Analysis') { 38 | steps { 39 | script { 40 | withSonarQubeEnv('SonarQube') { 41 | sh ''' 42 | echo "Running SonarQube Analysis..." 43 | sonar-scanner \ 44 | -Dsonar.projectKey=Project \ 45 | -Dsonar.sources=src \ 46 | -Dsonar.host.url=http://13.201.137.168:9000/ \ 47 | -Dsonar.login=sqa_6c22027d63c27dc6b4aa343136c1e112465616a8 | tee sonar-report.txt 48 | ''' 49 | } 50 | 51 | } 52 | } 53 | } 54 | 55 | stage('Snyk Security Scan') { 56 | steps { 57 | dir('src') { 58 | sh ''' 59 | echo "Running Snyk Security Scan..." 60 | snyk test --json > snyk-results.json || echo "Snyk scan completed with warnings." 61 | ''' 62 | } 63 | archiveArtifacts artifacts: 'src/snyk-results.json', allowEmptyArchive: true 64 | } 65 | } 66 | 67 | stage('TFScan') { 68 | steps { 69 | dir('terraform') { 70 | sh ''' 71 | echo "Running TFScan..." 72 | tfsec . > tfsec-results.json || { echo "TFSec scan failed"; exit 1; } 73 | ''' 74 | } 75 | archiveArtifacts artifacts: 'terraform/tfscan-report.txt', allowEmptyArchive: true 76 | } 77 | } 78 | 79 | stage('Terraform init & Plan') { 80 | steps { 81 | dir('terraform') { 82 | sh ''' 83 | echo "Initializing Terraform..." 84 | terraform init || { echo "Terraform init failed"; exit 1; } 85 | 86 | echo "Planning Terraform changes..." 87 | terraform plan -out=tfplan -var="aws_access_key=$(cat ../access_key.txt)" -var="aws_secret_key=$(cat ../secret_key.txt)" 88 | ''' 89 | } 90 | } 91 | } 92 | 93 | stage('Docker Build and Trivy Scan') { 94 | steps { 95 | dir('src') { 96 | sh ''' 97 | echo "Fetching Docker credentials from Vault..." 98 | export VAULT_ADDR="${VAULT_ADDR}" 99 | export VAULT_TOKEN="${VAULT_TOKEN}" 100 | 101 | DOCKER_USERNAME=$(vault kv get -field=username secret/docker) 102 | DOCKER_PASSWORD=$(vault kv get -field=password secret/docker) 103 | 104 | echo "Building Docker image..." 105 | docker build -t $DOCKER_USERNAME/sample-ecommerce-nodejs-app:latest . || { echo "Docker build failed"; exit 1; } 106 | 107 | echo "Scanning Docker image with Trivy..." 108 | trivy image --severity HIGH,CRITICAL $DOCKER_USERNAME/sample-ecommerce-nodejs-app:latest > trivy-results.json 109 | 110 | echo "Logging in to Docker Hub..." 111 | echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin 112 | 113 | echo "Pushing Docker image to Docker Hub..." 114 | docker push $DOCKER_USERNAME/sample-ecommerce-nodejs-app:latest 115 | ''' 116 | echo "Archiving Trivy scan results..." 117 | archiveArtifacts artifacts: 'trivy-results.json', allowEmptyArchive: true 118 | 119 | 120 | } 121 | } 122 | } 123 | 124 | stage('Nexus Integration') { 125 | steps { 126 | script { 127 | echo 'Fetching Nexus credentials from Vault...' 128 | // Fetch credentials from Vault 129 | NEXUS_USERNAME = sh(script: 'vault kv get -field=username nexus/credentials', returnStdout: true).trim() 130 | NEXUS_PASSWORD = sh(script: 'vault kv get -field=password nexus/credentials', returnStdout: true).trim() 131 | NEXUS_REPO_URL = sh(script: 'vault kv get -field=repo_url nexus/credentials', returnStdout: true).trim() 132 | 133 | echo 'Uploading Node.js app to Nexus...' 134 | // Create a temporary directory for the archive 135 | sh ''' 136 | mkdir -p tmp 137 | tar -czf tmp/app.tar.gz src/ 138 | ''' 139 | 140 | // Upload the archive to Nexus 141 | sh """ 142 | curl -u ${NEXUS_USERNAME}:${NEXUS_PASSWORD} \ 143 | --upload-file tmp/app.tar.gz \ 144 | ${NEXUS_REPO_URL}/repository/nodejs-app/ 145 | """ 146 | } 147 | } 148 | } 149 | 150 | stage('Terraform Apply') { 151 | steps { 152 | dir('terraform') { 153 | withCredentials([sshUserPrivateKey(credentialsId: 'ANSIBLE_SSH_KEY', keyFileVariable: 'SSH_KEY_PATH')]) { 154 | sh ''' 155 | 156 | echo "Applying Terraform changes..." 157 | terraform apply -auto-approve tfplan 158 | 159 | echo "Fetching Public IP from Terraform output..." 160 | PUBLIC_IP=$(terraform output -json public_ips | jq -r '.[0]') 161 | if [ -z "$PUBLIC_IP" ]; then 162 | echo "Error: Terraform did not return a public IP!" 163 | exit 1 164 | fi 165 | echo "Public IP: ${PUBLIC_IP}" 166 | 167 | echo "Storing Public IP in Ansible inventory..." 168 | mkdir -p ../ansible 169 | echo "[webserver]" > ../ansible/inventory.ini 170 | echo "${PUBLIC_IP} ansible_user=ec2-user ansible_ssh_private_key_file=$WORKSPACE/ansible/ansible_ssh_key.pem" >> ../ansible/inventory.ini 171 | 172 | echo "Verifying inventory file..." 173 | cat ../ansible/inventory.ini 174 | ''' 175 | } 176 | } 177 | } 178 | } 179 | 180 | stage('Run Ansible Playbook') { 181 | steps { 182 | dir('ansible') { 183 | withCredentials([sshUserPrivateKey(credentialsId: 'ANSIBLE_SSH_KEY', keyFileVariable: 'SSH_KEY_PATH')]) { 184 | sh ''' 185 | echo "Fixing SSH key permissions..." 186 | chmod 400 ${SSH_KEY_PATH} 187 | 188 | echo "Copying SSH Key to a Safe Location in Jenkins Workspace..." 189 | mkdir -p $WORKSPACE/ansible 190 | cp ${SSH_KEY_PATH} $WORKSPACE/ansible/ansible_ssh_key.pem 191 | chmod 400 $WORKSPACE/ansible/ansible_ssh_key.pem 192 | 193 | echo "Verifying inventory file..." 194 | if [ ! -f "inventory.ini" ]; then 195 | echo "Error: inventory.ini not found! Terraform Apply may have failed." 196 | exit 1 197 | fi 198 | cat inventory.ini 199 | 200 | # Extract the first IP from inventory file 201 | PUBLIC_IP=$(awk 'NR==2 {print $1}' inventory.ini) 202 | if [ -z "$PUBLIC_IP" ]; then 203 | echo "Error: No public IP found in inventory.ini!" 204 | exit 1 205 | fi 206 | echo "Public IP from inventory.ini: $PUBLIC_IP" 207 | 208 | echo "Disabling SSH host key checking..." 209 | export ANSIBLE_HOST_KEY_CHECKING=False 210 | 211 | echo "Checking for Ansible playbook..." 212 | if [ ! -f "playbook.yml" ]; then 213 | echo "Error: playbook.yml not found! Ensure the playbook is available." 214 | exit 1 215 | fi 216 | 217 | echo "Running Ansible Playbook..." 218 | ansible-playbook -i inventory.ini playbook.yml \ 219 | --private-key=$WORKSPACE/ansible/ansible_ssh_key.pem \ 220 | --user ec2-user -vvv || { echo "Ansible Playbook execution failed!"; exit 1; } 221 | 222 | echo "Ansible Playbook executed successfully." 223 | ''' 224 | } 225 | } 226 | } 227 | } 228 | 229 | 230 | stage('Send Slack Notification') { 231 | steps { 232 | script { 233 | def buildStatus = currentBuild.currentResult 234 | def color = (buildStatus == 'SUCCESS') ? 'good' : 'danger' 235 | 236 | slackSend ( 237 | channel: '#team-devops', 238 | message: "🚀 *Jenkins Pipeline Execution Completed: ${buildStatus}*", 239 | color: color 240 | ) 241 | } 242 | } 243 | } 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /Prometheus/prometheus.yaml: -------------------------------------------------------------------------------- 1 | # my global config 2 | global: 3 | scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. 4 | evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. 5 | # scrape_timeout is set to the global default (10s). 6 | 7 | # Alertmanager configuration 8 | alerting: 9 | alertmanagers: 10 | - static_configs: 11 | - targets: 12 | # - alertmanager:9093 13 | 14 | # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. 15 | rule_files: 16 | # - "first_rules.yml" 17 | # - "second_rules.yml" 18 | 19 | # A scrape configuration containing exactly one endpoint to scrape: 20 | # Here it's Prometheus itself. 21 | scrape_configs: 22 | # The job name is added as a label `job=` to any timeseries scraped from this config. 23 | - job_name: "node-js-app" 24 | 25 | # metrics_path defaults to '/metrics' 26 | # scheme defaults to 'http'. 27 | 28 | static_configs: 29 | - targets: ["localhost:3000"] 30 | 31 | - job_name: "trivy" 32 | static_configs: 33 | - targets: ["65.2.150.42:8085"] # Replace with your Public IP 34 | 35 | - job_name: "tfsec" 36 | static_configs: 37 | - targets: ["52.66.246.248:8086"] # Replace with your Public IP 38 | 39 | 40 | - job_name: 'otel-collector' 41 | scrape_interval: 5s 42 | static_configs: 43 | - targets: ["52.66.246.248:8888"] # Replace with your Public IP 44 | 45 | 46 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # 🚀 End-to-End DevSecOps Implementation: CI/CD, Security, and Monitoring 2 | 3 | ## Table of Content: 4 | - [Project Overview](#project-overview) 5 | - [Key Objectives](#key-objectives) 6 | - [Architecture](#architecture) 7 | - [Create Jenkins Server](#create-jenkins-server) 8 | - [Install OpenTelemetry and Project Dependencies](#install-opentelemetry-and-project-dependencies) 9 | - [Jenkins Installation](#jenkins-installation) 10 | - [Configuring Jenkins for CI/CD with Additional Tools](#configuring-jenkins-for-cicd-with-additional-tools) 11 | - [Troubleshooting Jenkins IP Address Updates](#troubleshooting-jenkins-ip-address-updates) 12 | - [Configure Tools](#configure-tools) 13 | - [Install Terraform](#install-terraform) 14 | - [Install Tfsec](#install-tfsec) 15 | - [Install Trivy](#install-trivy) 16 | - [Install Snyk CLI](#install-snyk-cli) 17 | - [Install Ansible](#install-ansible) 18 | - [Configuring Global Tools in Jenkins](#configuring-global-tools-in-jenkins) 19 | - [Create Your First Job to Verify Jenkins](#create-your-first-job-to-verify-jenkins) 20 | - [Deploying SonarQube as a Container](#deploying-sonarqube-as-a-container) 21 | - [Adding SonarQube Configuration to Jenkins](#adding-sonarqube-configuration-to-jenkins) 22 | - [Create a New Project in SonarQube](#create-a-new-project-in-sonarqube) 23 | - [Analyze Code with Sonar Scanner](#analyze-code-with-sonar-scanner) 24 | - [Installing HashiCorp Vault for Secure Secrets Management](#installing-hashicorp-vault-for-secure-secrets-management) 25 | - [Integrate Vault for Secrets Management](#integrate-vault-for-secrets-management) 26 | - [Secure Credentials in Jenkins Using HashiCorp Vault](#secure-credentials-in-jenkins-using-hashicorp-vault) 27 | - [Testing HashiCorp Vault in a Freestyle Jenkins Job](#testing-hashicorp-vault-in-a-freestyle-jenkins-job) 28 | - [Integrating Tfsec to Enhance Terraform Security Scanning](#integrating-tfsec-to-enhance-terraform-security-scanning) 29 | - [Integrating Trivy to Enhance Container Image Scanning](#integrating-trivy-to-enhance-container-image-scanning) 30 | - [Push Docker Image to a Container Registry](#push-docker-image-to-a-container-registry) 31 | - [Deploying Nexus Repository as a Docker Container](#deploying-nexus-repository-as-a-docker-container) 32 | - [Securely Managing Credentials with HashiCorp Vault](#securely-managing-credentials-with-hashicorp-vault) 33 | - [Storing Nexus Credentials](#storing-nexus-credentials) 34 | - [Storing Docker Credentials](#storing-docker-credentials) 35 | - [Storing Snyk Token](#storing-snyk-token) 36 | - [Monitoring with Prometheus and Grafana](#monitoring-with-prometheus-and-grafana) 37 | - [From Scans to Dashboards: Unlocking Security Insights with Trivy, Tfsec, Prometheus, and Grafana](#from-scans-to-dashboards-unlocking-security-insights-with-trivy-tfsec-prometheus-and-grafana) 38 | - [OpenTelemetry Setup and Configuration](#opentelemetry-setup-and-configuration) 39 | - [Jenkins Slack Notification Configuration](#jenkins-slack-notification-configuration) 40 | - [Configuring Grafana Alerts for Security and Performance Monitoring](#configuring-grafana-alerts-for-security-and-performance-monitoring) 41 | - [Automating with Jenkins Pipeline](#automating-with-jenkins-pipeline) 42 | - [CI/CD Pipeline: Automated DevSecOps Deployment](#cicd-pipeline-automated-devsecops-deployment) 43 | - [Who Can Use This Project?](#who-can-use-this-project) 44 | - [Challenges and Learnings](#challenges-and-learnings) 45 | - [Future Enhancements](#future-enhancements) 46 | 47 | --- 48 | 49 | ### Project Overview 50 | This DevSecOps project implements a fully automated CI/CD pipeline that integrates security scanning, observability, and infrastructure automation. The project ensures secure application deployment by incorporating static code analysis, container security scanning, infrastructure as code (IaC) validation, and real-time monitoring using industry-leading tools like OpenTelemetry, Prometheus, Grafana, Trivy, and TFSec. 51 | 52 | ### Key Objectives 53 | 54 | ✅ Continuous Integration & Deployment (CI/CD): 55 | Automate application builds, testing, and deployments using Jenkins, Docker, and Node.js to ensure seamless software delivery. 56 | 57 | ✅ Secrets Management: 58 | Securely handle sensitive credentials using HashiCorp Vault, ensuring encrypted access to secrets. 59 | 60 | ✅ Infrastructure as Code (IaC) Security: 61 | Automate infrastructure provisioning with Terraform, enforce best practices, and enhance security using TFSec for IaC validation. 62 | 63 | ✅ Static Code & Dependency Analysis: 64 | Ensure code quality, security, and compliance with SonarQube for static analysis, Snyk for dependency vulnerability scanning, and Trivy for container image security. 65 | 66 | ✅ Monitoring & Observability: 67 | Implement real-time performance tracking and security monitoring using Prometheus, Grafana, and OpenTelemetry to gain full visibility into system health. 68 | 69 | ✅ Artifact Management: 70 | Store, manage, and distribute application artifacts efficiently using Nexus Repository to improve version control and software traceability. 71 | 72 | ✅ Configuration Management: 73 | Automate and standardize system configurations with Ansible for consistent and scalable infrastructure setup. 74 | 75 | ✅ Team Collaboration & Alerting: 76 | Enhance developer communication and incident response by integrating Slack notifications for build failures, security alerts, and deployment updates. 77 | 78 | ## Architecture 79 | --- 80 | ![Architecture](/Images/Devsecops1.png) 81 | 82 | --- 83 | 84 | ### Cost Optimization Decisions 85 | 86 | To ensure a cost-effective solution without compromising on functionality, all tools used in this DevSecOps project have been integrated into the Jenkins server. This approach avoids the need for additional servers or infrastructure, reducing operational costs. 87 | 88 | #### Rationale 89 | - **Centralized Integration**: Running all tools (e.g. Prometheus, Grafana, Trivy, TFsec, SonarQube) on the same server minimizes resource utilization and eliminates the cost of multiple servers. 90 | - **Simplified Management**: Centralized integration simplifies maintenance, monitoring, and updates for all tools. 91 | - **Efficient Resource Usage**: Using the Jenkins server for multi-purpose tasks optimizes the allocated resources, leveraging idle capacity during pipeline executions. 92 | 93 | #### Implementation 94 | - All tools are installed and configured on the Jenkins server instance. 95 | - Prometheus and Grafana are set up to run on separate ports to avoid conflicts. 96 | - Tools like Trivy, TFsec, are containerized or run as CLI tools, leveraging Docker where applicable. 97 | 98 | 99 | --- 100 | ### Running the Application in the Background 101 | 102 | If you want to run the server continuously while using the terminal for other tasks, execute the provided command to run it in the background 103 | 104 | **Why Background Running?** 105 | Running the server in the background avoids the need to open duplicate terminals when integrating other tools or performing additional tasks. 106 | 107 | --- 108 | ## Create Jenkins Server 109 | 110 | ### Creating an EC2 Instance: 111 | 112 | 1. Log in to the AWS Management Console. 113 | 2. Navigate to **EC2 > Instances > Launch Instances**. 114 | 3. Configure the instance: 115 | - **AMI**: Amazon Linux 2. 116 | - **Instance Type**: `t3.xlarge`. 117 | - **Create a key pair** (Store it in Secure place) 118 | - **Storage**: 50 GiB gp2. 119 | - **Security Group**: Allow SSH (port 22) and HTTP (port 8080). 120 | - Assign a key pair. 121 | 4. Launch the instance and wait for it to initialize. 122 | 123 | ### Commands to Run After Launch: 124 | 125 | ```bash 126 | 127 | sudo yum update -y 128 | ``` 129 | ```bash 130 | 131 | sudo yum install git -y 132 | ``` 133 | 134 | ## Install OpenTelemetry and Project Dependencies 135 | 136 | ### 1. Install Node.js and npm 137 | 138 | Node.js is required to run the project, and npm (Node Package Manager) manages the project's dependencies. 139 | 140 | ### Installation Commands: 141 | ```bash 142 | curl -sL https://rpm.nodesource.com/setup_16.x | sudo bash - 143 | sudo yum install nodejs -y 144 | ``` 145 | 146 | ### Verify Installation: 147 | ```bash 148 | node -v 149 | npm -v 150 | ``` 151 | --- 152 | 153 | ![](/Images/nodejs-version.jpg) 154 | 155 | --- 156 | 157 | ### 2. Install Project Dependencies 158 | 159 | This project uses **OpenTelemetry (OTel)** for distributed tracing and observability. Install the necessary OpenTelemetry libraries: 160 | 161 | ### Clone the Project Repository 162 | 163 | 164 | 1. **Clone the Repository**: 165 | Run the following command to clone the GitHub repository: 166 | ```bash 167 | git clone https://github.com/DevopsProjects05/DevSecOps-End-to-End-Project.git 168 | ``` 169 | ```bash 170 | cd DevSecOps-End-to-End-Project/src 171 | ``` 172 | 173 | 2. Install OpenTelemetry libraries: 174 | ```bash 175 | npm install @opentelemetry/sdk-trace-node 176 | ``` 177 | ```bash 178 | npm install @opentelemetry/exporter-trace-otlp-http 179 | ``` 180 | 181 | #### Library Overview: 182 | - **@opentelemetry/sdk-trace-node**: Enables OpenTelemetry tracing in the Node.js application. 183 | - **@opentelemetry/exporter-trace-otlp-http**: Sends trace data from the application to the OpenTelemetry Collector over HTTP using the OTLP protocol. 184 | 185 | 186 | 187 | ### 3. Update the Collector URL in `server.js` 188 | 189 | Configure the application to send trace data to the OpenTelemetry Collector. 190 | 191 | #### Steps: 192 | 1. Open the `server.js` file: 193 | ```bash 194 | vi server.js 195 | ``` 196 | 197 | 2. Locate and update the following line: 198 | ```javascript 199 | url: 'http://:4318/v1/traces' 200 | ``` 201 | 202 | 3. Replace `` with the public IP address of your OpenTelemetry Collector: 203 | ```javascript 204 | url: 'http://public-ip:4318/v1/traces' 205 | ``` 206 | 207 | 4. Save and exit the file. 208 | 209 | 210 | 211 | #### 4. Start the Application 212 | 213 | Run the application to generate and send telemetry data to the OpenTelemetry Collector. 214 | 215 | #### Steps: 216 | 1. Executing node server.js in Background 217 | ```bash 218 | node server.js 219 | ``` 220 | **To Run in the Background:** 221 | This allows you to keep the process running without needing to open duplicate terminals. 222 | 223 | ```bash 224 | node server.js & 225 | ``` 226 | 227 | 2. Access the application at: 228 | ``` 229 | http://:3000 230 | ``` 231 | ### Application Successfully Running on Port 3000 232 | --- 233 | ![](/Images/1.NodeJs.jpg) 234 | --- 235 | 236 | 3. To stop the server: (if you run without &)(optional) 237 | ```bash 238 | Ctrl + C 239 | ``` 240 | 241 | 242 | 243 | ## Jenkins Installation 244 | 245 | 1. Add the Jenkins repository: 246 | 247 | ```bash 248 | sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.repo 249 | sudo rpm --import https://pkg.jenkins.io/redhat/jenkins.io-2023.key 250 | ``` 251 | ```bash 252 | sudo yum upgrade -y 253 | ``` 254 | 255 | 2. Install Java 17: 256 | 257 | ```bash 258 | amazon-linux-extras enable corretto17 259 | sudo yum install -y java-17-amazon-corretto 260 | java --version 261 | ``` 262 | 263 | ### Command Line Execution Result 264 | --- 265 | ![](/Images/java-version.jpg) 266 | 267 | --- 268 | 269 | 3. Install Jenkins: 270 | 271 | ```bash 272 | sudo yum install jenkins -y 273 | ``` 274 | 275 | 4. Enable and start Jenkins: 276 | 277 | ```bash 278 | sudo systemctl enable jenkins 279 | ``` 280 | ```bash 281 | sudo systemctl start jenkins 282 | ``` 283 | ```bash 284 | sudo systemctl status jenkins 285 | ``` 286 | ### Terminal Display of Running Commands 287 | --- 288 | ![](/Images/Jenkins-status.jpg) 289 | 290 | --- 291 | 292 | ### Access Jenkins 293 | 294 | Once you access Jenkins at `http://:8080`, you will see the following page: 295 | 296 | ### Jenkins Server is Up and Running on Port 8080 297 | --- 298 | ![](/Images/Jenkins/Jenkins-access.jpg) 299 | 300 | --- 301 | 302 | ### Retrieving the Initial Admin Password 303 | Run the following command in the terminal: 304 | ```bash 305 | cat /var/lib/jenkins/secrets/initialAdminPassword 306 | ``` 307 | ### Terminal Output Screenshot 308 | --- 309 | ![](/Images/jennkins-credential.jpg) 310 | 311 | --- 312 | Copy the output(initial admin password) and paste in **jenkins server** to continue 313 | 314 | After entering the initial admin password, you will be redirected to a page to install pluggins as shown below: 315 | 316 | --- 317 | ![](/Images/jenkisn-suggested-pluggins.jpg) 318 | 319 | --- 320 | 321 | Select **Install suggested plugins** to install necessary plugins 322 | 323 | ### You will see the plugins are getting installed once you click on suggested plugins: 324 | --- 325 | ![](/Images/jenkins-install-plugins-started.jpg) 326 | 327 | --- 328 | 329 | ### Create Jenkins User 330 | After installing plugins, you will be redirected to a page to set up a Jenkins user account. Fill in the required details: 331 | 332 | ### Here’s the Output You Should See 333 | 334 | --- 335 | ![](/Images/Jenkins/Jenkins-create-user.jpg) 336 | 337 | --- 338 | 339 | Provide the necessary details to create your **Jenkins account.** 340 | 341 | ### Once the plugins installed you will see jenkins url as shown below: 342 | 343 | --- 344 | ![](/Images/jenkins-url.jpg) 345 | 346 | 347 | **Save and Finish to start using Jenkins** 348 | 349 | --- 350 | 351 | ### Configuring Jenkins for CI-CD with Additional Tools 352 | 353 | #### 1. Install Essential Plugins 354 | 355 | 1. Go to Jenkins **Dashboard** > **Manage Jenkins** > **Plugins**. 356 | 357 | 2. Navigate to the **Available** tab and search for these plugins: 358 | 359 | - **Git Plugin**: For integrating Git repositories (pre-installed). 360 | 361 | - **Pipeline Plugin**: For creating declarative or scripted pipelines. 362 | - Pipeline: Stage View 363 | - Pipeline: Declarative Agent API 364 | 365 | - **Terraform Plugin**: For running Terraform commands in Jenkins. 366 | - **HashiCorp Vault**: To pull secrets from Vault (optional, based on your goals). 367 | - **HashiCorp Vault Pipeline** 368 | - **SonarQube Scanner Plugin**: For static code analysis integration. 369 | - **Docker**: To run Docker-related commands within Jenkins. 370 | - **Snyk Security**: For code and dependency scanning. 371 | - **Ansible Plugin**: To automate configuration management. 372 | - **Prometheus**: For Monitoring and Observability 373 | - **OpenTelemetry Agent Host Metrics Monitor Plugin** 374 | - **Slack Notification** : 375 | 376 | 377 | Install plugins as shown below: 378 | 379 | --- 380 | ![](/Images/Jenkins/plugins.jpg) 381 | ![](/Images/Jenkins/plugins-1.jpg) 382 | ![](/Images/slack-plugin.jpg) 383 | 384 | --- 385 | 386 | ### Restarting Jenkins 387 | 388 | After installing plugins or making configuration changes, you may need to restart your Jenkins server. You can do this in one of the following ways: 389 | 390 | 1. **Using the systemctl command** (Linux systems): 391 | ```bash 392 | systemctl restart jenkins 393 | ``` 394 | 2. **Using the Jenkins UI:** 395 | If you're on the plugin installation page, check the *"Restart Jenkins when installation is complete and no jobs are running"* box at the bottom of the page. 396 | Alternatively, navigate to the following URL in your browser to restart Jenkins: 397 | ```bash 398 | http://:8080/restart 399 | ``` 400 | Replace with your Jenkins server's public IP address. 401 | Ensure Jenkins has fully restarted before proceeding with further tasks. 402 | 403 | 404 | ### Troubleshooting: Updating Jenkins IP Address 405 | 406 | If you stop the Jenkins instance and start it again, you may experience slowness when accessing Jenkins or making changes. This happens because the Jenkins IP address changes after restarting the instance. 407 | 408 | To resolve this issue, follow these steps to update the latest IP address in Jenkins: 409 | 410 | 1. Open the Jenkins configuration file: 411 | ```bash 412 | vi /var/lib/jenkins/jenkins.model.JenkinsLocationConfiguration.xml 413 | ``` 414 | 2. Update the `Jenkins URL` field with the new public IP address of the instance. 415 | 416 | 3. Save the changes and restart Jenkins: 417 | ```bash 418 | systemctl restart jenkins 419 | ``` 420 | 421 | 422 | 423 | ## Configure Tools 424 | 425 | ### Install Terraform: 426 | 427 | ```bash 428 | sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo 429 | ``` 430 | ```bash 431 | sudo yum install -y terraform 432 | ``` 433 | ```bash 434 | terraform --version 435 | ``` 436 | 437 | ### Command Output Snapshot 438 | --- 439 | ![](/Images/terraform/succesfull-installation%20.jpg) 440 | 441 | --- 442 | 443 | 444 | ### Install TFScan: 445 | 446 | ```bash 447 | curl -s https://raw.githubusercontent.com/aquasecurity/tfsec/master/scripts/install_linux.sh | bash 448 | ``` 449 | ```bash 450 | tfsec --version 451 | ``` 452 | --- 453 | ![](/Images/Scanners/tfsec-version.jpg) 454 | 455 | --- 456 | ### Install Trivy: 457 | 458 | ```bash 459 | curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh 460 | ``` 461 | 462 | ```bash 463 | sudo mv /root/bin/trivy /usr/local/bin/trivy 464 | ``` 465 | 466 | ### Troubleshooting Trivy Installation 467 | 468 | If you encounter an issue where `trivy` is not found after installation, follow these steps to locate and move it manually: 469 | 470 | ### Issue 471 | You may see the following error when trying to move `trivy`: 472 | ```bash 473 | mv: cannot stat '/root/bin/trivy': No such file or directory 474 | ``` 475 | ### Solution 476 | 477 | ### Find where `trivy` was installed by running: 478 | ```sh 479 | find / -name trivy 2>/dev/null 480 | ``` 481 | This should return a path similar to: 482 | ```sh 483 | /root/DevSecOps-End-to-End-Project/src/bin/trivy 484 | ``` 485 | 486 | ### Move `trivy` to `/usr/local/bin/` for system-wide access: 487 | ```sh 488 | mv /root/DevSecOps-End-to-End-Project/src/bin/trivy /usr/local/bin/trivy 489 | ``` 490 | 491 | ### Verify the installation: 492 | ```sh 493 | trivy --version 494 | ``` 495 | If the installation was successful, this should output the installed Trivy version. 496 | 497 | ### Command Execution Status 498 | --- 499 | ![](/Images/Scanners/trivy-version.jpg) 500 | 501 | --- 502 | 503 | ### Install Snyk CLI: 504 | 505 | ```bash 506 | npm install -g snyk 507 | ``` 508 | ```bash 509 | snyk --version 510 | ``` 511 | 512 | ### Terminal Session Output 513 | --- 514 | ![](/Images/snyk-version.jpg) 515 | 516 | --- 517 | 518 | ### Install Ansible 519 | 520 | ### Install `ansible` using `pip`: 521 | ```sh 522 | yum install pip -y 523 | ``` 524 | ```bash 525 | pip install ansible 526 | ``` 527 | ```bash 528 | ansible --version 529 | ``` 530 | 531 | 532 | ### Execution Log in Terminal 533 | --- 534 | ![](/Images/ansible-version.jpg) 535 | 536 | --- 537 | 538 | 539 | 540 | ### Configuring Global Tools in Jenkins 541 | 542 | 1. **Git**: 543 | - Go to **Manage Jenkins > Global Tool Configuration**. 544 | - Under Git, click **Add Git** and set the path to `/usr/bin/git`. 545 | 546 | 547 | --- 548 | ![](/Images/git-path.jpg) 549 | 550 | --- 551 | Refer to the above screenshot to configure **Terraform & Ansible.** 552 | 553 | **Note**: Ensure that you uncheck `Install automatically.` 554 | 555 | 2. **Terraform**: 556 | - Add Terraform under Terraform installations. 557 | - Ensure the binary is installed at `/usr/bin/`. 558 | 559 | 3. **Ansible**: 560 | - Add Ansible installation and set the path to `/usr/bin/`. 561 | 562 | Click on `Apply & Save` to continue. 563 | 564 | --- 565 | 566 | ### Create Your First Job to Verify Jenkins 567 | 568 | Follow these steps to create a Freestyle Project in Jenkins to verify that Jenkins is properly configured with additional tools: 569 | 570 | 1. **Create a Freestyle Project:** 571 | - Go to the **Jenkins Dashboard** and click on **New Item**. 572 | - Enter a name for your job (e.g. `Verify-Jenkins`) and select Freestyle Project. 573 | 574 | 2. **Configure the Build Steps:** 575 | - Scroll down to the **Build** section and click **Add build step**. 576 | - Select **Execute shell** and add the following commands: 577 | ```bash 578 | echo "Jenkins is configured with additional tools!" 579 | tfsec --version 580 | trivy --version 581 | snyk --version 582 | ``` 583 | 584 | 3. **Save and Build:** 585 | - Click **Save** to create the job. 586 | - Go back to the project dashboard and click **Build Now** to execute the job. 587 | 588 | 4. **Verify the Output:** 589 | - Navigate to the **Console Output** of the build to verify that the commands ran successfully and the versions of `tfsec`, `trivy`, and `snyk` are displayed. 590 | 591 | 592 | 2. Save and build the job. 593 | 594 | 595 | ### Check the console output to verify the installed versions. 596 | 597 | --- 598 | 599 | ![](/Images/version-verification.jpg) 600 | 601 | --- 602 | ## Deploying SonarQube as a Container 603 | 604 | ### Steps to Install and Configure SonarQube: 605 | 606 | 1. Install Docker: 607 | 608 | ```bash 609 | sudo yum install docker -y 610 | ``` 611 | ```bash 612 | sudo systemctl enable docker 613 | sudo systemctl start docker 614 | ``` 615 | 616 | 2. Check Docker Status: 617 | ```bash 618 | sudo systemctl status docker 619 | ``` 620 | ### Terminal View of Executed Commands 621 | 622 | --- 623 | ![](/Images/docker-status.jpg) 624 | 625 | --- 626 | 627 | ### Run the SonarQube Container 628 | 629 | Execute the following command to pull and run the latest SonarQube container in detached mode (`-d`), mapping it to port **9000**: 630 | 631 | ```sh 632 | docker run -d --name sonarcontainer -p 9000:9000 sonarqube:latest 633 | ``` 634 | 635 | - `-d` → Runs the container in detached mode (in the background). 636 | - `--name sonarcontainer` → Assigns a custom name (`sonarcontainer`) to the container for easy management. 637 | - `-p 9000:9000` → Maps port **9000** of the container to port **9000** of the host machine. 638 | - `sonarqube:latest` → Uses the latest available SonarQube image from Docker Hub. 639 | 640 | Verify if the container is running using: 641 | 642 | ```sh 643 | docker ps 644 | ``` 645 | ### Command Execution Status 646 | 647 | --- 648 | 649 | ![](/Images/sonarqube-container.jpg) 650 | 651 | --- 652 | 653 | 654 | ### Sonarqube Successfully Running on Port 9000 655 | 656 | Once the container is running, access the SonarQube web interface: 657 | 658 | - Open a browser and navigate to: 659 | ```bash 660 | http://:9000 661 | ``` 662 | 663 | ### Console Output After Command Execution 664 | 665 | --- 666 | 667 | ![](/Images/Sonar/9.sonar.jpg) 668 | 669 | --- 670 | 671 | ### Default Credentials 672 | - **Username:** `admin` 673 | - **Password:** `admin` 674 | 675 | Upon first login, you will be prompted to change the default password for security. 676 | 677 | Provide a new Password : `Example@12345` (Suggested) 678 | 679 | --- 680 | ![](/Images/Sonar/10.sonar-update.jpg) 681 | 682 | --- 683 | 684 | ### Adding SonarQube Configuration to Jenkins 685 | 1. Go to **Manage Jenkins > System**. 686 | 2. Scroll to **SonarQube Servers** and click **Add SonarQube**. 687 | 3. Enter the following details: 688 | - **Name**: SonarQube server (or any identifier). 689 | - **Server URL**: `http://:9000`. 690 | 691 | --- 692 | 693 | ![](/Images/Sonar/14.sonarserver-add.jpg) 694 | 695 | --- 696 | 697 | **Save the configuration.** 698 | 699 | 700 | ### **Important Note:** 701 | Before proceeding, make sure to securely store the following values, as they will be required later: 702 | - `sonar.projectName` 703 | - `sonar.projectKey` 704 | - `Token` 705 | 706 | ### Create a New Project in SonarQube 707 | 708 | 1. Log in to SonarQube. 709 | 2. Click **Create a local project** and provide the project name (e.g. `Sample E-Commerce Project`). 710 | 3. Branch should be `main` then `Next` 711 | 4. Select **Use the global setting**, then click **Create Project**. 712 | 713 | ### Generate an Authentication Token 714 | 1. Navigate to **My Account > Security**. 715 | 2. Under **Generate Tokens**, enter a token name (e.g. `Sample Project Token`). 716 | 3. Select **Global Analysis** from the dropdown. 717 | 4. Click **Generate** and copy the token (save it securely; it will not be displayed again). 718 | 719 | ### Install Sonar Scanner 720 | 1. Create a directory for Sonar Scanner: 721 | ```bash 722 | mkdir -p /downloads/sonarqube 723 | cd /downloads/sonarqube 724 | ``` 725 | 2. Download the latest Sonar Scanner: 726 | ```bash 727 | wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip 728 | unzip sonar-scanner-cli-5.0.1.3006-linux.zip 729 | ``` 730 | ```bash 731 | sudo mv sonar-scanner-5.0.1.3006-linux /opt/sonar-scanner 732 | ``` 733 | 3. Add Sonar Scanner to the PATH: 734 | ```bash 735 | vi ~/.bashrc 736 | ``` 737 | ```bash 738 | export PATH="/opt/sonar-scanner/bin:$PATH" 739 | ``` 740 | Add the path as shown below: 741 | 742 | --- 743 | 744 | ![](/Images/Sonar/sonar-path.jpg) 745 | 746 | --- 747 | 748 | ```bash 749 | source ~/.bashrc 750 | ``` 751 | Verify the installation: 752 | ```bash 753 | sonar-scanner --version 754 | ``` 755 | ### Execution Log in Terminal 756 | --- 757 | ![](/Images/sonarqube-version.jpg) 758 | 759 | --- 760 | 761 | Ensure `SonarQube Scanner` plugin is installed. 762 | ### Analyze Code with Sonar Scanner 763 | 1. Navigate to the `src` directory. 764 | ```bash 765 | cd src 766 | ``` 767 | 2. Create and edit the `sonar-project.properties` file: 768 | ```bash 769 | vi sonar-project.properties 770 | ``` 771 | Add the following content: 772 | ``` 773 | # Unique project identifier in SonarQube 774 | sonar.projectKey=Sample-E-Commerce-Project 775 | 776 | # Display name of the project 777 | sonar.projectName=Sample E-Commerce Project 778 | 779 | # Directory where source code is located (relative to this file) 780 | sonar.sources=. 781 | 782 | # URL of the SonarQube server 783 | sonar.host.url=http://:9000 784 | 785 | # Authentication token from SonarQube 786 | sonar.login= 787 | ``` 788 | **Important** 789 | Ensure that you **replace Sonarqube server IP & token** before scanning 790 | 791 | 3. Run the Sonar Scanner: 792 | ```bash 793 | /opt/sonar-scanner/bin/sonar-scanner 794 | ``` 795 | 796 | ### You will see below result after running sonar scanner: 797 | 798 | --- 799 | 800 | ![](/Images/Sonar/12.sonar-success.jpg) 801 | 802 | --- 803 | 804 | 1. For debugging issues, use: 805 | ```bash 806 | /opt/sonar-scanner/bin/sonar-scanner -X 807 | ``` 808 | 809 | If you get an error: 810 | - Ensure your SonarQube server IP is configured in Jenkins. 811 | - Verify that your project key and authentication token are correct. 812 | - Make sure you are in the correct path (`/src`). 813 | - Confirm that the `sonar-project.properties` file exists in the `/src` directory. 814 | 815 | ### View Results in SonarQube 816 | 1. Open your browser and navigate to `http://:9000`. 817 | 2. Log in to the SonarQube dashboard. 818 | 3. Locate the project (e.g., `Sample E-Commerce Project`). 819 | 4. View analysis results, including security issues, reliability, maintainability, and code coverage. 820 | 821 | ### The following output will be visible upon successful execution: 822 | 823 | --- 824 | 825 | ![](/Images/Sonar/Sonarqube-passed.jpg) 826 | 827 | --- 828 | 829 | ## Installing HashiCorp Vault for Secure Secrets Management 830 | 831 | HashiCorp Vault is used to securely manage AWS credentials and other sensitive secrets, including: 832 | 833 | - **Nexus Credentials** 834 | - **Docker Hub Credentials** 835 | - **Snyk Token** 836 | - **SonarQube Token** 837 | - **Other Confidential Secrets** 838 | 839 | By integrating Vault, we ensure that secrets are securely stored and dynamically accessed, reducing security risks. 840 | 841 | 1. **Why Vault?** 842 | HashiCorp Vault is used to: 843 | - Securely store and manage sensitive information. 844 | - Dynamically generate AWS credentials for Terraform. 845 | 846 | 2. **Steps for Vault Integration**: 847 | Before proceeding, we need to integrate Vault: 848 | 849 | - **Install Vault**: 850 | ```bash 851 | sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo 852 | sudo yum install -y vault 853 | ``` 854 | 855 | - **Start Vault in Development Mode**: 856 | ```bash 857 | vault server -dev -dev-listen-address="0.0.0.0:8200" 858 | ``` 859 | **Note:** Copy the Root token to login into Hashicorp vault server 860 | - **Run Vault in Background (Optional)**: 861 | ```bash 862 | vault server -dev -dev-listen-address="0.0.0.0:8200" & 863 | ``` 864 | 865 | 3. **Access Vault Server** 866 | 867 | ```bash 868 | http://:8200 869 | ``` 870 | 871 | ### Vault is Up and Running at IP:8200 872 | --- 873 | ![](/Images/vault-login.jpg) 874 | 875 | --- 876 | 877 | Enter the **Root token** to login. 878 | 879 | ## Integrate Vault for Secrets Management 880 | 881 | ### Open a Separate Terminal for Configuration 882 | 883 | 1. Right-click on the tab of your terminal session. 884 | 2. From the context menu, select the option **'Duplicate Session'**. 885 | 3. This will open a new tab with a duplicate of your current terminal session, which you can use to continue the setup process. 886 | 4. After entering into the duplicate terminal, get sudo access and follow the steps below.. 887 | 888 | --- 889 | 890 | ### Step-by-Step Configuration 891 | 892 | 1. **Set Vault's Environment Variables**: 893 | ```bash 894 | export VAULT_ADDR=http://0.0.0.0:8200 895 | ``` 896 | ```bash 897 | export VAULT_TOKEN= 898 | ``` 899 | 2. **Enable the AWS Secrets Engine**: 900 | ```bash 901 | vault secrets enable -path=aws aws 902 | ``` 903 | 3. **Configure AWS Credentials in Vault**: 904 | ```bash 905 | vault write aws/config/root \ 906 | access_key= \ 907 | secret_key= 908 | ``` 909 | 4. Create a Vault Role for AWS Credentials 910 | 911 | ```bash 912 | vault write aws/roles/dev-role \ 913 | credential_type=iam_user \ 914 | policy_document=-< System > Vault Plugin**. 958 | 2. Enter the Vault URL: `http://:8200`. 959 | 3. Click **Apply** and **Save**. 960 | 961 | #### Steps to Create and Configure the Jenkins Job 962 | 1. **Create a New Freestyle Job**: 963 | - Go to **Jenkins Dashboard > New Item**. 964 | - Enter a job name (e.g., `Test-Vault`). 965 | - Select **Freestyle Project** and click **OK**. 966 | 967 | 2. **Add Build Step**: 968 | - Under **Build**, click on **Add Build Step**. 969 | - Select **Execute Shell**. 970 | 971 | 3. **Add the Following Shell Script**: 972 | ```bash 973 | # Export Vault address and token 974 | export VAULT_ADDR=http://:8200 975 | export VAULT_TOKEN= 976 | 977 | echo "Testing Vault Connection..." 978 | # Read AWS credentials from Vault 979 | vault read -format=json aws/creds/dev-role > aws_creds.json 980 | jq -r '.data.access_key' aws_creds.json 981 | jq -r '.data.secret_key' aws_creds.json 982 | ``` 983 | 984 | 4. **Run the Job:** 985 | 986 | - Click Save and then Build Now. 987 | 988 | 5. **Verify the Output:** 989 | 990 | - Check the Console Output to ensure: 991 | - Vault connection is successful. 992 | - The AWS credentials are retrieved and displayed below. 993 | 994 | --- 995 | ![](/Images/vault-job-success.jpg) 996 | 997 | --- 998 | 999 | ### Integrating `Tfsec` to Enhance Terraform Security Scanning 1000 | 1001 | To scan Terraform files for potential security vulnerabilities using `tfsec`, follow these steps: 1002 | 1003 | 1. **Ensure a Terraform File Exists**: 1004 | - Confirm that the required Terraform file (`.tf`) is available in the directory. 1005 | 1006 | 2. **Navigate to the Terraform Directory**: 1007 | ```bash 1008 | cd /root/DevSecOps-End-to-End-Project/terraform 1009 | ``` 1010 | 3. **Run tfsec**: 1011 | - Execute the following command to perform the security scan: 1012 | 1013 | ```bash 1014 | tfsec . 1015 | ``` 1016 | 1. **Analyze the Output**: 1017 | 1018 | - Review the results of the scan for any identified security issues and resolve them as needed. 1019 | 1020 | --- 1021 | ![](/Images/tfsec-ouput.jpg) 1022 | 1023 | --- 1024 | 1025 | 1026 | 1027 | ## Integrating `Trivy` to Enhance Container Image Scanning 1028 | 1029 | ### Install Docker 1030 | If Docker is not already installed, use the following command to install Docker: 1031 | ```bash 1032 | sudo yum install docker -y 1033 | ``` 1034 | Navigate to **Docker** directory 1035 | ```bash 1036 | cd DevSecOps-End-to-End-Project/Docker 1037 | 1038 | ``` 1039 | ### Steps to Integrate Trivy for Image Scanning 1040 | 1041 | 1. **Create the Dockerfile**: 1042 | - The Dockerfile is already available in the `/Docker` directory. Below is an example of the Dockerfile: 1043 | ```dockerfile 1044 | FROM node:16-alpine 1045 | WORKDIR /app 1046 | COPY package.json . 1047 | RUN npm install 1048 | COPY . . 1049 | EXPOSE 3000 1050 | CMD ["npm", "start"] 1051 | ``` 1052 | - Save this file in the root directory of your project. 1053 | 1054 | 2. **Build the Docker Image**: 1055 | - Navigate to your project directory and run: 1056 | ```bash 1057 | docker build -t sample-ecommerce-app . 1058 | ``` 1059 | 1060 | ### What You Can Expect After Running the Command 1061 | --- 1062 | ![](/Images/docker-image-build.jpg) 1063 | 1064 | --- 1065 | 1066 | 3. **Run the Docker Container (Optional for Testing)**: 1067 | - To test the container, run: 1068 | ```bash 1069 | docker run -p 3000:3000 sample-ecommerce-app 1070 | ``` 1071 | - Access the application in your browser at: 1072 | ``` 1073 | http://:3000 1074 | ``` 1075 | 1076 | ![](/Images/1.NodeJs.jpg) 1077 | 1078 | 4. **Scan the Image with Trivy**: 1079 | - Use Trivy to scan the Docker image for vulnerabilities: 1080 | ```bash 1081 | trivy image sample-ecommerce-app 1082 | ``` 1083 | 1084 | 5. **Analyze the Output**: 1085 | - Review the vulnerabilities identified in the scan and address them by updating dependencies or modifying the Dockerfile. 1086 | 1087 | --- 1088 | 1089 | ![](/Images/trivy-succes.jpg) 1090 | --- 1091 | 1092 | 6. **Clean Up**: 1093 | - Stop and remove the running container (if applicable): 1094 | ```bash 1095 | docker stop 1096 | docker rm 1097 | ``` 1098 | 1099 | ### Push Docker Image to a Container Registry 1100 | 1101 | To store and share your Docker image, push it to a container registry like Docker Hub, Amazon ECR, or Azure ACR. 1102 | 1103 | 1. **Log in to Docker Hub**: 1104 | ```bash 1105 | docker login -u -p 1106 | ``` 1107 | 1108 | 2. **Tag the Docker Image**: 1109 | ```bash 1110 | docker tag sample-ecommerce-app /sample-ecommerce-app:nodejs 1111 | ``` 1112 | 1113 | 3. **Push the Image to the Registry**: 1114 | ```bash 1115 | docker push /sample-ecommerce-app:nodejs 1116 | ``` 1117 | 4. Verify on Docker Hub. 1118 | 1119 | ### After running the steps, the output will appear as follows: 1120 | --- 1121 | 1122 | ![](/Images/dockerhub-success.jpg) 1123 | 1124 | --- 1125 | 1126 | 1127 | ## Deploying Nexus Repository as a Docker Container 1128 | 1129 | ### Run the Nexus Container 1130 | To deploy the Nexus Repository as a container, run the following command: 1131 | ```bash 1132 | docker run -d -p 8081:8081 --name nexus sonatype/nexus3 1133 | ``` 1134 | 1135 | ### Access Nexus 1136 | 1. Open your browser and navigate to: 1137 | ``` 1138 | http://:8081 1139 | ``` 1140 | --- 1141 | ![](/Images/nexus-launch.jpg) 1142 | 1143 | --- 1144 | 2. Retrieve the Admin Password: 1145 | - Run the following command to get the admin password: 1146 | ```bash 1147 | docker exec -it nexus cat /nexus-data/admin.password 1148 | ``` 1149 | **Click on the sign icon in the top-right corner.** 1150 | 3. The default credentials are: 1151 | - **Username**: `admin` 1152 | - **Password**: Retrived Password. 1153 | --- 1154 | 1155 | ![](/Images/nexus-credentials.jpg) 1156 | 1157 | --- 1158 | 1159 | 4. Update your password after the first login as shown below 1160 | --- 1161 | ![](/Images/nexus-credentials-update.jpg) 1162 | --- 1163 | 1. Select: Enable anonymous access → Click Next → Finish the setup. 1164 | 1165 | ### Configure Nexus 1166 | 1167 | #### Create a Docker Repository as shown below 1168 | 1169 | ![](/Images/nexus-config.jpg) 1170 | 1171 | 1. Navigate to Nexus Repositories: 1172 | - Click on the "Settings" (gear icon) → "Repositories". 1173 | 1174 | 2. Create a New Repository: 1175 | - Click on "Create repository". 1176 | - Choose **"docker (hosted)"** for pushing Docker images. 1177 | 1178 | 3. Configure the Repository: 1179 | - **Name**: Enter a name for the repository (e.g., `docker-hosted`). 1180 | - Allow anonymous Docker pull: Enable this option if needed. 1181 | 1182 | 4. Click on `create repository`. 1183 | 1184 | 1185 | ## Securely Managing Credentials with HashiCorp Vault 1186 | 1187 | ### Storing and Accessing Credentials in Vault 1188 | 1189 | ### Storing Nexus Credentials 1190 | 1191 | #### 1. Enable the KV Secrets Engine 1192 | Ensure the KV secrets engine is enabled in Vault to securely store credentials. 1193 | ```bash 1194 | vault secrets enable -path=nexus kv 1195 | ``` 1196 | #### 2. Store Nexus Credentials 1197 | Use the `vault kv put` command to securely store your Nexus credentials and repository URL or token: 1198 | ```bash 1199 | vault kv put nexus/credentials \ 1200 | username="your-nexus-username" \ 1201 | password="your-nexus-password" \ 1202 | repo_url=https://nexus.example.com 1203 | ``` 1204 | Replace `https://nexus.example.com` with your Nexus repository URL. 1205 | 1206 | #### How to Find Your Nexus Repository URL 1207 | 1208 | - Log in to your Nexus Repository. 1209 | - Navigate to Nexus Repositories: 1210 | - Click on the "Settings" (gear icon) → "Repositories". 1211 | - Identify the repository that you previously created, click on it. 1212 | - Copy the repository URL displayed under the repository details as shown below. 1213 | --- 1214 | ![](/Images/nexus-url.jpg) 1215 | 1216 | --- 1217 | 1218 | #### 3. Retrieve Nexus Credentials 1219 | To fetch the stored credentials: 1220 | - Retrieve all stored credentials: 1221 | ```bash 1222 | vault kv get nexus/credentials 1223 | ``` 1224 | 1225 | --- 1226 | 1227 | ### Storing Docker Credentials: 1228 | ```bash 1229 | vault kv put secret/docker username="" password="" 1230 | ``` 1231 | 1232 | #### Retrieve Docker Credentials: 1233 | - Fetch the username: 1234 | ```bash 1235 | vault kv get -field=username secret/docker 1236 | ``` 1237 | - Fetch the password: 1238 | ```bash 1239 | vault kv get -field=password secret/docker 1240 | ``` 1241 | 1242 | --- 1243 | 1244 | ### Storing Snyk Token 1245 | 1246 | ### 1. Sign In to Snyk 1247 | - Go to the [Snyk login page](https://snyk.io/). 1248 | - Log in using your preferred method (e.g., email/password, GitHub, GitLab, or SSO). 1249 | 1250 | ### 2. Navigate to Your API Token 1251 | - Click on your Organization bottom-left corner. 1252 | - Select **Account Settings** from the dropdown menu. 1253 | - Locate Auth token and click on `click to show` to view token. 1254 | - Below is the screenshot for your reference 1255 | --- 1256 | ![](/Images/snyk-token.jpg) 1257 | 1258 | --- 1259 | 1260 | ### 3. Enable the KV Secrets Engine (if not already enabled) 1261 | ```bash 1262 | vault secrets enable -path=snyk kv 1263 | ``` 1264 | - `-path=snyk`: Specifies a custom path for storing Snyk-related secrets. You can customize this path as needed. 1265 | 1266 | ### 4. Store the Snyk Token 1267 | ```bash 1268 | vault kv put snyk/token api_token="your-snyk-token" 1269 | ``` 1270 | Replace `your-snyk-token` with your actual Snyk token. 1271 | 1272 | ### 5. Retrieve the Snyk Token 1273 | To fetch the token programmatically or manually: 1274 | ```bash 1275 | vault kv get -field=api_token snyk/token 1276 | ``` 1277 | The `-field=api_token` flag extracts only the token value. 1278 | 1279 | --- 1280 | 1281 | ## Monitoring with Prometheus and Grafana 1282 | 1283 | ### Add Prometheus to Node.js Application 1284 | 1. Install Prometheus client: 1285 | ```bash 1286 | npm install prom-client 1287 | ``` 1288 | 2. Expose metrics in `server.js`. (included expose metrics in server.js) 1289 | 1290 | #### Next Steps 1291 | 1. Test this updated `server.js`: 1292 | ```bash 1293 | node server.js 1294 | ``` 1295 | **To Run in the Background:** 1296 | This allows you to keep the process running without needing to open duplicate terminals. 1297 | 1298 | ```bash 1299 | node server.js & 1300 | ``` 1301 | 1302 | 1303 | Access **Prometheus metrics** at: `http://:3000/metrics` to ensure it is working as expected. 1304 | 1305 | ### You will see the metrics once you access the URL: 1306 | 1307 | --- 1308 | 1309 | ![](/Images/metrics.jpg) 1310 | 1311 | --- 1312 | 1313 | ### Open a Separate Terminal for Prometheus Setup 1314 | 1315 | **Important** : Jump to **Install and Configure Prometheus** if you run node js in Background 1316 | 1317 | 1. **Right-click** on the tab of your terminal session. 1318 | 2. From the context menu, select the option **'Duplicate Session'**. 1319 | 3. This will open a new tab with a duplicate of your current terminal session, which you can use to continue the setup process. 1320 | 4. After entering into the duplicate terminal, get sudo access and navigate to: 1321 | ```bash 1322 | cd DevSecOps-End-to-End-Project/src 1323 | ``` 1324 | 1325 | 1326 | 1327 | ### Install and Configure Prometheus 1328 | 1. Download and run Prometheus: 1329 | ```bash 1330 | wget https://github.com/prometheus/prometheus/releases/download/v2.47.0/prometheus-2.47.0.linux-amd64.tar.gz 1331 | ``` 1332 | ```bash 1333 | tar -xvzf prometheus-2.47.0.linux-amd64.tar.gz 1334 | ``` 1335 | ```bash 1336 | cd prometheus-2.47.0.linux-amd64 1337 | ``` 1338 | 1339 | 1340 | ### Configure Prometheus 1341 | 1342 | 1. **Find the `prometheus.yml` File** 1343 | Ensure the `prometheus.yml` configuration file exists in the current directory 1344 | 1345 | 2. **Verify the file** 1346 | ```bash 1347 | ls 1348 | ``` 1349 | 2. **Edit the File** 1350 | ```bash 1351 | vi prometheus.yml 1352 | ``` 1353 | 1354 | 1. Locate the `scrape_configs:` section. 1355 | 2. Replace the following in your `prometheus.yml` file: 1356 | - **Job Name**: Change it to `"nodejs-app"`. 1357 | - **Host**: Replace `localhost` with your public IP address. 1358 | - **Port**: Update the port to `3000`. 1359 | 1360 | Here’s an example of the updated configuration: 1361 | ```yaml 1362 | scrape_configs: 1363 | # The job name is added as a label `job=` to any timeseries scraped from this config. 1364 | - job_name: "node-js-app" 1365 | 1366 | # metrics_path defaults to '/metrics' 1367 | # scheme defaults to 'http'. 1368 | 1369 | static_configs: 1370 | - targets: [":3000"] # Replace with your Public IP 1371 | ``` 1372 | Save the file in the same directory as Prometheus. 1373 | 1374 | #### Run Prometheus 1375 | 1376 | - To start the Prometheus server, use the following command: 1377 | 1378 | ```bash 1379 | ./prometheus --config.file=prometheus.yml 1380 | ``` 1381 | **To Run in the Background:** 1382 | This allows you to keep the process running without needing to open duplicate terminals. 1383 | 1384 | ```bash 1385 | ./prometheus --config.file=prometheus.yml & 1386 | ``` 1387 | 1388 | - Open the Prometheus server in your browser. 1389 | ```bash 1390 | http://Public-ip:9090/ 1391 | ``` 1392 | ### Prometheus Successfully Running on Port 9090 1393 | --- 1394 | ![](/Images/prometheus-dashboard.jpg) 1395 | 1396 | --- 1397 | 1398 | - Navigate to the Status tab. 1399 | 1400 | - Choose Targets from the dropdown. 1401 | 1402 | 1403 | ### Below is the result you can expect: 1404 | 1405 | --- 1406 | 1407 | ![](/Images/prometheus.jpg) 1408 | 1409 | --- 1410 | 1411 | ### Open a Separate Terminal for Grafana Setup 1412 | 1413 | **Important** : Jump to **Install and Configure Grafana** if you run `Prometheus` in Background 1414 | 1415 | 1. **Right-click** on the tab of your terminal session. 1416 | 2. From the context menu, select the option **'Duplicate Session'**. 1417 | 3. This will open a new tab with a duplicate of your current terminal session, which you can use to continue the setup process. 1418 | 4. After entering into the duplicate terminal, get sudo access and navigate to: 1419 | ```bash 1420 | cd DevSecOps-End-to-End-Project/src 1421 | ``` 1422 | 1423 | ### Install and Configure Grafana 1424 | 1. Download and run Grafana: 1425 | ```bash 1426 | wget https://dl.grafana.com/oss/release/grafana-10.0.0.linux-amd64.tar.gz 1427 | ``` 1428 | ```bash 1429 | tar -xvzf grafana-10.0.0.linux-amd64.tar.gz 1430 | ``` 1431 | ```bash 1432 | cd grafana-10.0.0/bin 1433 | ``` 1434 | Run Grafana 1435 | 1436 | ```bash 1437 | ./grafana-server 1438 | ``` 1439 | 1440 | ### Resolve Port Conflict with Grafana 1441 | 1442 | You may encounter an **error** because Grafana tries to access port 3000, which is **already occupied** by Node.js. To resolve this, we need to change the Grafana port to 3001. 1443 | 1444 | #### Steps to Change the Grafana Port 1445 | 1446 | 1.Find the `defaults.ini` file by running the following command: 1447 | ```bash 1448 | find / -name defaults.ini 2>/dev/null 1449 | ``` 1450 | 1451 | 2.Navigate to the `conf` directory: 1452 | ```bash 1453 | cd ../conf 1454 | ``` 1455 | 1456 | 3.Edit the `defaults.ini` file: 1457 | ```bash 1458 | vi defaults.ini 1459 | ``` 1460 | 4.Add the following line to set the `Grafana port` to 3001 as shown below: 1461 | ```bash 1462 | http_port = 3001 1463 | ``` 1464 | --- 1465 | 1466 | ![](/Images/port-change.jpg) 1467 | 1468 | --- 1469 | 1470 | #### Restart Grafana 1471 | Now, navigate back to the Grafana execution folder: 1472 | 1473 | ```bash 1474 | cd /root/DevSecOps-End-to-End-Project/src/prometheus-2.47.0.linux-amd64/grafana-10.0.0/bin 1475 | ``` 1476 | Run Grafana again: 1477 | ```bash 1478 | ./grafana-server 1479 | ``` 1480 | **To Run in the Background:** 1481 | This allows you to keep the process running without needing to open duplicate terminals. 1482 | ```bash 1483 | ./grafana-server & 1484 | ``` 1485 | **Access Grafana:** 1486 | ```bash 1487 | http://:3001. 1488 | ``` 1489 | 1490 | ### Grafana Running and Accessible on the Browser 1491 | 1492 | --- 1493 | ![](/Images/grafana-1.jpg) 1494 | 1495 | --- 1496 | 1497 | #### Login with Default Credentials 1498 | 1499 | 1. Use the following default credentials to log in: 1500 | - **Username:** `admin` 1501 | - **Password:** `admin` 1502 | 1503 | After initial login you will be prompted to change the password upon your first login. Follow the instructions to set a strong, secure password. 1504 | 1505 | 1506 | 1507 | ### Once you login you will see Grafana Dashboard as shown below: 1508 | --- 1509 | 1510 | ![](/Images/grafana-dashboard.jpg) 1511 | 1512 | --- 1513 | 1514 | #### Configure Prometheus as a Data Source 1515 | Add Prometheus as a data source. 1516 | - In Grafana Home page. 1517 | - Click on **data source.** 1518 | 1519 | ### The following page will appear: 1520 | 1521 | --- 1522 | ![](/Images/grafana-data-source.jpg) 1523 | 1524 | --- 1525 | Select **`Prometheus`** from the list. 1526 | 1527 | Enter Prometheus URL as shown below 1528 | 1529 | --- 1530 | ![](/Images/grafana-prometheus.jpg) 1531 | 1532 | --- 1533 | Click on **Save** to continue. 1534 | 1535 | #### Import a Pre-Built Dashboard 1536 | Go to Home Page > toggle menu > dashboards > new> Import in Grafana. 1537 | 1538 | 1539 | --- 1540 | ![](/Images/grafana-nodejs-id.jpg) 1541 | 1542 | --- 1543 | 1544 | #### Load the Node.js Dashboard 1545 | 1546 | 1. **Enter the Dashboard ID**: 1547 | - Use the Dashboard ID for Node.js: **`11159`**. 1548 | 1549 | 2. Click **Load** to fetch the dashboard configuration. 1550 | 1551 | 3. In the next step, select **`Prometheus`** as the data source to proceed. 1552 | 1553 | 1554 | #### The interface will appear as follows: 1555 | 1556 | --- 1557 | ![](/Images/grafana-load-nodejs.jpg) 1558 | 1559 | --- 1560 | 1561 | click on **import.** 1562 | 1563 | ### Here is the NodeJS Application Dashboard result after the process completes 1564 | 1565 | --- 1566 | ![](/Images/Grafana-App-Dashboard.jpg) 1567 | 1568 | --- 1569 | 1570 | ## From Scans to Dashboards: Unlocking Security Insights with Trivy, TFsec, Prometheus, and Grafana 1571 | 1572 | Trivy and TFsec are powerful security scanning tools for containers and Infrastructure as Code (IaC), but they lack a built-in graphical interface for visualizing vulnerabilities. This project bridges that gap by integrating Trivy and TFsec with Prometheus and Grafana, transforming raw security scan data into insightful, real-time dashboards for better monitoring and decision-making. 🚀 1573 | 1574 | ## Trivy Integration 1575 | 1576 | ### Run Trivy and Generate JSON Output 1577 | Navigate to Docker directory: 1578 | ```bash 1579 | cd DevSecOps-End-to-End-Project/Docker 1580 | ``` 1581 | ### Scan Docker Image with Trivy 1582 | ```sh 1583 | trivy image --format json --severity HIGH,CRITICAL > trivy-results.json 1584 | ``` 1585 | 1586 | After running this command, a `trivy-results.json` file will be created. 1587 | 1588 | ### Generate Prometheus Metrics from Trivy Results 1589 | Create a file `generate-trivy-metrics.js` and add the following content: 1590 | 1591 | ```bash 1592 | vi generate-trivy-metrics.js 1593 | ``` 1594 | ```javascript 1595 | const fs = require('fs'); 1596 | 1597 | try { 1598 | console.log('Reading Trivy results...'); 1599 | const trivyResults = JSON.parse(fs.readFileSync('trivy-results.json', 'utf8')); 1600 | 1601 | console.log('Generating Prometheus metrics...'); 1602 | const metrics = []; 1603 | trivyResults.Results.forEach((result) => { 1604 | result.Vulnerabilities.forEach((vuln) => { 1605 | metrics.push(`# HELP trivy_vulnerabilities Trivy vulnerability scan results`); 1606 | metrics.push(`# TYPE trivy_vulnerabilities gauge`); 1607 | metrics.push(`trivy_vulnerabilities{image="${result.Target}",severity="${vuln.Severity}",id="${vuln.VulnerabilityID}"} 1`); 1608 | }); 1609 | }); 1610 | 1611 | console.log('Writing metrics to trivy-metrics.prom...'); 1612 | fs.writeFileSync('trivy-metrics.prom', metrics.join('\n')); 1613 | console.log('Metrics file trivy-metrics.prom created successfully.'); 1614 | } catch (error) { 1615 | console.error('Error:', error.message); 1616 | } 1617 | ``` 1618 | **Run the script:** 1619 | ```sh 1620 | node generate-trivy-metrics.js 1621 | ``` 1622 | A `trivy-metrics.prom` file will be created. 1623 | 1624 | **Move the file to the `metrics` directory:** 1625 | ```sh 1626 | mv trivy-metrics.prom metrics 1627 | ``` 1628 | 1629 | Start a simple HTTP server to expose metrics on **port 8085**: 1630 | ```sh 1631 | python3 -m http.server 8085 1632 | ``` 1633 | Access `Trivy` metrics: 1634 | 1635 | ```bash 1636 | http://Public-ip:8085/ 1637 | ``` 1638 | ### Execution Log in Terminal 1639 | --- 1640 | ![](/Images/trivy-metrics-logs.jpg) 1641 | 1642 | --- 1643 | ### Trivy Metrics is Now Live at IP:8085 1644 | 1645 | --- 1646 | ![](/Images/trivy-metrics.jpg) 1647 | 1648 | --- 1649 | ### Open a Separate Terminal 1650 | 1651 | 1. **Right-click** on the tab of your terminal session. 1652 | 2. From the context menu, select the option **'Duplicate Session'**. 1653 | 3. This will open a new tab with a duplicate of your current terminal session, which you can use to continue the setup process. 1654 | 4. After entering into the duplicate terminal, get sudo access and navigate to: 1655 | ```bash 1656 | cd /root/DevSecOps-End-to-End-Project/src/prometheus-2.47.0.linux-amd64 1657 | ``` 1658 | ### Add Trivy to Prometheus Configuration 1659 | ```bash 1660 | vi prometheus.yml 1661 | ``` 1662 | ```yaml 1663 | - job_name: "trivy" 1664 | static_configs: 1665 | - targets: [":8085"] 1666 | ``` 1667 | **Below is the screenshot for your reference:** 1668 | 1669 | --- 1670 | ![](/Images/trivy-config.jpg) 1671 | 1672 | --- 1673 | 1674 | ### Reload Prometheus to Apply Changes 1675 | 1676 | Prometheus is already running in the background, follow these steps to reload it with the updated configuration: 1677 | 1678 | #### Steps to Reload Prometheus 1679 | 1680 | 1. **Find the Process ID (PID):** 1681 | Use the following command to locate the PID of the Prometheus process: 1682 | ```bash 1683 | ps aux | grep prometheus 1684 | ``` 1685 | 2. **Stop the Current Process:** Terminate the Prometheus process using the PID from the previous step: 1686 | 1687 | ```bash 1688 | kill 1689 | ``` 1690 | Replace with the actual Process ID. 1691 | 3. **Restart Prometheus in the Background:** Start Prometheus with the updated configuration in the background: 1692 | ```bash 1693 | ./prometheus --config.file=prometheus.yml & 1694 | ``` 1695 | ### Prometheus is successfully scraping metrics from Trivy 1696 | --- 1697 | ![](/Images/trivy-prometheus.jpg) 1698 | 1699 | --- 1700 | 1701 | The above screenshot confirms that Prometheus is successfully scraping metrics from Trivy. 1702 | 1703 | ### Visualize Trivy Metrics in Grafana 1704 | 1705 | Follow these steps to visualize Trivy metrics in Grafana: 1706 | 1707 | #### 1. Open Grafana 1708 | Access Grafana in your browser: 1709 | ```bash 1710 | http://:3001 1711 | ``` 1712 | 1713 | #### 2. Create a New Dashboard 1714 | - Navigate to the **Grafana Home Page**. 1715 | - Click on **Create your first Dashboard**. 1716 | 1717 | ### You will see the following page: 1718 | 1719 | --- 1720 | ![](/Images/grafana-prebuild.jpg) 1721 | 1722 | --- 1723 | 1724 | #### 3. Add a Visualization 1725 | Click on **Add visualization**, and you will be redirected to the following page: 1726 | 1727 | --- 1728 | ![](/Images/grafana-prometheus-trivy.jpg) 1729 | --- 1730 | Select **Prometheus** as the data source. 1731 | 1732 | #### 4. Run a Query 1733 | - Enter the PromQL query `trivy_vulnerabilities` under the metrics field. 1734 | - Click on **Run Query**. 1735 | - Choose a visualization type, such as **Table**, **Gauge**, or **Time Series**. 1736 | 1737 | #### Example: 1738 | 1739 | --- 1740 | ![](/Images/grafana-trivy-query.jpg) 1741 | 1742 | --- 1743 | 1744 | #### 5. View Trivy Vulnerabilities 1745 | 1746 | The dashboard will display the number of vulnerabilities: 1747 | 1748 | --- 1749 | ![](/Images/trivy-vulnerabilities.jpg) 1750 | 1751 | --- 1752 | 1753 | #### 6. Save the Dashboard 1754 | - Once you are satisfied with the visualization, save the dashboard for future use. 1755 | 1756 | --- 1757 | 1758 | #### Verify Trivy Metrics Manually 1759 | 1760 | To ensure the metrics are accurate, you can verify them manually by scanning an image directly with Trivy: 1761 | 1762 | 1. Run the following command: 1763 | ```bash 1764 | trivy image 1765 | ``` 1766 | 1767 | 2. The output will display the same number of vulnerabilities as seen in Grafana: 1768 | 1769 | --- 1770 | ![](/Images/trivy-succes.jpg) 1771 | --- 1772 | --- 1773 | 1774 | ## TFsec Integration 1775 | 1776 | ### Run TFsec and Generate JSON Output 1777 | Navigate to **terraform** directory: 1778 | ```bash 1779 | cd /root/DevSecOps-End-to-End-Project/terraform 1780 | ``` 1781 | ```bash 1782 | tfsec . --format=json > tfsec-results.json 1783 | ``` 1784 | After running this command, a tfsec-results.json file will be created. 1785 | ### Generate Prometheus Metrics from TFsec Results 1786 | Create a file `generate-tfsec-metrics.js` and add the following content: 1787 | 1788 | ```bash 1789 | vi generate-tfsec-metrics.js 1790 | ``` 1791 | 1792 | ```javascript 1793 | const fs = require('fs'); 1794 | 1795 | console.log("Reading TFsec results..."); 1796 | const tfsecResults = JSON.parse(fs.readFileSync('tfsec-results.json', 'utf8')); 1797 | 1798 | console.log("Generating Prometheus metrics..."); 1799 | let metrics = "# HELP tfsec_vulnerabilities TFsec vulnerability scan results\n"; 1800 | metrics += "# TYPE tfsec_vulnerabilities gauge\n"; 1801 | 1802 | tfsecResults.results.forEach(result => { 1803 | metrics += `tfsec_vulnerabilities{severity="${result.severity}",rule_id="${result.rule_id}",description="${result.description.replace(/"/g, '\\"')}"} 1\n`; 1804 | }); 1805 | 1806 | console.log("Writing metrics to tfsec-metrics.prom..."); 1807 | fs.writeFileSync('tfsec-metrics.prom', metrics); 1808 | 1809 | console.log("Metrics file tfsec-metrics.prom created successfully."); 1810 | ``` 1811 | **Run the script:** 1812 | ```sh 1813 | node generate-tfsec-metrics.js 1814 | ``` 1815 | A `tfsec-metrics.prom` file will be created. 1816 | 1817 | **Move the file to the `metrics` directory:** 1818 | ```sh 1819 | mv tfsec-metrics.prom metrics 1820 | ``` 1821 | 1822 | Start a simple HTTP server to expose metrics on **port 8086**: 1823 | ```sh 1824 | python3 -m http.server 8086 & 1825 | ``` 1826 | ### Execution Log in Terminal 1827 | 1828 | --- 1829 | ![](/Images/tfsec-metrics-logs.jpg) 1830 | 1831 | --- 1832 | 1833 | ### Tfsec Metrics is Now Live at IP:8086 1834 | --- 1835 | ![](/Images/tf-metrics.jpg) 1836 | 1837 | --- 1838 | 1839 | ### Open a Separate Terminal 1840 | 1841 | 1. **Right-click** on the tab of your terminal session. 1842 | 2. From the context menu, select the option **'Duplicate Session'**. 1843 | 3. This will open a new tab with a duplicate of your current terminal session, which you can use to continue the setup process. 1844 | 4. After entering into the duplicate terminal, get sudo access and navigate to: 1845 | ```bash 1846 | cd /root/DevSecOps-End-to-End-Project/src/prometheus-2.47.0.linux-amd64 1847 | ``` 1848 | 1849 | ### Add TFsec to Prometheus Configuration 1850 | ```bash 1851 | vi prometheus.yml 1852 | ``` 1853 | 1854 | ```yaml 1855 | - job_name: "tfsec" 1856 | static_configs: 1857 | - targets: [":8086"] 1858 | ``` 1859 | **Below is the screenshot for your reference:** 1860 | 1861 | --- 1862 | ![](/Images/tfsec-config.jpg) 1863 | 1864 | --- 1865 | 1866 | ### Reload Prometheus to Apply Changes 1867 | 1868 | Prometheus is already running in the background, follow these steps to reload it with the updated configuration: 1869 | 1870 | #### Steps to Reload Prometheus 1871 | 1872 | 1. **Find the Process ID (PID):** 1873 | Use the following command to locate the PID of the Prometheus process: 1874 | ```bash 1875 | ps aux | grep prometheus 1876 | ``` 1877 | 2. **Stop the Current Process:** Terminate the Prometheus process using the PID from the previous step: 1878 | 1879 | ```bash 1880 | kill 1881 | ``` 1882 | Replace with the actual Process ID. 1883 | 3. **Restart Prometheus in the Background:** Start Prometheus with the updated configuration in the background: 1884 | ```bash 1885 | ./prometheus --config.file=prometheus.yml & 1886 | ``` 1887 | 1888 | ### Prometheus is successfully scraping metrics from Tfsec 1889 | --- 1890 | ![](/Images/tfsec-up.jpg) 1891 | 1892 | --- 1893 | The above screenshot confirms that Prometheus is successfully scraping metrics from Tfsec. 1894 | 1895 | ### Visualize Tfsec Metrics in Grafana 1896 | 1897 | Follow these steps to visualize Tfsec metrics in Grafana: 1898 | 1899 | #### 1. Open Grafana 1900 | Access Grafana in your browser: 1901 | ```bash 1902 | http://:3001 1903 | ``` 1904 | 1905 | #### 2. Create a New Dashboard 1906 | - Navigate to the **Grafana Home Page**. 1907 | - Click on **Create your first Dashboard**. 1908 | 1909 | ### You will see the following page: 1910 | 1911 | --- 1912 | ![](/Images/grafana-prebuild.jpg) 1913 | 1914 | --- 1915 | 1916 | #### 3. Add a Visualization 1917 | Click on **Add visualization**, and you will be redirected to the following page: 1918 | 1919 | --- 1920 | ![](/Images/grafana-prometheus-trivy.jpg) 1921 | --- 1922 | Select **Prometheus** as the data source. 1923 | 1924 | #### 4. Run a Query 1925 | - Enter the PromQL query `tfsec_vulnerabilities` under the metrics field. 1926 | - Click on **Run Query**. 1927 | - Choose a visualization type, such as **Table**, **Gauge**, or **Time Series**. 1928 | 1929 | #### Example: 1930 | 1931 | --- 1932 | ![](/Images/tfsec-query.jpg) 1933 | 1934 | --- 1935 | 1936 | #### 5. View Tfsec Vulnerabilities 1937 | 1938 | The dashboard will display the number of vulnerabilities: 1939 | 1940 | --- 1941 | ![](/Images/tfsec_vulnerabilities.jpg) 1942 | 1943 | --- 1944 | 1945 | > **Note:** Previously, when TFSec was run, no vulnerabilities were detected, and the scan results were clear. To demonstrate the Grafana dashboard functionality, I intentionally made changes to the **main.tf** file to introduce vulnerabilities. 1946 | 1947 | 1948 | 1949 | 1950 | #### 6. Save the Dashboard 1951 | - Once you are satisfied with the visualization, save the dashboard for future use. 1952 | 1953 | --- 1954 | 1955 | #### Verify Tfsec Metrics Manually 1956 | 1957 | To ensure the metrics are accurate, you can verify them manually by scanning tf files directly with tfsec: 1958 | 1959 | 1. Run the following command: 1960 | ```bash 1961 | tfsec . 1962 | ``` 1963 | 1964 | 2. The output will display the same number of vulnerabilities as seen in Grafana: 1965 | 1966 | --- 1967 | ![](/Images/tfsec-manual.jpg) 1968 | 1969 | --- 1970 | 1971 | ## OpenTelemetry Setup and Configuration 1972 | Since we have already installed the OpenTelemetry-related dependencies and updated the `collectorUrl` in `server.js` earlier, let's proceed with downloading the OpenTelemetry Collector. 1973 | 1974 | --- 1975 | ![](/Images/otel-logo.png) 1976 | 1977 | --- 1978 | 1979 | ### Download and Set Up OpenTelemetry Collector 1980 | The OpenTelemetry Collector processes and exports telemetry data from the application to a desired backend. 1981 | 1982 | #### **Download the Collector** 1983 | ```bash 1984 | wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.83.0/otelcol-contrib_0.83.0_linux_amd64.tar.gz 1985 | ``` 1986 | 1987 | 1988 | #### **Extract the File** 1989 | ```bash 1990 | tar -xvf otelcol-contrib_0.83.0_linux_amd64.tar.gz 1991 | ``` 1992 | 1993 | #### Move the Binary to a System-Wide Location 1994 | ```bash 1995 | sudo mv otelcol-contrib /usr/local/bin/otelcol 1996 | ``` 1997 | - Why: Places the binary in a directory included in your system’s PATH, so you can run it from anywhere. 1998 | - Result: The Collector is installed and ready to use. 1999 | 2000 | #### Verify Installation 2001 | ```bash 2002 | otelcol --version 2003 | ``` 2004 | 2005 | ![](/Images/otel-version.jpg) 2006 | - Why: Confirms that the Collector is installed correctly. 2007 | - Result: Displays the version of the Collector. 2008 | 2009 | --- 2010 | 2011 | ### Run the OpenTelemetry Collector 2012 | Ensure the `otel-collector-config.yaml` file is present in your directory. Run the Collector with the configuration file. 2013 | ```bash 2014 | otelcol --config otel-collector-config.yaml 2015 | ``` 2016 | 2017 | ![](/Images/otel-success.jpg) 2018 | 2019 | 2020 | Check the Collector logs to confirm traces are being received: 2021 | ``` 2022 | INFO TracesExporter {"kind": "exporter", "data_type": "traces", "resource spans": 1, "spans": 1} 2023 | ``` 2024 | ### Metrics Endpoint 2025 | 2026 | The OpenTelemetry Collector exposes its internal metrics at the /metrics endpoint. These metrics are in Prometheus format and provide insights into the Collector's performance and health. 2027 | 2028 | Access the metrics at: 2029 | ```bash 2030 | http://your-public-ip:8888/metrics 2031 | ``` 2032 | --- 2033 | ![](/Images/otel-metrics.jpg) 2034 | 2035 | --- 2036 | 2037 | ### 8. Enhance Tracing in the Application (*This step is already included in server.js*) 2038 | Add custom spans to improve the observability of specific routes. 2039 | 2040 | #### Edit `server.js` to Add Custom Spans** 2041 | ```bash 2042 | vi /root/DevSecOps-End-to-End-Project/src/server.js 2043 | ``` 2044 | Add the following code to create a custom span for the `/custom` route: 2045 | ```javascript 2046 | app.get('/custom', (req, res) => { 2047 | const span = tracer.startSpan('Custom Route Span'); 2048 | res.send('This is a custom route'); 2049 | span.end(); 2050 | }); 2051 | ``` 2052 | - Why: Custom spans provide detailed observability for specific operations. 2053 | - Result: Requests to `/custom` will generate a new span named `Custom Route Span`. 2054 | 2055 | #### Restart the Application 2056 | ```bash 2057 | node server.js 2058 | ``` 2059 | - Why: Applies the changes to the server. 2060 | - Result: The application restarts with the new custom span functionality. 2061 | 2062 | #### Test the Custom Route 2063 | Visit the custom route in your browser or using `curl`: 2064 | ```bash 2065 | http://:3000/custom 2066 | ``` 2067 | --- 2068 | 2069 | ![](/Images/otel-custom-metrics.jpg) 2070 | 2071 | --- 2072 | - Why: Generates traffic to test the new custom span. 2073 | - Result: A span is created for the `/custom` route and sent to the Collector. 2074 | 2075 | --- 2076 | 2077 | ## Configure Prometheus to Scrape OpenTelemetry Metrics 2078 | 2079 | ```bash 2080 | vi prometheus.yml 2081 | ``` 2082 | 2083 | ```yaml 2084 | - job_name: 'otel-collector' 2085 | scrape_interval: 5s 2086 | static_configs: 2087 | - targets: ["your-public-ip:8888"] 2088 | ``` 2089 | *(Replace your-public-ip with your actual server IP)* 2090 | 2091 | **Below is the screenshot for your reference:** 2092 | 2093 | --- 2094 | ![](/Images/otel-config.jpg) 2095 | 2096 | --- 2097 | 2098 | ### Reload Prometheus to Apply Changes 2099 | 2100 | Prometheus is already running in the background, follow these steps to reload it with the updated configuration: 2101 | 2102 | #### Steps to Reload Prometheus 2103 | 2104 | 1. **Find the Process ID (PID):** 2105 | Use the following command to locate the PID of the Prometheus process: 2106 | ```bash 2107 | ps aux | grep prometheus 2108 | ``` 2109 | 2. **Stop the Current Process:** Terminate the Prometheus process using the PID from the previous step: 2110 | 2111 | ```bash 2112 | kill 2113 | ``` 2114 | Replace with the actual Process ID. 2115 | 3. **Restart Prometheus in the Background:** Start Prometheus with the updated configuration in the background: 2116 | ```bash 2117 | ./prometheus --config.file=prometheus.yml & 2118 | ``` 2119 | ### Prometheus is successfully scraping metrics from opentelemetry 2120 | --- 2121 | ![](/Images/otel-up.jpg) 2122 | 2123 | --- 2124 | The above screenshot confirms that Prometheus is successfully scraping metrics from opentelemetry. 2125 | 2126 | ### Visualize OpenTelemetry Metrics in Grafana 2127 | 2128 | Follow these steps to visualize OpenTelemetry metrics in Grafana: 2129 | 2130 | #### 1. Open Grafana 2131 | Access Grafana in your browser: 2132 | ```bash 2133 | http://:3001 2134 | ``` 2135 | 2136 | #### 2. Create a New Dashboard 2137 | - Navigate to the **Grafana Home Page**. 2138 | - Click on **Create your first Dashboard**. 2139 | 2140 | ### You will see the following page: 2141 | 2142 | --- 2143 | ![](/Images/grafana-prebuild.jpg) 2144 | 2145 | --- 2146 | 2147 | #### 3. Add a Visualization 2148 | Click on **Add visualization**, and you will be redirected to the following page: 2149 | 2150 | --- 2151 | ![](/Images/grafana-prometheus-trivy.jpg) 2152 | --- 2153 | Select **Prometheus** as the data source. 2154 | 2155 | #### 4. Run a Query 2156 | - Enter the PromQL queries in the metrics field, run the query, and choose a visualization type like Table, Gauge, or Time Series. 2157 | - **CPU Usage Visualization** 2158 | ```PromQL 2159 | rate(process_cpu_seconds_total[5m]) 2160 | ``` 2161 | **Visualization Type**: Time Series 2162 | 2163 | --- 2164 | ![](/Images/otel-process-cpu.jpg) 2165 | 2166 | --- 2167 | - **Memory Usage Visualization** 2168 | ```PromQL 2169 | process_resident_memory_bytes 2170 | ``` 2171 | **Visualization Type:** Gauge 2172 | 2173 | --- 2174 | ![](/Images/otel-memory-bytes.jpg) 2175 | 2176 | --- 2177 | - **Uptime Visualization** 2178 | ```PromQL 2179 | time() - process_start_time_seconds 2180 | ``` 2181 | --- 2182 | ![](/Images/otel-process-start.jpg) 2183 | 2184 | --- 2185 | #### 5. Save the Dashboard 2186 | - Once you are satisfied with the visualization, save the dashboard for future use. 2187 | 2188 | --- 2189 | 2190 | ## 🔔 **Jenkins Slack Notification Configuration** 2191 | 📢 Automate **Build Status Alerts** with Slack Integration in Jenkins! 2192 | 2193 | ### ✅ **Follow this Guide:** 2194 | 📌 [Step-by-Step Slack Notification Setup in Jenkins](https://www.youtube.com/watch?v=9ZUy3oHNgh8&t=789s) 2195 | 2196 | --- 2197 | 2198 | --- 2199 | 2200 | ## ⚠️ Configuring Grafana Alerts for Security and Performance Monitoring 2201 | 2202 | ### 📌 Step 1: Open Grafana & Navigate to Alerting 2203 | - Go to **Grafana Dashboard** (`http://your-grafana-ip:3001`). 2204 | - Click on **"Alerting" → "Alert Rules"**. 2205 | - Click **"Create Alert Rule"**. 2206 | 2207 | ### 📌 Step 2: Select Data Source & Define Alert Conditions 2208 | - Choose **Prometheus** as the data source. 2209 | - Define a **PromQL query** to specify alert conditions. 2210 | 2211 | ### 📌 Step 3: Define Alert Queries for Each Tool 2212 | 2213 | #### ✅ **Trivy Security Alerts (Critical Vulnerabilities)** 2214 | ```promql 2215 | trivy_vulnerabilities{severity="CRITICAL"} > 0 2216 | ``` 2217 | 2218 | - **Condition:** If `CRITICAL` vulnerabilities exist, trigger an alert. 2219 | 2220 | #### ✅ TFsec Security Alerts (Terraform Misconfigurations) 2221 | - **PromQL Query:** 2222 | ```promql 2223 | tfsec_vulnerabilities > 0 2224 | ``` 2225 | - **Condition:** If TFsec detects infrastructure misconfigurations, trigger an alert. 2226 | 2227 | #### ✅OpenTelemetry Performance Alerts (High CPU Usage) 2228 | - **PromQL Query:** 2229 | ```promql 2230 | rate(process_cpu_seconds_total[5m]) > 0.9 2231 | ``` 2232 | - **Condition:** If CPU usage exceeds `90%` for `5 minutes`, trigger an alert. 2233 | 2234 | ### 📌 Configure Notification Channels 2235 | - Navigate to **"Alerting" → "Notification Policies"**. 2236 | - Click **"Add a New Contact Point"**. 2237 | 2238 | #### **✅ Slack Integration** 2239 | - Select **"Slack"** as the notification type. 2240 | - Paste the **Slack Webhook URL**. 2241 | - Click **"Send Test Notification"** to verify. 2242 | --- 2243 | ![](/Images/Grafana-alert.jpg) 2244 | 2245 | --- 2246 | 2247 | #### **✅ Microsoft Teams Integration** 2248 | - Select **"Webhook"** as the notification type. 2249 | - Paste the **Microsoft Teams Webhook URL**. 2250 | 2251 | #### **✅ Email Notification Setup** 2252 | - Select **"Email"** as the notification type. 2253 | - Enter the recipient email (e.g., `security-team@company.com`). 2254 | 2255 | ### Enable Alerting & Save 2256 | - Click **"Save & Apply"**. 2257 | - Ensure **alert rules are active**. 2258 | - Generate a **test alert** by manually increasing vulnerabilities or CPU usage. 2259 | 2260 | ### Verify Alerts 2261 | - Check if Slack, Teams, or Email notifications are received. 2262 | - Adjust alert thresholds to minimize false positives. 2263 | 2264 | --- 2265 | ## Automating with Jenkins Pipeline 2266 | 2267 | ### Creating Jenkins Pipeline 2268 | 2269 | 1. In the Jenkins dashboard, click on **+ New Item** or **New Job**. 2270 | 2. Provide a name (e.g., Devsecops Pipeline). 2271 | 3. Select **Pipeline** and click **OK** to proceed. 2272 | 4. In the left-side menu, click **Configure**. 2273 | 5. In the **Pipeline** section: 2274 | - in **Definition** select **Pipeline script from SCM**. 2275 | - Under **SCM**, select **Git**. 2276 | - Provide the repository URL: `https://github.com/DevopsProjects05/DevSecOps-End-to-End-Project.git`. 2277 | - In **Branches to build**, enter: `*/main`. 2278 | - For **Script Path**, enter: `Jenkinsfile/Jenkinsfile`. 2279 | 6. Click **Apply** and **Save**. 2280 | 2281 | ### Store the Private Key in Jenkins Credentials 2282 | 2283 | Once the **EC2 instance** is launched, store the **private key** in **Jenkins Global Credentials** for secure SSH access. 2284 | 2285 | 1. **Open the `.pem` file** (e.g., `ci-cd-key.pem`) using **Notepad** or any text editor. 2286 | 2. **Copy the entire private key**, including: `-----BEGIN RSA PRIVATE KEY----- (Private Key Content) -----END RSA PRIVATE KEY-----` 2287 | 3. **Go to Jenkins Dashboard** → **Manage Jenkins** → **Manage Credentials**. 2288 | 4. Under **Global credentials**, click **Add Credentials**. 2289 | 5. **Set the following values**: 2290 | - **Kind**: Select **SSH Username with Private Key**. 2291 | - **ID**: Enter **"ANSIBLE_SSH_KEY"**. 2292 | - **Username**: Enter **"ec2-user"**. 2293 | - **Private Key**: Select **"Enter directly"**, then **paste** the copied private key. 2294 | 6. Click **Add**, then **Apply & Save**. 2295 | 2296 | ✅ **Your private key is now securely stored in Jenkins, ready for automated deployments!** 🚀 2297 | 2298 | ``` 2299 | # ⚠️🚀 **IMPORTANT NOTE: BEFORE RUNNING THE PIPELINE** 🚀⚠️ 2300 | 2301 | **Before executing the Jenkins pipeline, ensure the following critical conditions are met to prevent failures: 2302 | 2303 | ## ❌ Delete Any Existing EC2 Instance 2304 | - Before running the pipeline, delete any existing EC2 instance to avoid conflicts and unexpected errors. 2305 | 2306 | ## 🔐 Ensure Proper Permissions for Ansible SSH Key 2307 | - The SSH key used by Ansible must have correct permissions to enable a secure connection. 2308 | 2309 | ### ✅ Run the Following Command: # Replace with your workspace name 2310 | 2311 | chmod 777 /var/lib/jenkins/workspace/your-workspace-name/ansible/ansible_ssh_key.pem 2312 | 2313 | ``` 2314 | 2315 | ### Build the Jenkins Pipeline 2316 | 2317 | Once everything is set up, follow these steps to execute the Jenkins pipeline: 2318 | 2319 | 1. **Go to the Jenkins Dashboard**. 2320 | 2. Click on the **pipeline** that you have created. 2321 | 3. Click **"Build Now"** to start executing the pipeline. 2322 | 2323 | ✅ **Jenkins will now trigger the pipeline execution and automate the deployment process!** 🚀 2324 | 2325 | --- 2326 | ## **CI-CD Pipeline: Automated DevSecOps Deployment** 2327 | 2328 | This Jenkins pipeline automates the **secure deployment** of a Node.js application by integrating **Vault for secrets management, SonarQube for code quality, Snyk for security scanning, and TFScan for Terraform security checks**. It provisions **AWS infrastructure using Terraform**, builds and scans Docker images with **Trivy**, stores artifacts in **Nexus**, and deploys via **Ansible**. Additionally, it ensures **continuous monitoring and automated notifications** via Slack. This **end-to-end DevSecOps pipeline** guarantees a **robust, secure, and efficient software delivery process**. 2329 | 2330 | ### You will see the stage view of your pipeline: 2331 | 2332 | --- 2333 | ![](/Images/Devsecopspipeline.jpg) 2334 | 2335 | --- 2336 | 2337 | ## Who Can Use This Project? 2338 | 2339 | ✅ **DevOps Engineers** - To implement security in CI/CD pipelines. 2340 | ✅ **Security Teams** - To monitor vulnerabilities & enforce compliance. 2341 | ✅ **Developers** - To integrate security scanning into development workflows. 2342 | ✅ **Cloud Architects** - To manage Infrastructure as Code (IaC) securely. 2343 | ✅ **Interview Candidates** - To showcase **hands-on experience** in DevSecOps. 2344 | 2345 | --- 2346 | 2347 | ## Challenges and Learnings 2348 | ### Challenges Faced: 2349 | **Tool Integration Complexity:** Integrating multiple tools (Jenkins, Terraform, Trivy, SonarQube, etc.) required careful configuration and troubleshooting to ensure compatibility and smooth operation. 2350 | 2351 | **Security and Secrets Management:** Securely managing sensitive credentials using HashiCorp Vault and ensuring they were not exposed in logs or environment variables was a critical challenge. 2352 | 2353 | **Monitoring and Observability:** Setting up Prometheus, Grafana, and OpenTelemetry for real-time monitoring and tracing required learning new tools and configuring custom metrics. 2354 | 2355 | **Cost Optimization:** Balancing cost and functionality while running all tools on a single EC2 instance required careful resource allocation and performance tuning. 2356 | 2357 | **Pipeline Failures:** Debugging pipeline failures (e.g., Terraform errors, Docker build issues) required a systematic approach to identify and resolve root causes. 2358 | 2359 | ### Key Learnings: 2360 | **Automation is Key:** Automating repetitive tasks (e.g., infrastructure provisioning, security scans) reduces human error and speeds up deployments. 2361 | 2362 | **Security is Non-Negotiable:** Integrating security tools (e.g., Trivy, TFsec, Snyk) early in the pipeline ensures vulnerabilities are caught before production. 2363 | 2364 | **Observability is Crucial:** Real-time monitoring and alerting (via Prometheus, Grafana, and OpenTelemetry) provide actionable insights into system performance and security. 2365 | 2366 | **Documentation Matters:** Clear and detailed documentation is essential for onboarding new team members and troubleshooting issues. 2367 | 2368 | **Collaboration is Vital:** Integrating Slack notifications ensures team members are informed about pipeline status and security alerts. 2369 | 2370 | --- 2371 | 2372 | ### Future Enhancements 2373 | **Kubernetes Integration:** Migrate the application and tools to a Kubernetes cluster for better scalability and resource management. 2374 | 2375 | **Advanced Security Measures:** Integrate OWASP ZAP for dynamic application security testing (DAST) and runtime security monitoring using tools like Falco. 2376 | 2377 | **Multi-Cloud Support:** Extend the pipeline to support multi-cloud deployments (e.g., AWS, Azure, GCP) using Terraform or Crossplane. 2378 | 2379 | **Enhanced Monitoring:** Add distributed tracing using Jaeger or Zipkin and implement log aggregation using the ELK Stack or Fluentd. 2380 | 2381 | **Pipeline Optimization:** Implement parallel stages in the Jenkins pipeline and add automated rollback mechanisms for deployment failures. 2382 | 2383 | **Compliance and Governance:** Integrate compliance checks using tools like Open Policy Agent (OPA) or HashiCorp Sentinel. 2384 | 2385 | **AI/ML Integration:** Use machine learning models to predict and prevent potential security vulnerabilities or performance bottlenecks. 2386 | 2387 | **Improved Collaboration:** Integrate Jira or Trello for task management and add more notification channels (e.g., Microsoft Teams, PagerDuty). 2388 | 2389 | **Cost Management:** Implement cost monitoring and optimization tools like AWS Cost Explorer and add automated resource scaling. 2390 | 2391 | **User-Friendly Dashboards:** Create a centralized dashboard for all pipeline metrics, security insights, and deployment statuses using Grafana or Kibana. -------------------------------------------------------------------------------- /ansible/playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install Docker and Deploy Node.js App 3 | hosts: all 4 | become: true 5 | 6 | tasks: 7 | - name: Install Docker 8 | yum: 9 | name: docker 10 | state: present 11 | 12 | - name: Start Docker service 13 | systemd: 14 | name: docker 15 | state: started 16 | enabled: yes 17 | 18 | - name: Pull Docker Image 19 | command: docker pull nuthan0530/sample-ecommerce-nodejs-app 20 | 21 | - name: Run Docker Container 22 | command: docker run -d -p 80:3000 --name ecommerce-app nuthan0530/sample-ecommerce-nodejs-app 23 | -------------------------------------------------------------------------------- /src/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .git/ 3 | .env 4 | *.log 5 | *.pem 6 | *.key 7 | test-results/ 8 | -------------------------------------------------------------------------------- /src/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16-alpine 2 | 3 | # Set the working directory inside the container 4 | WORKDIR /app 5 | 6 | # Copy package.json from the src directory 7 | COPY package.json ./ 8 | RUN npm install 9 | 10 | # Copy the full application source code from src 11 | COPY . . 12 | 13 | # Expose the application port 14 | EXPOSE 3000 15 | 16 | # Start the application 17 | CMD ["npm", "start"] 18 | -------------------------------------------------------------------------------- /src/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: 'node', 3 | transform: { 4 | '^.+\\.js$': 'babel-jest' 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /src/otel-collector-config.yaml: -------------------------------------------------------------------------------- 1 | receivers: 2 | otlp: 3 | protocols: 4 | grpc: 5 | http: 6 | 7 | exporters: 8 | logging: 9 | 10 | service: 11 | pipelines: 12 | traces: 13 | receivers: [otlp] 14 | exporters: [logging] 15 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ecommerce-website", 3 | "version": "1.0.0", 4 | "description": "E-commerce project using Node.js", 5 | "main": "server.js", 6 | "scripts": { 7 | "start": "node server.js", 8 | "dev": "nodemon server.js", 9 | "test": "jest --no-coverage", 10 | "build": "echo 'No specific build step for Node.js frontend and backend' && exit 0", 11 | "lint": "eslint .", 12 | "format": "prettier --write ." 13 | }, 14 | "dependencies": { 15 | "express": "^4.18.2", 16 | "prom-client": "^14.0.1", 17 | "@opentelemetry/api": "^1.5.0", 18 | "@opentelemetry/sdk-trace-node": "^1.9.0", 19 | "@opentelemetry/resources": "^1.5.0", 20 | "@opentelemetry/exporter-trace-otlp-http": "^0.57.1" 21 | }, 22 | "devDependencies": { 23 | "nodemon": "^2.0.20", 24 | "jest": "^29.4.0", 25 | "supertest": "^6.3.3", 26 | "eslint": "^8.23.1", 27 | "prettier": "^2.7.1" 28 | }, 29 | "author": "Nuthan Gatla", 30 | "license": "ISC" 31 | } 32 | -------------------------------------------------------------------------------- /src/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | E-Commerce Website 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 40 |
41 | 42 | 43 |
44 |
45 | 46 | 47 |
48 |
49 |
50 |

Welcome to E-Commerce Website

51 |

About E-Commerce Company

52 |

We provide high quality products for all your needs. Whether you're shopping for fashion, electronics, or everyday essentials, we offer a wide range of products. Shop from the comfort of your home and get fast, reliable delivery.

53 |
54 |
55 |
56 | 57 | 58 |
59 |

© 2025 E-Commerce Website. All rights reserved.

60 |
61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /src/public/script.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', function () { 2 | // Fetch products from the API 3 | fetch('/api/products') 4 | .then((response) => response.json()) 5 | .then((products) => { 6 | const productsContainer = document.querySelector('.products'); 7 | 8 | // Loop through products and render them 9 | products.forEach((product) => { 10 | const productElement = document.createElement('div'); 11 | productElement.classList.add('product'); 12 | productElement.innerHTML = ` 13 |

${product.name}

14 |

Price: ${product.price}

15 | 16 | `; 17 | productsContainer.appendChild(productElement); 18 | }); 19 | 20 | // Add event listener for "Add to Cart" buttons 21 | document.querySelectorAll('.add-to-cart').forEach((button) => { 22 | button.addEventListener('click', function () { 23 | alert('Added to cart!'); 24 | }); 25 | }); 26 | }) 27 | .catch((error) => console.error('Error fetching products:', error)); 28 | }); 29 | 30 | // OpenTelemetry Tracing Example 31 | import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'; 32 | import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; 33 | import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'; 34 | 35 | const provider = new WebTracerProvider(); 36 | const exporter = new OTLPTraceExporter({ 37 | url: 'http://localhost:4318/v1/traces', 38 | }); 39 | provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); 40 | provider.register(); 41 | 42 | const tracer = provider.getTracer('ecommerce-frontend'); 43 | 44 | document.getElementById('buy-now').addEventListener('click', () => { 45 | const span = tracer.startSpan('buy-now-click'); 46 | console.log('Buy Now clicked!'); 47 | span.end(); 48 | }); 49 | -------------------------------------------------------------------------------- /src/public/style.css: -------------------------------------------------------------------------------- 1 | /* General Styles */ 2 | body { 3 | font-family: 'Roboto', sans-serif; 4 | background-color: #f8f9fa; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | /* Navbar Styles */ 10 | .navbar { 11 | background: linear-gradient(135deg, #71b7e6, #9b59b6); 12 | } 13 | 14 | /* Hero Section Styles */ 15 | .hero { 16 | background: url('https://zeve.au/sitecentre/uploads/2022/04/how-to-get-started-with-an-ecommerce-store.jpg') no-repeat center center; 17 | background-size: cover; 18 | height: 60vh; 19 | display: flex; 20 | justify-content: center; 21 | align-items: center; 22 | color: white; 23 | text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); 24 | } 25 | 26 | .hero h1 { 27 | font-size: 3rem; 28 | animation: fadeInDown 1s ease-in-out; 29 | } 30 | 31 | @keyframes fadeInDown { 32 | from { 33 | opacity: 0; 34 | transform: translateY(-20px); 35 | } 36 | to { 37 | opacity: 1; 38 | transform: translateY(0); 39 | } 40 | } 41 | 42 | /* Highlight Class */ 43 | .highlight { 44 | color: skyblue; 45 | } 46 | 47 | /* Content Section Styles */ 48 | .content { 49 | padding: 2rem 0; 50 | } 51 | 52 | /* Footer Styles */ 53 | .footer { 54 | background: #333; 55 | color: white; 56 | padding: 1rem 0; 57 | text-align: center; 58 | } -------------------------------------------------------------------------------- /src/server.js: -------------------------------------------------------------------------------- 1 | // Import dependencies 2 | const path = require('path'); 3 | const express = require('express'); 4 | const client = require('prom-client'); // Prometheus client library 5 | const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node'); 6 | const { trace } = require('@opentelemetry/api'); 7 | const { Resource } = require('@opentelemetry/resources'); 8 | const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http'); 9 | const { SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node'); 10 | 11 | // OpenTelemetry Setup 12 | const resource = new Resource({ 13 | 'service.name': 'devsecops-app', // Service name for traces 14 | }); 15 | const traceExporter = new OTLPTraceExporter({ 16 | url: 'http://15.207.71.232:4318/v1/traces', // Replace with your OpenTelemetry Collector IP 17 | }); 18 | const tracerProvider = new NodeTracerProvider({ resource }); 19 | tracerProvider.addSpanProcessor(new SimpleSpanProcessor(traceExporter)); 20 | tracerProvider.register(); 21 | const tracer = trace.getTracer('devsecops-tracer'); 22 | 23 | // Initialize Express app 24 | const app = express(); 25 | const port = process.env.PORT || 3000; 26 | 27 | // Serve static files (HTML, CSS, JS) 28 | app.use(express.static(path.join(__dirname, 'public'))); 29 | 30 | // Prometheus Metrics Setup 31 | const collectDefaultMetrics = client.collectDefaultMetrics; 32 | collectDefaultMetrics(); // Default system metrics like CPU, memory, etc. 33 | 34 | // Custom HTTP request duration metric 35 | const httpRequestDuration = new client.Histogram({ 36 | name: 'http_request_duration_seconds', 37 | help: 'Duration of HTTP requests in seconds', 38 | labelNames: ['method', 'route', 'status_code'], 39 | buckets: [0.1, 0.3, 0.5, 1, 1.5], // Define custom buckets 40 | }); 41 | 42 | // Middleware to measure HTTP request durations 43 | app.use((req, res, next) => { 44 | const end = httpRequestDuration.startTimer(); // Start timer 45 | res.on('finish', () => { 46 | end({ 47 | method: req.method, 48 | route: req.route ? req.route.path : req.url, 49 | status_code: res.statusCode, 50 | }); 51 | }); 52 | next(); 53 | }); 54 | 55 | // Expose Prometheus metrics at /metrics endpoint 56 | app.get('/metrics', async (req, res) => { 57 | res.set('Content-Type', client.register.contentType); 58 | res.send(await client.register.metrics()); 59 | }); 60 | 61 | // Home route with custom span 62 | app.get('/', (req, res) => { 63 | const span = tracer.startSpan('Home Route Span'); 64 | res.sendFile(path.join(__dirname, 'public/index.html')); 65 | span.end(); 66 | }); 67 | 68 | // Health check route with custom span 69 | app.get('/health', (req, res) => { 70 | const span = tracer.startSpan('Health Check Route Span'); 71 | res.json({ status: 'UP', timestamp: new Date().toISOString() }); 72 | span.end(); 73 | }); 74 | 75 | // Custom route with a detailed custom span 76 | app.get('/custom', (req, res) => { 77 | const span = tracer.startSpan('Custom Route Span'); 78 | span.addEvent('Processing custom route'); 79 | res.send('This is a custom route with OpenTelemetry!'); 80 | span.end(); 81 | }); 82 | 83 | // New additional route for handling errors 84 | app.get('/error', (req, res) => { 85 | const span = tracer.startSpan('Error Route Span'); 86 | span.addEvent('Simulating error route'); 87 | res.status(500).json({ error: 'Simulated error occurred!' }); 88 | span.end(); 89 | }); 90 | 91 | // Start the server 92 | if (require.main === module) { 93 | app.listen(port, () => { 94 | console.log(`Server is running on http://localhost:${port}`); 95 | }); 96 | } 97 | 98 | module.exports = app; 99 | -------------------------------------------------------------------------------- /src/test/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: 'node', 3 | collectCoverage: false, // Completely disable code coverage 4 | testPathIgnorePatterns: ["/node_modules/", "/dist/"], // Ignore unnecessary folders 5 | reporters: [ 6 | "default", 7 | ["jest-junit", { outputDirectory: "./test-results", outputName: "results.xml" }] 8 | ], 9 | verbose: true, // Enables detailed test execution logs 10 | }; -------------------------------------------------------------------------------- /src/test/server.test.js: -------------------------------------------------------------------------------- 1 | const request = require('supertest'); 2 | const app = require('../server'); 3 | 4 | describe('E-Commerce Website Tests', () => { 5 | it('GET / should return the homepage', async () => { 6 | const res = await request(app).get('/'); 7 | expect(res.statusCode).toBe(200); 8 | }); 9 | 10 | it('GET /health should return server health status', async () => { 11 | const res = await request(app).get('/health'); 12 | expect(res.statusCode).toBe(200); 13 | expect(res.body.status).toBe('UP'); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /terraform/.gitignore: -------------------------------------------------------------------------------- 1 | terraform.tfvars -------------------------------------------------------------------------------- /terraform/main.tf: -------------------------------------------------------------------------------- 1 | provider "vault" { 2 | } 3 | 4 | data "vault_generic_secret" "aws_credentials" { 5 | path = "aws/creds/dev-role" 6 | } 7 | 8 | provider "aws" { 9 | region = "ap-south-1" 10 | access_key = var.aws_access_key 11 | secret_key = var.aws_secret_key 12 | } 13 | 14 | 15 | 16 | resource "aws_security_group" "Sample-Ecommerce-Instance-SG" { 17 | name = "Sample-Ecommerce-Instance-SG" 18 | description = "Allow restricted SSH and HTTP traffic" 19 | 20 | ingress { 21 | from_port = 22 22 | to_port = 22 23 | protocol = "tcp" 24 | cidr_blocks = ["49.204.214.169/32"] # Restrict SSH access to a specific range 25 | description = "Allow SSH from private network" 26 | } 27 | 28 | ingress { 29 | from_port = 80 30 | to_port = 80 31 | protocol = "tcp" 32 | cidr_blocks = ["49.204.214.169/32"] # Restrict HTTP access to a specific range 33 | description = "Allow HTTP from private network" 34 | } 35 | 36 | egress { 37 | from_port = 0 38 | to_port = 0 39 | protocol = "-1" 40 | cidr_blocks = [] # Restrict outbound traffic 41 | description = "Allow outbound traffic to private network" 42 | } 43 | 44 | tags = { 45 | Name = "Sample-Ecommerce-Instance-SG" 46 | } 47 | 48 | } 49 | 50 | resource "aws_instance" "Sample-Ecommerce-Instance" { 51 | ami = "ami-0ddfba243cbee3768" # Replace with your region-specific AMI 52 | instance_type = "t2.micro" # Free-tier eligible instance type 53 | key_name = "Devsecops" # SSH key pair name 54 | 55 | 56 | 57 | root_block_device { 58 | encrypted = true # Encrypt the root block device 59 | } 60 | 61 | metadata_options { 62 | http_tokens = "required" # Require metadata HTTP tokens 63 | } 64 | 65 | tags = { 66 | 67 | Name = "Sample-Ecommerce-Instance" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /terraform/output.tf: -------------------------------------------------------------------------------- 1 | output "public_ips" { 2 | value = aws_instance.Sample-Ecommerce-Instance.*.public_ip 3 | description = "Public IP addresses of the created instances" 4 | } -------------------------------------------------------------------------------- /terraform/variables.tf: -------------------------------------------------------------------------------- 1 | variable "aws_access_key" { 2 | description = "AWS Access Key" 3 | type = string 4 | } 5 | 6 | variable "aws_secret_key" { 7 | description = "AWS Secret Key" 8 | type = string 9 | } 10 | --------------------------------------------------------------------------------