diff --git a/.aws/buildspec-build.yml b/.aws/buildspec-build.yml new file mode 100644 index 00000000..5d9fb31e --- /dev/null +++ b/.aws/buildspec-build.yml @@ -0,0 +1,85 @@ +version: 0.2 + +env: + # ==================== # + # Ref: SECRET CONFIG # + # ==================== # + parameter-store: + BUILDNUMBER: /devopscorner/cicd/staging/repo/bookstore-adot/buildnumber + STORE_AWS_ACCOUNT: /devopscorner/cicd/staging/credentials/aws_account + STORE_AWS_ACCESS_KEY: /devopscorner/cicd/staging/credentials/aws_access_key + STORE_AWS_SECRET_KEY: /devopscorner/cicd/staging/credentials/aws_secret_key + STORE_REPO_URL: /devopscorner/cicd/staging/repo/bookstore-adot/url + STORE_REPO_BRANCH: /devopscorner/cicd/staging/repo/bookstore-adot/branch + STORE_REPO_FOLDER: /devopscorner/cicd/staging/repo/bookstore-adot/folder + STORE_EKS_CLUSTER: /devopscorner/cicd/staging/eks_cluster + STORE_BASE64_PUB_KEY: /devopscorner/cicd/staging/credentials/base64_pub_key + STORE_BASE64_PRIV_KEY: /devopscorner/cicd/staging/credentials/base64_priv_key + STORE_BASE64_PEM_KEY: /devopscorner/cicd/staging/credentials/base64_pem_key + STORE_BASE64_SSH_CONFIG: /devopscorner/cicd/staging/credentials/base64_ssh_config + STORE_BASE64_KNOWN_HOSTS: /devopscorner/cicd/staging/credentials/known_hosts + STORE_BASE64_KUBECONFIG: /devopscorner/cicd/staging/credentials/base64_kube_config + + # ===================================== # + # Ref: Pipeline Environment Variables # + # ===================================== # + variables: + ENV_CICD: "dev" + AWS_DEFAULT_REGION: "us-west-2" + INFRA_CICD: "terraform/environment/providers/aws/infra/resources" + INFRA_CICD_PATH: "bookstore-adot" + INFRA_ECR_PATH: "devopscorner/bookstore-adot" + +phases: + pre_build: + commands: + # ======================= # + # Setup Auth Repository # + # ======================= # + - mkdir -p ~/.ssh + - echo "${STORE_BASE64_PUB_KEY}" | base64 -d > ~/.ssh/id_rsa.pub + - echo "${STORE_BASE64_PRIV_KEY}" | base64 -d > ~/.ssh/id_rsa + - echo "${STORE_BASE64_KNOWN_HOSTS}" | base64 -d > ~/.ssh/known_hosts + - chmod 400 ~/.ssh/id_rsa* + - chmod 644 ~/.ssh/known_hosts + - eval "$(ssh-agent -s)" + - ssh-add ~/.ssh/id_rsa + - echo '- DONE -' + build: + commands: + # ========================= # + # Refactoring AWS Account # + # ========================= # + - cd ${CODEBUILD_SRC_DIR} && find ./ -type f -exec sed -i "s/YOUR_AWS_ACCOUNT/${STORE_AWS_ACCOUNT}/g" {} \; + # ============= # + # Build Image # + # ============= # + - make ecr-build-alpine ARGS=${STORE_AWS_ACCOUNT} CI_PATH=${INFRA_ECR_PATH} + # ============== # + # Unit Testing # + # ============== # + # - make unit-test + # ============ # + # Tags Image # + # ============ # + - make ecr-tag-alpine ARGS=${STORE_AWS_ACCOUNT} CI_PATH=${INFRA_ECR_PATH} + - docker images --format "{{.Repository}}:{{.Tag}}" | grep ${INFRA_ECR_PATH} + # ============ # + # Push Image # + # ============ # + - make ecr-push-alpine ARGS=${STORE_AWS_ACCOUNT} TAGS=${INFRA_ECR_PATH} + +artifacts: + files: + - _infra/* + - .aws/* + - docs/* + - src/* + - dockerhub-build.sh + - dockerhub-push.sh + - dockerhub-tag.sh + - ecr-build.sh + - ecr-push.sh + - ecr-tag.sh + - Makefile + name: "artifact-$(date '+%Y%m%d-%H%M%S')" \ No newline at end of file diff --git a/.aws/buildspec-deploy.yml b/.aws/buildspec-deploy.yml new file mode 100644 index 00000000..c9b22402 --- /dev/null +++ b/.aws/buildspec-deploy.yml @@ -0,0 +1,88 @@ +version: 0.2 + +env: + # ==================== # + # Ref: SECRET CONFIG # + # ==================== # + parameter-store: + BUILDNUMBER: /devopscorner/cicd/staging/repo/bookstore-adot/buildnumber + STORE_AWS_ACCOUNT: /devopscorner/cicd/staging/credentials/aws_account + STORE_AWS_ACCESS_KEY: /devopscorner/cicd/staging/credentials/aws_access_key + STORE_AWS_SECRET_KEY: /devopscorner/cicd/staging/credentials/aws_secret_key + STORE_REPO_URL: /devopscorner/cicd/staging/repo/bookstore-adot/url + STORE_REPO_BRANCH: /devopscorner/cicd/staging/repo/bookstore-adot/branch + STORE_REPO_FOLDER: /devopscorner/cicd/staging/repo/bookstore-adot/folder + STORE_EKS_CLUSTER: /devopscorner/cicd/staging/eks_cluster + STORE_BASE64_PUB_KEY: /devopscorner/cicd/staging/credentials/base64_pub_key + STORE_BASE64_PRIV_KEY: /devopscorner/cicd/staging/credentials/base64_priv_key + STORE_BASE64_PEM_KEY: /devopscorner/cicd/staging/credentials/base64_pem_key + STORE_BASE64_SSH_CONFIG: /devopscorner/cicd/staging/credentials/base64_ssh_config + STORE_BASE64_KNOWN_HOSTS: /devopscorner/cicd/staging/credentials/known_hosts + STORE_BASE64_KUBECONFIG: /devopscorner/cicd/staging/credentials/base64_kube_config + + # ===================================== # + # Ref: Pipeline Environment Variables # + # ===================================== # + variables: + ENV_CICD: "dev" + AWS_DEFAULT_REGION: "us-west-2" + INFRA_CICD: "terraform/environment/providers/aws/infra/resources" + INFRA_CICD_PATH: "bookstore-adot" + INFRA_ECR_PATH: "devopscorner/bookstore-adot" + +phases: + pre_build: + commands: + # ======================= # + # Setup Auth Repository # + # ======================= # + - mkdir -p ~/.ssh + - mkdir -p ~/.kube + - echo "${STORE_BASE64_PUB_KEY}" | base64 -d > ~/.ssh/id_rsa.pub + - echo "${STORE_BASE64_PRIV_KEY}" | base64 -d > ~/.ssh/id_rsa + - echo "${STORE_BASE64_KNOWN_HOSTS}" | base64 -d > ~/.ssh/known_hosts + - echo "${STORE_BASE64_KUBECONFIG}" | base64 -d > ~/.kube/config + - chmod 400 ~/.ssh/id_rsa* + - chmod 400 ~/.kube/config* + - chmod 644 ~/.ssh/known_hosts + - eval "$(ssh-agent -s)" + - ssh-add ~/.ssh/id_rsa + - echo '- DONE -' + build: + commands: + # ========================= # + # Refactoring AWS Account # + # ========================= # + - cd ${CODEBUILD_SRC_DIR} && find ./ -type f -exec sed -i "s/YOUR_AWS_ACCOUNT/${STORE_AWS_ACCOUNT}/g" {} \; + # ================== # + # Helm Repo Update # + # ================== # + - AWS_REGION=${AWS_DEFAULT_REGION} helm repo add devopscorner-staging s3://devopscorner-adot-chart/staging + - AWS_REGION=${AWS_DEFAULT_REGION} helm repo add devopscorner-prod s3://devopscorner-adot-chart/prod + - helm repo update + # ============ # + # Deploy K8S # + # ============ # + - cd _infra/${ENV_CICD} + - aws eks update-kubeconfig --region ${AWS_DEFAULT_REGION} --name ${STORE_EKS_CLUSTER} + - kubectl version + - kubectl config use-context arn:aws:eks:${AWS_DEFAULT_REGION}:${STORE_AWS_ACCOUNT}:cluster/${STORE_EKS_CLUSTER} + - kubectl get ns -A + - helmfile --version + - helmfile -f helm-template.yml apply + - echo '-- ALL DONE --' + +artifacts: + files: + - _infra/* + - .aws/* + - docs/* + - src/* + - dockerhub-build.sh + - dockerhub-push.sh + - dockerhub-tag.sh + - ecr-build.sh + - ecr-push.sh + - ecr-tag.sh + - Makefile + name: "artifact-$(date '+%Y%m%d-%H%M%S')" \ No newline at end of file diff --git a/.aws/buildspec-provisioning-amg.yml b/.aws/buildspec-provisioning-amg.yml new file mode 100644 index 00000000..16c3df24 --- /dev/null +++ b/.aws/buildspec-provisioning-amg.yml @@ -0,0 +1,84 @@ +version: 0.2 + +env: + # ==================== # + # Ref: SECRET CONFIG # + # ==================== # + parameter-store: + BUILDNUMBER: /devopscorner/cicd/staging/repo/bookstore-adot/buildnumber + STORE_AWS_ACCOUNT: /devopscorner/cicd/staging/credentials/aws_account + STORE_AWS_ACCESS_KEY: /devopscorner/cicd/staging/credentials/aws_access_key + STORE_AWS_SECRET_KEY: /devopscorner/cicd/staging/credentials/aws_secret_key + STORE_REPO_URL: /devopscorner/cicd/staging/repo/bookstore-adot/url + STORE_REPO_BRANCH: /devopscorner/cicd/staging/repo/bookstore-adot/branch + STORE_REPO_FOLDER: /devopscorner/cicd/staging/repo/bookstore-adot/folder + STORE_EKS_CLUSTER: /devopscorner/cicd/staging/eks_cluster + STORE_BASE64_PUB_KEY: /devopscorner/cicd/staging/credentials/base64_pub_key + STORE_BASE64_PRIV_KEY: /devopscorner/cicd/staging/credentials/base64_priv_key + STORE_BASE64_PEM_KEY: /devopscorner/cicd/staging/credentials/base64_pem_key + STORE_BASE64_SSH_CONFIG: /devopscorner/cicd/staging/credentials/base64_ssh_config + STORE_BASE64_KNOWN_HOSTS: /devopscorner/cicd/staging/credentials/known_hosts + STORE_BASE64_KUBECONFIG: /devopscorner/cicd/staging/credentials/base64_kube_config + + # ===================================== # + # Ref: Pipeline Environment Variables # + # ===================================== # + variables: + ENV_CICD: "dev" + AWS_DEFAULT_REGION: "us-west-2" + INFRA_CICD: "terraform/environment/providers/aws/infra/resources" + INFRA_RESOURCES_TERRAFORM: "amg" + INFRA_CICD_PATH: "bookstore-adot" + INFRA_ECR_PATH: "devopscorner/bookstore-adot" + +phases: + build: + commands: + # ========================= # + # Refactoring AWS Account # + # ========================= # + - cd ${CODEBUILD_SRC_DIR} && find ./ -type f -exec sed -i "s/YOUR_AWS_ACCOUNT/${STORE_AWS_ACCOUNT}/g" {} \; + # =========================== # + # Install Terraform Modules # + # =========================== # + - make codebuild-modules + - cd ${CODEBUILD_SRC_DIR}/${INFRA_RESOURCES}/${INFRA_RESOURCES_TERRAFORM} + # ========================= # + # Terraform Plan (Review) # + # ========================= # + - terraform init + - terraform workspace select ${WORKSPACE_ENV} || terraform workspace new ${WORKSPACE_ENV} + - terraform plan --out tfplan.binary + - terraform show -json tfplan.binary > tfplan.json + # ================== # + # Terraform Addons # + # ================== # + # ~ Terrascan ~ + - terrascan init + - terrascan scan -o human + # ~ Tfsec ~ + - tfsec . + # ~ Checkov + - checkov -f tfplan.json + # ~ Infracost + - infracost breakdown --path tfplan.json + # ======================== # + # Terraform Provisioning # + # ======================== # + - terraform apply -auto-approve +artifacts: + files: + - _infra/* + - .aws/* + - docs/* + - src/* + - dockerhub-build.sh + - dockerhub-push.sh + - dockerhub-tag.sh + - ecr-build.sh + - ecr-push.sh + - ecr-tag.sh + - Makefile + - tfplan.binary + - tfplan.json + name: "artifact-$(date '+%Y%m%d-%H%M%S')" \ No newline at end of file diff --git a/.aws/buildspec-provisioning-amp.yml b/.aws/buildspec-provisioning-amp.yml new file mode 100644 index 00000000..072e624a --- /dev/null +++ b/.aws/buildspec-provisioning-amp.yml @@ -0,0 +1,84 @@ +version: 0.2 + +env: + # ==================== # + # Ref: SECRET CONFIG # + # ==================== # + parameter-store: + BUILDNUMBER: /devopscorner/cicd/staging/repo/bookstore-adot/buildnumber + STORE_AWS_ACCOUNT: /devopscorner/cicd/staging/credentials/aws_account + STORE_AWS_ACCESS_KEY: /devopscorner/cicd/staging/credentials/aws_access_key + STORE_AWS_SECRET_KEY: /devopscorner/cicd/staging/credentials/aws_secret_key + STORE_REPO_URL: /devopscorner/cicd/staging/repo/bookstore-adot/url + STORE_REPO_BRANCH: /devopscorner/cicd/staging/repo/bookstore-adot/branch + STORE_REPO_FOLDER: /devopscorner/cicd/staging/repo/bookstore-adot/folder + STORE_EKS_CLUSTER: /devopscorner/cicd/staging/eks_cluster + STORE_BASE64_PUB_KEY: /devopscorner/cicd/staging/credentials/base64_pub_key + STORE_BASE64_PRIV_KEY: /devopscorner/cicd/staging/credentials/base64_priv_key + STORE_BASE64_PEM_KEY: /devopscorner/cicd/staging/credentials/base64_pem_key + STORE_BASE64_SSH_CONFIG: /devopscorner/cicd/staging/credentials/base64_ssh_config + STORE_BASE64_KNOWN_HOSTS: /devopscorner/cicd/staging/credentials/known_hosts + STORE_BASE64_KUBECONFIG: /devopscorner/cicd/staging/credentials/base64_kube_config + + # ===================================== # + # Ref: Pipeline Environment Variables # + # ===================================== # + variables: + ENV_CICD: "dev" + AWS_DEFAULT_REGION: "us-west-2" + INFRA_CICD: "terraform/environment/providers/aws/infra/resources" + INFRA_RESOURCES_TERRAFORM: "amp" + INFRA_CICD_PATH: "bookstore-adot" + INFRA_ECR_PATH: "devopscorner/bookstore-adot" + +phases: + build: + commands: + # ========================= # + # Refactoring AWS Account # + # ========================= # + - cd ${CODEBUILD_SRC_DIR} && find ./ -type f -exec sed -i "s/YOUR_AWS_ACCOUNT/${STORE_AWS_ACCOUNT}/g" {} \; + # =========================== # + # Install Terraform Modules # + # =========================== # + - make codebuild-modules + - cd ${CODEBUILD_SRC_DIR}/${INFRA_RESOURCES}/${INFRA_RESOURCES_TERRAFORM} + # ========================= # + # Terraform Plan (Review) # + # ========================= # + - terraform init + - terraform workspace select ${WORKSPACE_ENV} || terraform workspace new ${WORKSPACE_ENV} + - terraform plan --out tfplan.binary + - terraform show -json tfplan.binary > tfplan.json + # ================== # + # Terraform Addons # + # ================== # + # ~ Terrascan ~ + - terrascan init + - terrascan scan -o human + # ~ Tfsec ~ + - tfsec . + # ~ Checkov + - checkov -f tfplan.json + # ~ Infracost + - infracost breakdown --path tfplan.json + # ======================== # + # Terraform Provisioning # + # ======================== # + - terraform apply -auto-approve +artifacts: + files: + - _infra/* + - .aws/* + - docs/* + - src/* + - dockerhub-build.sh + - dockerhub-push.sh + - dockerhub-tag.sh + - ecr-build.sh + - ecr-push.sh + - ecr-tag.sh + - Makefile + - tfplan.binary + - tfplan.json + name: "artifact-$(date '+%Y%m%d-%H%M%S')" \ No newline at end of file diff --git a/.aws/buildspec-provisioning-eks.yml b/.aws/buildspec-provisioning-eks.yml new file mode 100644 index 00000000..fa08219c --- /dev/null +++ b/.aws/buildspec-provisioning-eks.yml @@ -0,0 +1,84 @@ +version: 0.2 + +env: + # ==================== # + # Ref: SECRET CONFIG # + # ==================== # + parameter-store: + BUILDNUMBER: /devopscorner/cicd/staging/repo/bookstore-adot/buildnumber + STORE_AWS_ACCOUNT: /devopscorner/cicd/staging/credentials/aws_account + STORE_AWS_ACCESS_KEY: /devopscorner/cicd/staging/credentials/aws_access_key + STORE_AWS_SECRET_KEY: /devopscorner/cicd/staging/credentials/aws_secret_key + STORE_REPO_URL: /devopscorner/cicd/staging/repo/bookstore-adot/url + STORE_REPO_BRANCH: /devopscorner/cicd/staging/repo/bookstore-adot/branch + STORE_REPO_FOLDER: /devopscorner/cicd/staging/repo/bookstore-adot/folder + STORE_EKS_CLUSTER: /devopscorner/cicd/staging/eks_cluster + STORE_BASE64_PUB_KEY: /devopscorner/cicd/staging/credentials/base64_pub_key + STORE_BASE64_PRIV_KEY: /devopscorner/cicd/staging/credentials/base64_priv_key + STORE_BASE64_PEM_KEY: /devopscorner/cicd/staging/credentials/base64_pem_key + STORE_BASE64_SSH_CONFIG: /devopscorner/cicd/staging/credentials/base64_ssh_config + STORE_BASE64_KNOWN_HOSTS: /devopscorner/cicd/staging/credentials/known_hosts + STORE_BASE64_KUBECONFIG: /devopscorner/cicd/staging/credentials/base64_kube_config + + # ===================================== # + # Ref: Pipeline Environment Variables # + # ===================================== # + variables: + ENV_CICD: "dev" + AWS_DEFAULT_REGION: "us-west-2" + INFRA_CICD: "terraform/environment/providers/aws/infra/resources" + INFRA_RESOURCES_TERRAFORM: "eks" + INFRA_CICD_PATH: "bookstore-adot" + INFRA_ECR_PATH: "devopscorner/bookstore-adot" + +phases: + build: + commands: + # ========================= # + # Refactoring AWS Account # + # ========================= # + - cd ${CODEBUILD_SRC_DIR} && find ./ -type f -exec sed -i "s/YOUR_AWS_ACCOUNT/${STORE_AWS_ACCOUNT}/g" {} \; + # =========================== # + # Install Terraform Modules # + # =========================== # + - make codebuild-modules + - cd ${CODEBUILD_SRC_DIR}/${INFRA_RESOURCES}/${INFRA_RESOURCES_TERRAFORM} + # ========================= # + # Terraform Plan (Review) # + # ========================= # + - terraform init + - terraform workspace select ${WORKSPACE_ENV} || terraform workspace new ${WORKSPACE_ENV} + - terraform plan --out tfplan.binary + - terraform show -json tfplan.binary > tfplan.json + # ================== # + # Terraform Addons # + # ================== # + # ~ Terrascan ~ + - terrascan init + - terrascan scan -o human + # ~ Tfsec ~ + - tfsec . + # ~ Checkov + - checkov -f tfplan.json + # ~ Infracost + - infracost breakdown --path tfplan.json + # ======================== # + # Terraform Provisioning # + # ======================== # + - terraform apply -auto-approve +artifacts: + files: + - _infra/* + - .aws/* + - docs/* + - src/* + - dockerhub-build.sh + - dockerhub-push.sh + - dockerhub-tag.sh + - ecr-build.sh + - ecr-push.sh + - ecr-tag.sh + - Makefile + - tfplan.binary + - tfplan.json + name: "artifact-$(date '+%Y%m%d-%H%M%S')" \ No newline at end of file diff --git a/.aws/buildspec-provisioning-opensearch.yml b/.aws/buildspec-provisioning-opensearch.yml new file mode 100644 index 00000000..59ff31a2 --- /dev/null +++ b/.aws/buildspec-provisioning-opensearch.yml @@ -0,0 +1,84 @@ +version: 0.2 + +env: + # ==================== # + # Ref: SECRET CONFIG # + # ==================== # + parameter-store: + BUILDNUMBER: /devopscorner/cicd/staging/repo/bookstore-adot/buildnumber + STORE_AWS_ACCOUNT: /devopscorner/cicd/staging/credentials/aws_account + STORE_AWS_ACCESS_KEY: /devopscorner/cicd/staging/credentials/aws_access_key + STORE_AWS_SECRET_KEY: /devopscorner/cicd/staging/credentials/aws_secret_key + STORE_REPO_URL: /devopscorner/cicd/staging/repo/bookstore-adot/url + STORE_REPO_BRANCH: /devopscorner/cicd/staging/repo/bookstore-adot/branch + STORE_REPO_FOLDER: /devopscorner/cicd/staging/repo/bookstore-adot/folder + STORE_EKS_CLUSTER: /devopscorner/cicd/staging/eks_cluster + STORE_BASE64_PUB_KEY: /devopscorner/cicd/staging/credentials/base64_pub_key + STORE_BASE64_PRIV_KEY: /devopscorner/cicd/staging/credentials/base64_priv_key + STORE_BASE64_PEM_KEY: /devopscorner/cicd/staging/credentials/base64_pem_key + STORE_BASE64_SSH_CONFIG: /devopscorner/cicd/staging/credentials/base64_ssh_config + STORE_BASE64_KNOWN_HOSTS: /devopscorner/cicd/staging/credentials/known_hosts + STORE_BASE64_KUBECONFIG: /devopscorner/cicd/staging/credentials/base64_kube_config + + # ===================================== # + # Ref: Pipeline Environment Variables # + # ===================================== # + variables: + ENV_CICD: "dev" + AWS_DEFAULT_REGION: "us-west-2" + INFRA_CICD: "terraform/environment/providers/aws/infra/resources" + INFRA_RESOURCES_TERRAFORM: "opensearch" + INFRA_CICD_PATH: "bookstore-adot" + INFRA_ECR_PATH: "devopscorner/bookstore-adot" + +phases: + build: + commands: + # ========================= # + # Refactoring AWS Account # + # ========================= # + - cd ${CODEBUILD_SRC_DIR} && find ./ -type f -exec sed -i "s/YOUR_AWS_ACCOUNT/${STORE_AWS_ACCOUNT}/g" {} \; + # =========================== # + # Install Terraform Modules # + # =========================== # + - make codebuild-modules + - cd ${CODEBUILD_SRC_DIR}/${INFRA_RESOURCES}/${INFRA_RESOURCES_TERRAFORM} + # ========================= # + # Terraform Plan (Review) # + # ========================= # + - terraform init + - terraform workspace select ${WORKSPACE_ENV} || terraform workspace new ${WORKSPACE_ENV} + - terraform plan --out tfplan.binary + - terraform show -json tfplan.binary > tfplan.json + # ================== # + # Terraform Addons # + # ================== # + # ~ Terrascan ~ + - terrascan init + - terrascan scan -o human + # ~ Tfsec ~ + - tfsec . + # ~ Checkov + - checkov -f tfplan.json + # ~ Infracost + - infracost breakdown --path tfplan.json + # ======================== # + # Terraform Provisioning # + # ======================== # + - terraform apply -auto-approve +artifacts: + files: + - _infra/* + - .aws/* + - docs/* + - src/* + - dockerhub-build.sh + - dockerhub-push.sh + - dockerhub-tag.sh + - ecr-build.sh + - ecr-push.sh + - ecr-tag.sh + - Makefile + - tfplan.binary + - tfplan.json + name: "artifact-$(date '+%Y%m%d-%H%M%S')" \ No newline at end of file diff --git a/.aws/cicd-aws-codepipeline.yml b/.aws/cicd-aws-codepipeline.yml new file mode 100644 index 00000000..7c8a7c6d --- /dev/null +++ b/.aws/cicd-aws-codepipeline.yml @@ -0,0 +1,48 @@ +version: 0.2 + +phases: + install: + runtime-versions: + docker: 19 + build: + commands: + - go build -o app + - | + if [[ "$CODEBUILD_WEBHOOK_TRIGGER" == "branch/main" ]]; then + semver=1.0.0-${CODEBUILD_SOURCE_VERSION} + elif [[ "$CODEBUILD_WEBHOOK_TRIGGER" == "branch/features/"* ]]; then + semver=1.0.0-${CODEBUILD_WEBHOOK_TRIGGER#branch/features/}.${CODEBUILD_SOURCE_VERSION} + elif [[ "$CODEBUILD_WEBHOOK_TRIGGER" == "branch/bugfix/"* ]]; then + semver=1.1.0-${CODEBUILD_WEBHOOK_TRIGGER#branch/bugfix/}.${CODEBUILD_SOURCE_VERSION} + elif [[ "$CODEBUILD_WEBHOOK_TRIGGER" == "branch/hotfix/"* ]]; then + semver=1.1.1-${CODEBUILD_WEBHOOK_TRIGGER#branch/hotfix/}.${CODEBUILD_SOURCE_VERSION} + fi + echo "Semantic version: $semver" + echo "imageTag=$semver" >> $CODEBUILD_SRC_DIR/variables.env + $(aws ecr get-login --no-include-email --region $AWS_REGION) + docker build -t $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_NAME:$semver . + docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_NAME:$semver + docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_NAME:$semver $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_NAME:latest + docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_NAME:latest + post_build: + commands: + - | + echo "Deploying to Kubernetes using Helm" + curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash + helmfile sync + +artifacts: + files: + - _infra/* + - .aws/* + - docs/* + - src/* + - dockerhub-build.sh + - dockerhub-push.sh + - dockerhub-tag.sh + - ecr-build.sh + - ecr-push.sh + - ecr-tag.sh + - Makefile + name: "artifact-$(date '+%Y%m%d-%H%M%S')" + discard-paths: yes diff --git a/.aws/known_hosts b/.aws/known_hosts new file mode 100644 index 00000000..12da9c3a --- /dev/null +++ b/.aws/known_hosts @@ -0,0 +1,17 @@ +# GITLAB +## >> ssh-keyscan -H 'gitlab.com' >> ~/.ssh/known_hosts +## >> ssh -T git@gitlab.com + +# GITHUB +## >> ssh-keyscan -H 'github.com' >> ~/.ssh/known_hosts +## >> ssh -T git@github.com + +# BITBUCKET +## >> ssh-keyscan -H 'bitbucket.org' >> ~/.ssh/known_hosts +## >> ssh -T git@bitbucket.org + +# Azure DevOps +## >> ssh-keyscan -H 'vs-ssh.visualstudio.com' >> ~/.ssh/known_hosts +## >> ssh-keyscan -H '[organization]@vs-ssh.visualstudio.com' >> ~/.ssh/known_hosts +## >> ssh -T vs-ssh.visualstudio.com +## >> ssh -T [organization]@vs-ssh.visualstudio.com diff --git a/.aws/ssh-config b/.aws/ssh-config new file mode 100644 index 00000000..ed2abf17 --- /dev/null +++ b/.aws/ssh-config @@ -0,0 +1,17 @@ +############################# +### Repository CodeCommit ### +############################# +Host git-codecommit.*.amazonaws.com + User YOUR_CODECOMIT_SSH_ID + IdentityFile ~/.ssh/id_rsa + IdentitiesOnly yes + +############################### +### Repository Azure DevOps ### +############################### +Host ssh.dev.azure.com + User git + #PubkeyAcceptedAlgorithms +ssh-rsa + #HostkeyAlgorithms +ssh-rsa + IdentityFile ~/.ssh/id_rsa + IdentitiesOnly yes \ No newline at end of file diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..af2f8718 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +bin/** +build/** +logs/** +log/** +src/.env +src/*.db +.env +*.db diff --git a/.github/workflows/cicd-github.yml b/.github/workflows/cicd-github.yml new file mode 100644 index 00000000..1b472ad6 --- /dev/null +++ b/.github/workflows/cicd-github.yml @@ -0,0 +1,73 @@ +name: CI/CD Pipeline + +on: + push: + branches: + - features/* + - bugfix/* + - hotfix/* + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + env: + imageName: 'devopcorner/bookstore-adot' + ecrRegistry: '0987612345.dkr.ecr.us-west-2.amazonaws.com' + helmReleaseName: 'bookstore-adot' + + steps: + - name: Checkout Code + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.17 + + - name: Build Go Application + run: go build -o app + + - name: Set Semantic Version + run: | + if [[ "$GITHUB_REF" == "refs/heads/features/"* ]]; then + semver=1.0.0-${GITHUB_REF#refs/heads/features/}.${GITHUB_SHA::8} + elif [[ "$GITHUB_REF" == "refs/heads/bugfix/"* ]]; then + semver=1.1.0-${GITHUB_REF#refs/heads/bugfix/}.${GITHUB_SHA::8} + elif [[ "$GITHUB_REF" == "refs/heads/hotfix/"* ]]; then + semver=1.1.1-${GITHUB_REF#refs/heads/hotfix/}.${GITHUB_SHA::8} + fi + echo "::set-env name=imageTag::$semver" + + - name: Build and Push Docker Image + uses: docker/build-push-action@v2 + with: + context: . + push: true + tags: | + ${{ env.imageName }}:${{ env.imageTag }} + ${{ env.imageName }}:${{ github.ref }}-latest + ${{ env.imageName }}:latest + registry: ${{ env.ecrRegistry }} + username: ${{ secrets.ECR_USERNAME }} + password: ${{ secrets.ECR_PASSWORD }} + + - name: Install Helm + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.EKS_HOST }} + username: ${{ secrets.EKS_USERNAME }} + key: ${{ secrets.EKS_PRIVATE_KEY }} + script: | + curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash + + - name: Deploy to EKS using Helmfile + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.EKS_HOST }} + username: ${{ secrets.EKS_USERNAME }} + key: ${{ secrets.EKS_PRIVATE_KEY }} + script: | + helmfile sync diff --git a/.github/workflows/clone.yml b/.github/workflows/clone.yml new file mode 100644 index 00000000..0bbd1b6d --- /dev/null +++ b/.github/workflows/clone.yml @@ -0,0 +1,39 @@ +name: GitHub Clone Count for 14 days at every 6 hours + +# Controls when the action will run. +on: + schedule: + - cron: "0 */6 * * *" + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + - name: Parse clone count using REST API + run: | + curl --user "${{ github.actor }}:${{ secrets.SECRET_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + https://api.github.com/repos/${{ github.repository }}/traffic/clones \ + > clone.json + + - name: Add to git repo + run: | + git add . + git config --global user.name "GitHub Action" + git config --global user.email "action@github.com" + git commit -m "Automated clone.json update" + + - name: Push + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/repo-sync-from-github.yml b/.github/workflows/repo-sync-from-github.yml new file mode 100644 index 00000000..e1fc09d0 --- /dev/null +++ b/.github/workflows/repo-sync-from-github.yml @@ -0,0 +1,35 @@ +# Pipeline to automatically mirror +# a GitHub repository in AWS CodeCommit + +name: Sync Repository with AWS CodeCommit + +on: + workflow_dispatch + +env: + GITHUB_REPO_URL: ${{ secrets.GITHUB_REPO_URL }} + GITHUB_GIT_USERNAME: ${{ secrets.GITHUB_GIT_USERNAME }} + GITHUB_GIT_PASSWORD: ${{ secrets.GITHUB_GIT_PASSWORD }} + AWS_REPO_URL: ${{ secrets.AWS_REPO_URL }} + AWS_GIT_USERNAME: ${{ secrets.AWS_GIT_USERNAME }} + AWS_GIT_PASSWORD: ${{ secrets.AWS_GIT_PASSWORD }} + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Parse clone count using REST API + run: | + + # Install urlencode function to encode reserved characters in passwords + sudo apt-get install gridsite-clients + + # Create local mirror of Azure DevOps repository + git clone --mirror https://${GITHUB_GIT_USERNAME}:$(urlencode ${GITHUB_GIT_PASSWORD})@${GITHUB_REPO_URL} repo-mirror + + # Sync AWS CodeCommit repository + cd repo-mirror + git push --mirror https://${AWS_GIT_USERNAME}:$(urlencode ${AWS_GIT_PASSWORD})@${AWS_REPO_URL} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..d2e5e9fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,81 @@ +#### Terraform .gitignore template +## Comment path that would like to get ignored + +### Basic .gitignore +# **/terraform.tfstate +**/terraform.tfstate.backup +**/terraform.tfplan +**/.terraform/** +**/terraform.tfstate.d/** +**/*.tfplan +**/terraform_plugins/** +tfplan* +backend.hcl +*.hcl +*.lock.hcl +# only for snd +#backend.tf +#*.tfvars + +### https://raw.githubusercontent.com/hashicorp/terraform/master/.gitignore +*.dll +*.exe +.DS_Store +example.tf +terraform.tfplan +terraform.tfstate +tf.out +.vagrant/ +*.backup +./*.tfstate +errored.tfstate +.terraform/ +*.log +*.bak +*~ +.*.swp +.idea +*.iml +*.test +*.iml +#.envrc + +### https://raw.github.com/github/gitignore/abad92dac5a4306f72242dae3bca6e277bce3615/Global/Vim.gitignore + +# swap +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +# session +Session.vim +# temporary +.netrwhist +*~ +# auto-generated tag files +tags + +### Ignore .DS_Store on MAC +.DS_Store +.DS_Store? + +### Temporary dir for CodeDeploy +build/ +.build +dummy.zip + +terraform.tfstate* +*.tgz +*.pem +*.pub +*.env +*.icloud +*.id_rsa +logs +.idea +dist + +terraform/modules/** +test/** + +*.db + +dynamodb-golang-adot* \ No newline at end of file diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 00000000..44a7a05e --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,44 @@ +# This is an example goreleaser.yaml file with some sane defaults. +# Make sure to check the documentation at http://goreleaser.com +before: + hooks: + # You may remove this if you don't use go modules. + - go mod download + +builds: + - id: "go-bookstore-adot" + main: ./src/main.go + env: + # - GOOS=linux + # - GOARCH=amd64 + - CGO_ENABLED=0 + goos: + - linux + - windows + - darwin + +archives: + - id: "archive-go-bookstore-adot" + name_template: "authc_{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" + builds: # Builds reference which build instances should be archived in this archive. + - "goapp" + replacements: + darwin: Darwin + linux: Linux + windows: Windows + 386: i386 + amd64: x86_64 + allow_different_binary_count: true + +checksum: + name_template: 'checksums.txt' + +snapshot: + name_template: "{{ .Tag }}-next" + +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..e38a7107 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,51 @@ +# Golang Bookstore ADOT + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +![goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) ![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) ![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) [![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) ![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) ![download latest](https://img.shields.io/github/downloads/devopscorner/golang-adot/0.1/total) ![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) ![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) ![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) ![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) ![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) ![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) [![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Available Tags + +### Alpine GOLANG + +| Image name | Size | +|------------|------| +| `devopscorner/bookstore-adot:latest` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/latest.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=latest) ![default-latest](https://img.shields.io/static/v1?label=latest&message=default&color=brightgreen) ![latest](https://img.shields.io/static/v1?label=latest&message=alpine&color=orange) | +| `devopscorner/bookstore-adot:alpine` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/alpine.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=alpine) ![latest](https://img.shields.io/static/v1?label=latest&message=alpine&color=orange) | +| `devopscorner/bookstore-adot:alpine-latest` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/alpine-latest.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=alpine-latest) | +| `devopscorner/bookstore-adot:alpine-3.17` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/alpine-3.17.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=alpine-3.17) | + +### CICD Alpine-3.17 + +| Image name | Size | +|------------|------| +| `devopscorner/bookstore-adot:cicd-alpine` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-alpine.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-alpine) | +| `devopscorner/bookstore-adot:cicd-alpine-latest` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-alpine-latest.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-alpine-latest) | +| `devopscorner/bookstore-adot:cicd-alpine-3.17` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-alpine-3.17.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-alpine-3.17) | + +### CICD CodeBuild-4.0 + +| Image name | Size | +|------------|------| +| `devopscorner/bookstore-adot:cicd-codebuild` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-codebuild.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-codebuild) ![default-cicd-codebuild](https://img.shields.io/static/v1?label=latest&message=default&color=brightgreen) ![cicd-codebuild](https://img.shields.io/static/v1?label=latest&message=cicd-codebuild&color=orange) | +| `devopscorner/bookstore-adot:cicd-codebuild-latest` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-codebuild-latest.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-codebuild-latest) | +| `devopscorner/bookstore-adot:cicd-codebuild-4.0` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-codebuild-4.0.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-codebuild-4.0) | +| `devopscorner/bookstore-adot:cicd-latest` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-latest.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-latest) ![cicd-latest](https://img.shields.io/static/v1?label=latest&message=cicd-codebuild&color=orange) | + +--- + +### version 0.1 + +- First release for Golang Bookstore ADOT (AWS Distro for OpenTelemetry) +- Added HelmChart - Build, Pack & Push to S3 Bucket +- Added Terraform Provisioning Script + - Core Infra + - TFState DynamoDB + - Resources + - EC2 Instances Jumphost + - EKS + - Monitoring +- Added compability builder script container for AMD64 & ARM64 +- Added Pipeline CI/CD (default) with AWS Developer Tools (AWS CodeCommit, AWS CodeBuild & AWS CodePipeline) \ No newline at end of file diff --git a/Dockerfile-CICD.alpine-3.17-amd64 b/Dockerfile-CICD.alpine-3.17-amd64 new file mode 100644 index 00000000..2efa8005 --- /dev/null +++ b/Dockerfile-CICD.alpine-3.17-amd64 @@ -0,0 +1,138 @@ +### Builder ### +FROM golang:1.19.6-alpine3.17 as builder + +WORKDIR /go/src/app +ENV GIN_MODE=release +ENV GOPATH=/go + +RUN apk add --no-cache \ + build-base \ + git \ + curl \ + make \ + bash + +COPY src /go/src/app + +RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 \ + cd /go/src/app && \ + go build -mod=readonly -ldflags="-s -w" -o goapp + +### Binary ### +FROM devopscorner/cicd:alpine-3.17 + +ARG BUILD_DATE +ARG BUILD_VERSION +ARG GIT_COMMIT +ARG GIT_URL + +ENV VENDOR="DevOpsCornerId" +ENV AUTHOR="DevOpsCorner.id " +ENV IMG_NAME="alpine" +ENV IMG_VERSION="3.17" +ENV IMG_DESC="Docker GO App Alpine 3.17" +ENV IMG_ARCH="linux/amd64" + +ENV ALPINE_VERSION="3.17" +ENV GIN_MODE=release +ENV GOLANG_VERSION=1.19.6 +ENV APP_URL=${APP_URL:-http://localhost} +ENV APP_PORT=${APP_PORT:-8080} +ENV DB_CONNECTION=${DB_CONNECTION:-sqlite} +ENV DB_HOST=${DB_HOST:-localhost} +ENV DB_PORT=${DB_PORT} +ENV DB_DATABASE=${DB_DATABASE:-go-bookstore.db} +ENV DB_USERNAME=${DB_USERNAME:-root} +ENV DB_PASSWORD=${DB_PASSWORD} +ENV JWT_AUTH_USERNAME=${JWT_AUTH_USERNAME:-devopscorner} +ENV JWT_AUTH_PASSWORD=${JWT_AUTH_PASSWORD:-DevOpsCorner2023} +ENV JWT_SECRET=${JWT_SECRET:-s3cr3t} + +# Logger +ENV LOG_LEVEL=${LOG_LEVEL:-INFO} + +# AWS Credentials +ENV AWS_REGION=${AWS_REGION:-us-west-2} +ENV AWS_ACCESS_KEY=${AWS_ACCESS_KEY:-YOUR_AWS_ACCESS_KEY} +ENV AWS_SECRET_KEY_ID=${AWS_SECRET_KEY_ID:-YOUR_AWS_SECRET_KEY_ID} + +# OpenSearch +ENV OPENSEARCH_ENDPOINT=${OPENSEARCH_ENDPOINT:-https://opensearch.us-west-2.es.amazonaws.com} +ENV OPENSEARCH_USERNAME=${OPENSEARCH_USERNAME:-devopscorner} +ENV OPENSEARCH_PASSWORD=${OPENSEARCH_PASSWORD:-DevOpsCorner2023} + +# Prometheus +ENV PROMETHEUS_ENDPOINT=${PROMETHEUS_ENDPOINT:-http://localhost:9090} + +# Grafana +ENV GRAFANA_ENDPOINT=${GRAFANA_ENDPOINT:-http://localhost:3000} +ENV GRAFANA_API_KEY=${GRAFANA_API_KEY:-YOUR_GRAFANA_API_KEY} + +# OpenTelemetry +ENV OTEL_INSTRUMENTATION_METRIC_ENABLED=${OTEL_INSTRUMENTATION_METRIC_ENABLED:-true} +ENV OTEL_INSTRUMENTATION_TRACE_ENABLED=${OTEL_INSTRUMENTATION_TRACE_ENABLED:-true} +ENV OTEL_INSTRUMENTATION_LOG_ENABLED=${OTEL_INSTRUMENTATION_LOG_ENABLED:-true} +ENV OTEL_SERVICE_NAME=${OTEL_SERVICE_NAME:-bookstore-adot} +ENV OTEL_EXPORTER_OTLP_ENDPOINT=${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4317} +ENV OTEL_EXPORTER_OTLP_INSECURE=${OTEL_EXPORTER_OTLP_INSECURE:-true} +ENV OTEL_EXPORTER_OTLP_HEADERS=${OTEL_EXPORTER_OTLP_HEADERS} +ENV OTEL_RESOURCE_ATTRIBUTES=${OTEL_RESOURCE_ATTRIBUTES} + +# Jaeger +ENV JAEGER_AGENT_PORT=${JAEGER_AGENT_PORT:-6831} +ENV JAEGER_SAMPLER_TYPE=${JAEGER_SAMPLER_TYPE:-const} +ENV JAEGER_SAMPLER_PARAM=${JAEGER_SAMPLER_PARAM:-1} +ENV JAEGER_SAMPLER_MANAGER_HOST_PORT=${JAEGER_SAMPLER_MANAGER_HOST_PORT} +ENV JAEGER_REPORTER_LOG_SPANS=${JAEGER_REPORTER_LOG_SPANS:-true} +ENV JAEGER_REPORTER_BUFFER_FLUSH_INTERVAL=${JAEGER_REPORTER_BUFFER_FLUSH_INTERVAL:-5} +ENV JAEGER_REPORTER_MAX_QUEUE_SIZE=${JAEGER_REPORTER_MAX_QUEUE_SIZE:-100} +ENV JAEGER_REPORTER_LOCAL_AGENT_HOST_PORT=${JAEGER_REPORTER_LOCAL_AGENT_HOST_PORT} +ENV JAEGER_REPORTER_COLLECTOR_ENDPOINT=${JAEGER_REPORTER_COLLECTOR_ENDPOINT:-http://localhost:14268/api/traces} +ENV JAEGER_REPORTER_COLLECTOR_USER=${JAEGER_REPORTER_COLLECTOR_USER:-devopscorner} +ENV JAEGER_REPORTER_COLLECTOR_PASSWORD=${JAEGER_REPORTER_COLLECTOR_PASSWORD:-DevOpsCorner2023} +ENV JAEGER_TAGS=${JAEGER_TAGS:-golang,otel,restful,api,bookstore} + +# X-Ray +ENV XRAY_VERSION=${XRAY_VERSION:-latest} + +LABEL maintainer="$AUTHOR" \ + architecture="$IMG_ARCH" \ + alpine-version="$ALPINE_VERSION" \ + org.label-schema.build-date="$BUILD_DATE" \ + org.label-schema.name="$IMG_NAME" \ + org.label-schema.description="$IMG_DESC" \ + org.label-schema.vcs-ref="$GIT_COMMIT" \ + org.label-schema.vcs-url="$GIT_URL" \ + org.label-schema.vendor="$VENDOR" \ + org.label-schema.version="$BUILD_VERSION" \ + org.label-schema.schema-version="$IMG_VERSION" \ + org.opencontainers.image.authors="$AUTHOR" \ + org.opencontainers.image.description="$IMG_DESC" \ + org.opencontainers.image.vendor="$VENDOR" \ + org.opencontainers.image.version="$IMG_VERSION" \ + org.opencontainers.image.revision="$GIT_COMMIT" \ + org.opencontainers.image.created="$BUILD_DATE" \ + fr.hbis.docker.base.build-date="$BUILD_DATE" \ + fr.hbis.docker.base.name="$IMG_NAME" \ + fr.hbis.docker.base.vendor="$VENDOR" \ + fr.hbis.docker.base.version="$BUILD_VERSION" + +USER root + +## Install Golang with GVM ## +RUN curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer | bash +RUN gvm install go${GOLANG_VERSION}; sync +RUN gvm use go${GOLANG_VERSION} --default; sync + +WORKDIR /go + +COPY --from=builder /go/src/app/goapp /go/goapp +COPY --from=devopscorner/k8s-context:latest /usr/local/bin/k8s-context /usr/local/bin/k8s-context +COPY --from=devopscorner/k8s-context:latest /usr/local/bin/kc /usr/local/bin/kc + +COPY src /go/src +COPY src/.env.example /go/.env +COPY entrypoint.sh /go/entrypoint + +# ENTRYPOINT ["/go/goapp"] +EXPOSE 80 443 8080 diff --git a/Dockerfile-CICD.codebuild-4.0-amd64 b/Dockerfile-CICD.codebuild-4.0-amd64 new file mode 100644 index 00000000..15787a4e --- /dev/null +++ b/Dockerfile-CICD.codebuild-4.0-amd64 @@ -0,0 +1,138 @@ +### Builder ### +FROM golang:1.19.6-alpine3.17 as builder + +WORKDIR /go/src/app +ENV GIN_MODE=release +ENV GOPATH=/go + +RUN apk add --no-cache \ + build-base \ + git \ + curl \ + make \ + bash + +COPY src /go/src/app + +RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 \ + cd /go/src/app && \ + go build -mod=readonly -ldflags="-s -w" -o goapp + +### Binary ### +FROM devopscorner/cicd:codebuild-4.0 + +ARG BUILD_DATE +ARG BUILD_VERSION +ARG GIT_COMMIT +ARG GIT_URL + +ENV VENDOR="DevOpsCornerId" +ENV AUTHOR="DevOpsCorner.id " +ENV IMG_NAME="alpine" +ENV IMG_VERSION="4.0" +ENV IMG_DESC="Docker GO App with CodeBuild 4.0" +ENV IMG_ARCH="linux/amd64" + +ENV CODEBUILD_VERSION="4.0" +ENV GIN_MODE=release +ENV GOLANG_VERSION=1.19.6 +ENV APP_URL=${APP_URL:-http://localhost} +ENV APP_PORT=${APP_PORT:-8080} +ENV DB_CONNECTION=${DB_CONNECTION:-sqlite} +ENV DB_HOST=${DB_HOST:-localhost} +ENV DB_PORT=${DB_PORT} +ENV DB_DATABASE=${DB_DATABASE:-go-bookstore.db} +ENV DB_USERNAME=${DB_USERNAME:-root} +ENV DB_PASSWORD=${DB_PASSWORD} +ENV JWT_AUTH_USERNAME=${JWT_AUTH_USERNAME:-devopscorner} +ENV JWT_AUTH_PASSWORD=${JWT_AUTH_PASSWORD:-DevOpsCorner2023} +ENV JWT_SECRET=${JWT_SECRET:-s3cr3t} + +# Logger +ENV LOG_LEVEL=${LOG_LEVEL:-INFO} + +# AWS Credentials +ENV AWS_REGION=${AWS_REGION:-us-west-2} +ENV AWS_ACCESS_KEY=${AWS_ACCESS_KEY:-YOUR_AWS_ACCESS_KEY} +ENV AWS_SECRET_KEY_ID=${AWS_SECRET_KEY_ID:-YOUR_AWS_SECRET_KEY_ID} + +# OpenSearch +ENV OPENSEARCH_ENDPOINT=${OPENSEARCH_ENDPOINT:-https://opensearch.us-west-2.es.amazonaws.com} +ENV OPENSEARCH_USERNAME=${OPENSEARCH_USERNAME:-devopscorner} +ENV OPENSEARCH_PASSWORD=${OPENSEARCH_PASSWORD:-DevOpsCorner2023} + +# Prometheus +ENV PROMETHEUS_ENDPOINT=${PROMETHEUS_ENDPOINT:-http://localhost:9090} + +# Grafana +ENV GRAFANA_ENDPOINT=${GRAFANA_ENDPOINT:-http://localhost:3000} +ENV GRAFANA_API_KEY=${GRAFANA_API_KEY:-YOUR_GRAFANA_API_KEY} + +# OpenTelemetry +ENV OTEL_INSTRUMENTATION_METRIC_ENABLED=${OTEL_INSTRUMENTATION_METRIC_ENABLED:-true} +ENV OTEL_INSTRUMENTATION_TRACE_ENABLED=${OTEL_INSTRUMENTATION_TRACE_ENABLED:-true} +ENV OTEL_INSTRUMENTATION_LOG_ENABLED=${OTEL_INSTRUMENTATION_LOG_ENABLED:-true} +ENV OTEL_SERVICE_NAME=${OTEL_SERVICE_NAME:-bookstore-adot} +ENV OTEL_EXPORTER_OTLP_ENDPOINT=${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4317} +ENV OTEL_EXPORTER_OTLP_INSECURE=${OTEL_EXPORTER_OTLP_INSECURE:-true} +ENV OTEL_EXPORTER_OTLP_HEADERS=${OTEL_EXPORTER_OTLP_HEADERS} +ENV OTEL_RESOURCE_ATTRIBUTES=${OTEL_RESOURCE_ATTRIBUTES} + +# Jaeger +ENV JAEGER_AGENT_PORT=${JAEGER_AGENT_PORT:-6831} +ENV JAEGER_SAMPLER_TYPE=${JAEGER_SAMPLER_TYPE:-const} +ENV JAEGER_SAMPLER_PARAM=${JAEGER_SAMPLER_PARAM:-1} +ENV JAEGER_SAMPLER_MANAGER_HOST_PORT=${JAEGER_SAMPLER_MANAGER_HOST_PORT} +ENV JAEGER_REPORTER_LOG_SPANS=${JAEGER_REPORTER_LOG_SPANS:-true} +ENV JAEGER_REPORTER_BUFFER_FLUSH_INTERVAL=${JAEGER_REPORTER_BUFFER_FLUSH_INTERVAL:-5} +ENV JAEGER_REPORTER_MAX_QUEUE_SIZE=${JAEGER_REPORTER_MAX_QUEUE_SIZE:-100} +ENV JAEGER_REPORTER_LOCAL_AGENT_HOST_PORT=${JAEGER_REPORTER_LOCAL_AGENT_HOST_PORT} +ENV JAEGER_REPORTER_COLLECTOR_ENDPOINT=${JAEGER_REPORTER_COLLECTOR_ENDPOINT:-http://localhost:14268/api/traces} +ENV JAEGER_REPORTER_COLLECTOR_USER=${JAEGER_REPORTER_COLLECTOR_USER:-devopscorner} +ENV JAEGER_REPORTER_COLLECTOR_PASSWORD=${JAEGER_REPORTER_COLLECTOR_PASSWORD:-DevOpsCorner2023} +ENV JAEGER_TAGS=${JAEGER_TAGS:-golang,otel,restful,api,bookstore} + +# X-Ray +ENV XRAY_VERSION=${XRAY_VERSION:-latest} + +LABEL maintainer="$AUTHOR" \ + architecture="$IMG_ARCH" \ + codebuild-version="$CODEBUILD_VERSION" \ + org.label-schema.build-date="$BUILD_DATE" \ + org.label-schema.name="$IMG_NAME" \ + org.label-schema.description="$IMG_DESC" \ + org.label-schema.vcs-ref="$GIT_COMMIT" \ + org.label-schema.vcs-url="$GIT_URL" \ + org.label-schema.vendor="$VENDOR" \ + org.label-schema.version="$BUILD_VERSION" \ + org.label-schema.schema-version="$IMG_VERSION" \ + org.opencontainers.image.authors="$AUTHOR" \ + org.opencontainers.image.description="$IMG_DESC" \ + org.opencontainers.image.vendor="$VENDOR" \ + org.opencontainers.image.version="$IMG_VERSION" \ + org.opencontainers.image.revision="$GIT_COMMIT" \ + org.opencontainers.image.created="$BUILD_DATE" \ + fr.hbis.docker.base.build-date="$BUILD_DATE" \ + fr.hbis.docker.base.name="$IMG_NAME" \ + fr.hbis.docker.base.vendor="$VENDOR" \ + fr.hbis.docker.base.version="$BUILD_VERSION" + +USER root + +## Install Golang with GVM ## +RUN curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer | bash +RUN gvm install go${GOLANG_VERSION}; sync +RUN gvm use go${GOLANG_VERSION} --default; sync + +WORKDIR /go + +COPY --from=builder /go/src/app/goapp /go/goapp +COPY --from=devopscorner/k8s-context:latest /usr/local/bin/k8s-context /usr/local/bin/k8s-context +COPY --from=devopscorner/k8s-context:latest /usr/local/bin/kc /usr/local/bin/kc + +COPY src /go/src +COPY src/.env.example /go/.env +COPY entrypoint.sh /go/entrypoint + +# ENTRYPOINT ["/go/goapp"] +EXPOSE 80 443 8080 diff --git a/Dockerfile-amd64 b/Dockerfile-amd64 new file mode 100644 index 00000000..385ae042 --- /dev/null +++ b/Dockerfile-amd64 @@ -0,0 +1,143 @@ +### Builder ### +FROM golang:1.19.6-alpine3.17 as builder + +WORKDIR /go/src/app +ENV GIN_MODE=release +ENV GOPATH=/go + +RUN apk add --no-cache \ + build-base \ + git \ + curl \ + make \ + bash + +COPY src /go/src/app + +RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 \ + cd /go/src/app && \ + go build -mod=readonly -ldflags="-s -w" -o goapp + +### Binary ### +FROM golang:1.19.6-alpine3.17 + +ARG BUILD_DATE +ARG BUILD_VERSION +ARG GIT_COMMIT +ARG GIT_URL + +ENV VENDOR="DevOpsCornerId" +ENV AUTHOR="DevOpsCorner.id " +ENV IMG_NAME="alpine" +ENV IMG_VERSION="3.17" +ENV IMG_DESC="Docker GO App Alpine 3.17" +ENV IMG_ARCH="linux/amd64" + +ENV ALPINE_VERSION="3.17" +ENV GIN_MODE=release +ENV GOLANG_VERSION=1.19.6 +ENV APP_URL=${APP_URL:-http://localhost} +ENV APP_PORT=${APP_PORT:-8080} +ENV DB_CONNECTION=${DB_CONNECTION:-sqlite} +ENV DB_HOST=${DB_HOST:-localhost} +ENV DB_PORT=${DB_PORT} +ENV DB_DATABASE=${DB_DATABASE:-go-bookstore.db} +ENV DB_USERNAME=${DB_USERNAME:-root} +ENV DB_PASSWORD=${DB_PASSWORD} +ENV JWT_AUTH_USERNAME=${JWT_AUTH_USERNAME:-devopscorner} +ENV JWT_AUTH_PASSWORD=${JWT_AUTH_PASSWORD:-DevOpsCorner2023} +ENV JWT_SECRET=${JWT_SECRET:-s3cr3t} + +# Logger +ENV LOG_LEVEL=${LOG_LEVEL:-INFO} + +# AWS Credentials +ENV AWS_REGION=${AWS_REGION:-us-west-2} +ENV AWS_ACCESS_KEY=${AWS_ACCESS_KEY:-YOUR_AWS_ACCESS_KEY} +ENV AWS_SECRET_KEY_ID=${AWS_SECRET_KEY_ID:-YOUR_AWS_SECRET_KEY_ID} + +# OpenSearch +ENV OPENSEARCH_ENDPOINT=${OPENSEARCH_ENDPOINT:-https://opensearch.us-west-2.es.amazonaws.com} +ENV OPENSEARCH_USERNAME=${OPENSEARCH_USERNAME:-devopscorner} +ENV OPENSEARCH_PASSWORD=${OPENSEARCH_PASSWORD:-DevOpsCorner2023} + +# Prometheus +ENV PROMETHEUS_ENDPOINT=${PROMETHEUS_ENDPOINT:-http://localhost:9090} + +# Grafana +ENV GRAFANA_ENDPOINT=${GRAFANA_ENDPOINT:-http://localhost:3000} +ENV GRAFANA_API_KEY=${GRAFANA_API_KEY:-YOUR_GRAFANA_API_KEY} + +# OpenTelemetry +ENV OTEL_INSTRUMENTATION_METRIC_ENABLED=${OTEL_INSTRUMENTATION_METRIC_ENABLED:-true} +ENV OTEL_INSTRUMENTATION_TRACE_ENABLED=${OTEL_INSTRUMENTATION_TRACE_ENABLED:-true} +ENV OTEL_INSTRUMENTATION_LOG_ENABLED=${OTEL_INSTRUMENTATION_LOG_ENABLED:-true} +ENV OTEL_SERVICE_NAME=${OTEL_SERVICE_NAME:-bookstore-adot} +ENV OTEL_EXPORTER_OTLP_ENDPOINT=${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4317} +ENV OTEL_EXPORTER_OTLP_INSECURE=${OTEL_EXPORTER_OTLP_INSECURE:-true} +ENV OTEL_EXPORTER_OTLP_HEADERS=${OTEL_EXPORTER_OTLP_HEADERS} +ENV OTEL_RESOURCE_ATTRIBUTES=${OTEL_RESOURCE_ATTRIBUTES} + +# Jaeger +ENV JAEGER_AGENT_PORT=${JAEGER_AGENT_PORT:-6831} +ENV JAEGER_SAMPLER_TYPE=${JAEGER_SAMPLER_TYPE:-const} +ENV JAEGER_SAMPLER_PARAM=${JAEGER_SAMPLER_PARAM:-1} +ENV JAEGER_SAMPLER_MANAGER_HOST_PORT=${JAEGER_SAMPLER_MANAGER_HOST_PORT} +ENV JAEGER_REPORTER_LOG_SPANS=${JAEGER_REPORTER_LOG_SPANS:-true} +ENV JAEGER_REPORTER_BUFFER_FLUSH_INTERVAL=${JAEGER_REPORTER_BUFFER_FLUSH_INTERVAL:-5} +ENV JAEGER_REPORTER_MAX_QUEUE_SIZE=${JAEGER_REPORTER_MAX_QUEUE_SIZE:-100} +ENV JAEGER_REPORTER_LOCAL_AGENT_HOST_PORT=${JAEGER_REPORTER_LOCAL_AGENT_HOST_PORT} +ENV JAEGER_REPORTER_COLLECTOR_ENDPOINT=${JAEGER_REPORTER_COLLECTOR_ENDPOINT:-http://localhost:14268/api/traces} +ENV JAEGER_REPORTER_COLLECTOR_USER=${JAEGER_REPORTER_COLLECTOR_USER:-devopscorner} +ENV JAEGER_REPORTER_COLLECTOR_PASSWORD=${JAEGER_REPORTER_COLLECTOR_PASSWORD:-DevOpsCorner2023} +ENV JAEGER_TAGS=${JAEGER_TAGS:-golang,otel,restful,api,bookstore} + +# X-Ray +ENV XRAY_VERSION=${XRAY_VERSION:-latest} + +LABEL maintainer="$AUTHOR" \ + architecture="$IMG_ARCH" \ + alpine-version="$ALPINE_VERSION" \ + org.label-schema.build-date="$BUILD_DATE" \ + org.label-schema.name="$IMG_NAME" \ + org.label-schema.description="$IMG_DESC" \ + org.label-schema.vcs-ref="$GIT_COMMIT" \ + org.label-schema.vcs-url="$GIT_URL" \ + org.label-schema.vendor="$VENDOR" \ + org.label-schema.version="$BUILD_VERSION" \ + org.label-schema.schema-version="$IMG_VERSION" \ + org.opencontainers.image.authors="$AUTHOR" \ + org.opencontainers.image.description="$IMG_DESC" \ + org.opencontainers.image.vendor="$VENDOR" \ + org.opencontainers.image.version="$IMG_VERSION" \ + org.opencontainers.image.revision="$GIT_COMMIT" \ + org.opencontainers.image.created="$BUILD_DATE" \ + fr.hbis.docker.base.build-date="$BUILD_DATE" \ + fr.hbis.docker.base.name="$IMG_NAME" \ + fr.hbis.docker.base.vendor="$VENDOR" \ + fr.hbis.docker.base.version="$BUILD_VERSION" + +RUN apk add --no-cache \ + build-base \ + git \ + curl \ + make \ + bash; sync + +## Install Golang with GVM ## +RUN curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer | bash +RUN gvm install go${GOLANG_VERSION}; sync +RUN gvm use go${GOLANG_VERSION} --default; sync + +WORKDIR /go + +COPY --from=builder /go/src/app/goapp /go/goapp +COPY --from=devopscorner/k8s-context:latest /usr/local/bin/k8s-context /usr/local/bin/k8s-context +COPY --from=devopscorner/k8s-context:latest /usr/local/bin/kc /usr/local/bin/kc + +COPY src /go/src +COPY src/.env.example /go/.env +COPY entrypoint.sh /go/entrypoint + +ENTRYPOINT ["/go/goapp"] +EXPOSE 80 443 8080 diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..4268ad4b --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020-2023 DevOpsCorner Indonesia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..e69b8e23 --- /dev/null +++ b/Makefile @@ -0,0 +1,207 @@ +# ----------------------------------------------------------------------------- +# MAKEFILE RUNNING COMMAND +# ----------------------------------------------------------------------------- +# Author : DevOps Engineer (support@devopscorner.id) +# License : Apache v2 +# ----------------------------------------------------------------------------- +# Notes: +# use [TAB] instead [SPACE] + +export PATH_DOCKER="." +export PROJECT_NAME="bookstore-adot" +export AWS_DEFAULT_REGION="us-west-2" +export TF_PATH="terraform/environment/providers/aws/infra" +export TF_CORE="$(TF_PATH)/core" +export TF_RESOURCES="$(TF_PATH)/resources" +export TF_STATE="$(TF_PATH)/tfstate" + +export TF_MODULES="terraform/modules/providers/aws" + +export CI_REGISTRY ?= $(ARGS).dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com +export CI_PROJECT_PATH ?= devopscorner +export CI_PROJECT_NAME ?= bookstore-adot + +IMAGE = $(CI_REGISTRY)/${CI_PROJECT_PATH}/${CI_PROJECT_NAME} +DIR = $(shell pwd) +VERSION ?= 1.7.0 + +export BASE_IMAGE=alpine +export BASE_VERSION=3.17 +export ALPINE_VERSION=3.17 + +GO_APP ?= bookstore-adot +SOURCES = $(shell find . -name '*.go' | grep -v /vendor/) +VERSION ?= $(shell git describe --tags --always --dirty) +GOPKGS = $(shell go list ./ | grep -v /vendor/) +BUILD_FLAGS ?= +LDFLAGS ?= -X github.com/devopscorner/golang-adot/src/config.Version=$(VERSION) -w -s +TAG ?= "v0.3.0" +GOARCH ?= amd64 +GOOS ?= linux +GO111MODULE ?= on + +export PATH_APP=`pwd` + +# ========================= # +# BUILD GO APP (Binary) # +# ========================= # +.PHONY: build + +default: build + +test.race: + go test -v -race -count=1 `go list ./...` + +test: + go test -v -count=1 `go list ./...` + +fmt: + go fmt $(GOPKGS) + +check: + golint $(GOPKGS) + go vet $(GOPKGS) + +# build: build/$(BINARY) + +# build/$(BINARY): $(SOURCES) +# GO111MODULE=$(GO111MODULE) GOOS=$(GOOS) GOARCH=$(GOARCH) CGO_ENABLED=0 go build -o build/$(BINARY) $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" . + +tag: + git tag $(TAG) + +build: + @echo "============================================" + @echo " Task : Build Binary GO APP " + @echo " Date/Time : `date`" + @echo "============================================" + @echo ">> Build GO Apps... " + @echo ">> GO111MODULE=$(GO111MODULE) GOOS=$(GOOS) GOARCH=$(GOARCH) CGO_ENABLED=0 go build -o build/$(GO_APP) $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" ./main.go" + @cd src && GO111MODULE=$(GO111MODULE) GOOS=$(GOOS) GOARCH=$(GOARCH) CGO_ENABLED=0 go build -o build/$(GO_APP) $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" ./main.go + @echo '- DONE -' + +build-mac-amd: + @echo "============================================" + @echo " Task : Build Binary GO APP " + @echo " Date/Time : `date`" + @echo "============================================" + @echo ">> Build GO Apps... " + @echo ">> GO111MODULE=$(GO111MODULE) GOOS=darwin GOARCH=amd64 go build -o build/$(GO_APP) $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" ./main.go" + @cd src && GO111MODULE=$(GO111MODULE) GOOS=darwin GOARCH=amd64 go build -o build/$(GO_APP) $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" ./main.go + @echo '- DONE -' + +build-mac-arm: + @echo "============================================" + @echo " Task : Build Binary GO APP " + @echo " Date/Time : `date`" + @echo "============================================" + @echo ">> Build GO Apps... " + @echo ">> GO111MODULE=$(GO111MODULE) GOOS=darwin GOARCH=arm64 go build -o build/$(GO_APP) $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" ./main.go" + @cd src && GO111MODULE=$(GO111MODULE) GOOS=darwin GOARCH=arm64 go build -o build/$(GO_APP) $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" ./main.go + @echo '- DONE -' + +# =============== # +# GET MODULES # +# =============== # +.PHONY: sub-officials sub-community sub-all codebuild-modules +sub-officials: + @echo "============================================================" + @echo " Task : Get Official Submodules " + @echo " Date/Time : `date` " + @echo "============================================================" + @mkdir -p $(TF_MODULES)/officials + @cd $(PATH_APP) && ./get-officials.sh + +sub-community: + @echo "============================================================" + @echo " Task : Get Community Submodules " + @echo " Date/Time : `date` " + @echo "============================================================" + @mkdir -p $(TF_MODULES)/community + @cd $(PATH_APP) && ./get-community.sh + +sub-all: + @make sub-officials + @echo '' + @make sub-community + @echo '' + @echo '---' + @echo '- ALL DONE -' + +codebuild-modules: + @echo "============================================================" + @echo " Task : Get CodeBuild Modules " + @echo " Date/Time : `date` " + @echo "============================================================" + @./get-modules-codebuild.sh + +# ==================== # +# CLONE REPOSITORY # +# ==================== # +.PHONY: git-clone +git-clone: + @echo "=================================================" + @echo " Task : Clone Repository Sources " + @echo " Date/Time : `date`" + @echo "=================================================" + @sh ./git-clone.sh $(SOURCE) $(TARGET) + @echo '- DONE -' + +# ========================== # +# BUILD CONTAINER GO-APP # +# ========================== # +.PHONY: dockerhub-build-alpine ecr-build-alpine +# ./dockerhub-build.sh Dockerfile [DOCKERHUB_IMAGE_PATH] [alpine] [version|latest|tags] [custom-tags] +dockerhub-build-alpine: + @echo "========================================================" + @echo " Task : Create Container GO-APP Alpine Image " + @echo " Date/Time : `date`" + @echo "========================================================" + @sh ./dockerhub-build.sh Dockerfile $(CI_PATH) alpine ${ALPINE_VERSION} + +# ./ecr-build.sh [AWS_ACCOUNT] Dockerfile [ECR_PATH] [alpine] [version|latest|tags] [custom-tags] +ecr-build-alpine: + @echo "========================================================" + @echo " Task : Create Container GO-APP Alpine Image " + @echo " Date/Time : `date`" + @echo "========================================================" + @sh ./ecr-build.sh $(ARGS) Dockerfile $(CI_PATH) alpine ${ALPINE_VERSION} + +# ========================= # +# TAGS CONTAINER GO-APP # +# ========================= # +.PHONY: tag-dockerhub-alpine tag-ecr-alpine +# ./dockerhub-tag.sh [DOCKERHUB_IMAGE_PATH] [alpine] [version|latest|tags] [custom-tags] +dockerhub-tag-alpine: + @echo "========================================================" + @echo " Task : Set Tags Image Alpine to DockerHub" + @echo " Date/Time : `date`" + @echo "========================================================" + @sh ./dockerhub-tag.sh $(CI_PATH) alpine ${ALPINE_VERSION} + +# ./ecr-tag.sh [AWS_ACCOUNT] [ECR_PATH] [alpine|codebuild] [version|latest|tags] [custom-tags] +ecr-tag-alpine: + @echo "========================================================" + @echo " Task : Set Tags Image Alpine to ECR" + @echo " Date/Time : `date`" + @echo "========================================================" + @sh ./ecr-tag.sh $(ARGS) $(CI_PATH) alpine ${ALPINE_VERSION} + +# ========================= # +# PUSH CONTAINER GO-APP # +# ========================= # +.PHONY: dockerhub-push-alpine ecr-push-alpine +# ./dockerhub-push.sh [DOCKERHUB_IMAGE_PATH] [alpine|version|latest|tags|custom-tags] +dockerhub-push-alpine: + @echo "========================================================" + @echo " Task : Push Image Alpine to DockerHub" + @echo " Date/Time : `date`" + @echo "========================================================" + @sh ./dockerhub-push.sh $(CI_PATH) alpine + +ecr-push-alpine: + @echo "========================================================" + @echo " Task : Push Image Alpine to ECR" + @echo " Date/Time : `date`" + @echo "========================================================" + @sh ./ecr-push.sh $(ARGS) $(CI_PATH) alpine diff --git a/README.md b/README.md new file mode 100644 index 00000000..ec8ff98d --- /dev/null +++ b/README.md @@ -0,0 +1,346 @@ +# Golang Bookstore ADOT + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +![goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![download latest](https://img.shields.io/github/downloads/devopscorner/golang-adot/0.1/total) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Available Tags + +### Alpine GOLANG + +| Image name | Size | +|------------|------| +| `devopscorner/bookstore-adot:latest` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/latest.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=latest) ![default-latest](https://img.shields.io/static/v1?label=latest&message=default&color=brightgreen) ![latest](https://img.shields.io/static/v1?label=latest&message=alpine&color=orange) | +| `devopscorner/bookstore-adot:alpine` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/alpine.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=alpine) ![latest](https://img.shields.io/static/v1?label=latest&message=alpine&color=orange) | +| `devopscorner/bookstore-adot:alpine-latest` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/alpine-latest.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=alpine-latest) | +| `devopscorner/bookstore-adot:alpine-3.17` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/alpine-3.17.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=alpine-3.17) | + +### CICD Alpine-3.17 + +| Image name | Size | +|------------|------| +| `devopscorner/bookstore-adot:cicd-alpine` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-alpine.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-alpine) | +| `devopscorner/bookstore-adot:cicd-alpine-latest` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-alpine-latest.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-alpine-latest) | +| `devopscorner/bookstore-adot:cicd-alpine-3.17` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-alpine-3.17.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-alpine-3.17) | + +### CICD CodeBuild-4.0 + +| Image name | Size | +|------------|------| +| `devopscorner/bookstore-adot:cicd-codebuild` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-codebuild.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-codebuild) ![default-cicd-codebuild](https://img.shields.io/static/v1?label=latest&message=default&color=brightgreen) ![cicd-codebuild](https://img.shields.io/static/v1?label=latest&message=cicd-codebuild&color=orange) | +| `devopscorner/bookstore-adot:cicd-codebuild-latest` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-codebuild-latest.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-codebuild-latest) | +| `devopscorner/bookstore-adot:cicd-codebuild-4.0` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-codebuild-4.0.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-codebuild-4.0) | +| `devopscorner/bookstore-adot:cicd-latest` | [![docker image size](https://img.shields.io/docker/image-size/devopscorner/bookstore-adot/cicd-latest.svg?label=Image%20size&logo=docker)](https://hub.docker.com/repository/docker/devopscorner/bookstore-adot/tags?page=1&ordering=last_updated&name=cicd-latest) ![cicd-latest](https://img.shields.io/static/v1?label=latest&message=cicd-codebuild&color=orange) | + +--- + +## Documentation + +- Index Documentation, go to [this](docs/README.md) link +- Build, Tag & Push container image to **DockerHub**, go to [this](docs/container-bookstore-adot-dockerhub.md) link +- Build, Tag & Push container image to **Amazon ECR (Elastic Container Registry)**, go to [this](docs/container-bookstore-adot-ecr.md) link +- Workflow CI/CD Pipeline, go to [this](docs/workflow-cicd-bookstore-adot-pipeline.md) link +- Deployments: + - **AWS Developer Tools** (AWS CodeCommit, AWS CodeBuild & AWS CodePipeline), detail [here](docs/deployment-aws-developer-tools.md) link + - **Jenkins CI/CD**, detail [here](docs/deployment-jenkins.md) link + - **Terraform AWS CodeBuild, AWS CodePipeline & Amazon SNS**, detail [here](docs/deployment-terraform.md) link + + +## GO Repository Pattern + +- Folder Structure + ``` + . + ├── .env + ├── .env.example + ├── config + │   ├── config.go + │   ├── config_test.go + │   ├── const.go + │   ├── logger.go + │   └── value.go + ├── controller + │   ├── book_controller.go + │   ├── book_controller_test.go + │   ├── login_controller.go + │   └── login_controller_test.go + ├── driver + │   ├── db.go + │   ├── dynamo.go + │   ├── mysql.go + │   ├── psql.go + │   └── sqlite.go + ├── dynamodb-golang-adot + ├── go.mod + ├── go.sum + ├── main.go + ├── main_test.go + ├── middleware + │   ├── auth_middleware.go + │   └── auth_middleware_test.go + ├── migrate_book.go.example + ├── migrate_book_dynamo.go.example + ├── model + │   └── book.go + ├── observability + │   ├── metrics.go + │   ├── provider.go + │   └── xray.go + ├── repository + │   └── book_repository.go + ├── routes + │   ├── book_routes.go + │   ├── main_routes.go + │   └── telemetry_routes.go + └── view + ├── book_view.go + ├── error_view.go + └── login_view.go + + 10 directories, 36 files + ``` + +## Coverages: +### AWS Services +- Amazon Elastic Container Registry (ECR) +- Amazon Managed Service for Prometheus (AMP) +- Amazon Managed Service for Grafana (AMG) +- AWS Distro for OpenTelemetry (ADOT) +- AWS CloudWatch +- AWS X-Ray +- AWS Systems Manager Parameter Store +- AWS Developer Tools (AWS CodeCommit, AWS CodePipeline, AWS CodeBuild) +- Amazon EKS +- Amazon OpenSearch +- Amazon DynamoDB + +### Others: +- Docker +- Docker-Compose +- Golang +- HelmChart +- Postman +- Terraform + +## Environment Variables + +- Default Value + ``` + GIN_MODE=release + APP_URL=http://localhost + APP_PORT=8080 + DB_CONNECTION=dynamo + DB_HOST=localhost + DB_PORT= + DB_DATABASE=dynamodb-golang-adot + DB_USERNAME=root + DB_PASSWORD= + JWT_AUTH_USERNAME=devopscorner + JWT_AUTH_PASSWORD=DevOpsCorner2023 + JWT_SECRET=s3cr3t + ``` + +- Multi Driver Connection + ``` + # default + DB_CONNECTION=dynamo + --- + Available for: + - sqlite + - mysql + - postgres + - dynamo + ``` + +- DynamoDB Connection + ``` + DB_CONNECTION=dynamo + --- + DB_DATABASE --> Dynamo Table + AWS_REGION --> AWS Region (Dynamo Region) + AWS_ACCESS_KEY --> AWS Access Key + AWS_SECRET_KEY_ID --> AWS Secret Key Id + ``` + +- AWS X-Ray (AWS Distribution Tracing System) + - `XRAY_VERSION`: Daemon Version X-Ray + - `latest`: Use the latest version of the AWS X-Ray daemon available. + - `3.x`: Use version 3.x of the AWS X-Ray daemon. + - `2.x`: Use version 2.x of the AWS X-Ray daemon. + - `1.x`: Use version 1.x of the AWS X-Ray daemon. + + - `XRAY_DAEMON_ENDPOINT: Daemon Endpoint of X-Ray + ``` + XRAY_DAEMON_ENDPOINT=http://localhost:2000 + ``` + - `XRAY_DAEMON_PORT: Daemon Endpoint Port of X-Ray + ``` + XRAY_DAEMON_PORT=2000 + ``` + +- Prometheus + ``` + PROMETHEUS_ENDPOINT=http://localhost:9090 + PROMETHEUS_PORT=9090 + ``` + +- Grafana + ``` + GRAFANA_ENDPOINT=http://localhost:3000 + GRAFANA_API_KEY=YOUR_GRAFANA_API_KEY + ``` + +- OpenTelemetry + ``` + OTEL_INSTRUMENTATION_METRIC_ENABLED=true + OTEL_INSTRUMENTATION_TRACE_ENABLED=true + OTEL_INSTRUMENTATION_LOG_ENABLED=true + + # Trace Type: xray / jaeger + OTEL_INSTRUMENTATION_TRACE_NAME=xray + + OTEL_SERVICE_NAME=bookstore-adot + OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 + OTEL_EXPORTER_OTLP_PORT=4317 + OTEL_EXPORTER_OTLP_INSECURE=true + OTEL_EXPORTER_OTLP_HEADERS= + OTEL_RESOURCE_ATTRIBUTES= + ``` + +- Jaeger Environment + - `JAEGER_SERVICE_NAME`: The name of the service being instrumented (`JAEGER_SERVICE_NAME` = `OTEL_SERVICE_NAME`). + - `JAEGER_AGENT_HOST`: The host name or IP address of the Jaeger agent to use for sending trace data. + - `JAEGER_AGENT_PORT`: The port number of the Jaeger agent to use for sending trace data. + - `JAEGER_SAMPLER_TYPE`: The type of sampling to use for tracing (e.g. const, probabilistic, rateLimiting, remote). + - `JAEGER_SAMPLER_PARAM`: The parameter value to use for the selected sampler type. + - `JAEGER_SAMPLER_MANAGER_HOST_PORT`: The host name and port of the remote sampling manager to use (if using remote sampling). + - `JAEGER_REPORTER_LOG_SPANS`: Whether to log spans instead of sending them to a Jaeger agent (e.g. true or false). + - `JAEGER_REPORTER_MAX_QUEUE_SIZE`: The maximum number of spans that can be queued before they are sent to a Jaeger agent. + - `JAEGER_REPORTER_FLUSH_INTERVAL`: The interval at which to flush the span queue and send spans to a Jaeger agent (e.g. 1 * time.Second). + - `JAEGER_REPORTER_LOCAL_AGENT_HOST_PORT`: The host and port of the local Jaeger agent, if using UDP instead of HTTP. + - `JAEGER_REPORTER_COLLECTOR_ENDPOINT`: The endpoint URL of the Jaeger collector (e.g. `http://localhost:14268/api/traces`). + - `JAEGER_REPORTER_COLLECTOR_USER`: The username for authenticating with the Jaeger collector, if required. + - `JAEGER_REPORTER_COLLECTOR_PASSWORD`: The password for authenticating with the Jaeger collector, if required. + - `JAEGER_TAGS`: Additional tags to attach to the trace (e.g. key1=value1,key2=value2). + + +## Reproduce Testing + +- RESTful API Testing, go to [this](docs/test-restful-api.md) link + +## Reproduce Provisioning + 1. Install Terraform Modules, detail [here](docs/reproduce-01-teraform-modules.md) + 2. Provisioning HelmChart Template, detail [here](docs/reproduce-02-helm-template.md) + 3. Provisioning TFState DB & Bucket, detail [here](docs/reproduce-03-provisioning-tfstate-db-bucket.md) + 4. Provisioning Infra Core, detail [here](docs/reproduce-04-provisioning-infra-core.md) + 5. Provisioning Infra CI/CD, detail [here](docs/reproduce-05-provisioning-infra-cicd.md) + 6. Provisioning Resources Amazon EKS, detail [here](docs/reproduce-06-provisioning-resources-eks.md) + 7. Provisioning Resources Managed Services Prometheus (AMP), detail [here](docs/reproduce-07-provisioning-resources-amp.md) + 8. Provisioning Resources Managed Services Grafana (AMG), detail [here](docs/reproduce-08-provisioning-resources-amg.md) + 9. Provisioning Resources Managed Services OpenSearch, detail [here](docs/reproduce-09-provisioning-resources-opensearch.md) + +## Tested Environment + +### Versioning + +- Docker version + + ``` + docker version + + Client: + Cloud integration: v1.0.22 + Version: 20.10.17-rd + API version: 1.41 + Go version: go1.17.11 + Git commit: c2e4e01 + Built: Fri Jul 22 18:31:17 2022 + OS/Arch: darwin/amd64 + Context: default + Experimental: true + ``` + +- Docker-Compose version + + ``` + docker-compose -v + --- + Docker Compose version v2.11.1 + ``` + +- AWS Cli + + ``` + aws --version + --- + aws-cli/2.8.7 Python/3.9.11 Darwin/21.6.0 exe/x86_64 prompt/off + ``` + +- Terraform Cli + + ``` + terraform version + --- + Terraform v1.3.5 + on darwin_amd64 + - provider registry.terraform.io/hashicorp/aws v3.74.3 + - provider registry.terraform.io/hashicorp/local v2.1.0 + - provider registry.terraform.io/hashicorp/null v3.1.0 + - provider registry.terraform.io/hashicorp/random v3.1.0 + - provider registry.terraform.io/hashicorp/time v0.7.2 + ``` + +- Terraform Environment Cli + + ``` + tfenv -v + --- + tfenv 2.2.2 + ``` + +- Golang Version Manager (GVM) + + ``` + gvm version + --- + Go Version Manager v1.0.22 installed at /Users/devopscorner/.gvm + ``` + +- Golang Version + ``` + go version + --- + go version go1.19.6 darwin/arm64 + ``` + +## Security Check + +Make sure that you didn't push sensitive information in this repository + +- [ ] AWS Credentials (AWS_ACCESS_KEY, AWS_SECRET_KEY) +- [ ] AWS Account ID +- [ ] AWS Resources ARN +- [ ] Username & Password +- [ ] Private (id_rsa) & Public Key (id_rsa.pub) +- [ ] DNS Zone ID +- [ ] APP & API Key + +## Copyright + +- Author: **Dwi Fahni Denni (@zeroc0d3)** +- Vendor: **DevOps Corner Indonesia (devopscorner.id)** +- License: **Apache v2** diff --git a/_infra/helm/dev/api-rest-values.yml b/_infra/helm/dev/api-rest-values.yml new file mode 100644 index 00000000..71bb59ff --- /dev/null +++ b/_infra/helm/dev/api-rest-values.yml @@ -0,0 +1,110 @@ +replicaCount: 1 + +secret: + enabled: false + +configMap: + enabled: true + name: "bookstore-adot-rest-api" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "GO App", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + .env : |- + export GIN_MODE=release + +image: + repository: YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot + pullPolicy: Always + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "bookstore-adot-rest" + +serviceAccount: + create: true + annotations: {} + name: bookstore-adot-rest + namespace: devops-tools + +service: + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +container: + ports: + - name: http + containerPort: 8080 + protocol: TCP + +ingress: + enabled: true + annotations: + nginx.ingress.kubernetes.io/cors-allow-headers: '*' + nginx.ingress.kubernetes.io/cors-allow-methods: '*' + nginx.ingress.kubernetes.io/cors-allow-origin: '*' + nginx.ingress.kubernetes.io/enable-cors: "true" + nginx.ingress.kubernetes.io/affinity: cookie + nginx.ingress.kubernetes.io/from-to-www-redirect: "true" + kubernetes.io/ingress.class: nginx + ingress.kubernetes.io/whitelist-source-range: 32.0.0.0/32 + hosts: + #- host: bookstore-adot-rest.awscb.id + - host: bookstore-adot-rest.devops-tools.svc.cluster.local + http: + paths: + - path: / + backend: + serviceName: bookstore-adot-rest + servicePort: 80 + tls: [] + + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: api + +resources: + limits: + cpu: 200m + memory: 300Mi + requests: + cpu: 100m + memory: 150Mi + +autoscaling: + enabled: true + minReplicas: 1 + maxReplicas: 4 + targetCPUUtilizationPercentage: 80 + targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "devops-tools" + +tolerations: [] + +affinity: {} + +podAnnotations: {} + +podSecurityContext: {} + +securityContext: {} diff --git a/_infra/helm/dev/helm-template.yml b/_infra/helm/dev/helm-template.yml new file mode 100644 index 00000000..dd69b2d1 --- /dev/null +++ b/_infra/helm/dev/helm-template.yml @@ -0,0 +1,22 @@ +--- +repositories: + - name: devopscorner-adot-lab + url: s3://devopscorner-adot-chart/lab + +templates: + default: &default + namespace: devops-tools + version: "1.4.0-rc" + +releases: + - name: bookstore-adot-rest + chart: devopscorner-adot-lab/api + values: + - ./api-rest-values.yml + <<: *default + + - name: bookstore-adot-grpc + chart: devopscorner-adot-lab/api + values: + - ./api-grpc-values.yml + <<: *default \ No newline at end of file diff --git a/_infra/iam/ecr-codebuild-permission.json b/_infra/iam/ecr-codebuild-permission.json new file mode 100644 index 00000000..78e1a063 --- /dev/null +++ b/_infra/iam/ecr-codebuild-permission.json @@ -0,0 +1,35 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "CodeBuildAccessPrincipal", + "Effect": "Allow", + "Principal": { + "Service": "codebuild.amazonaws.com" + }, + "Action": [ + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage", + "ecr:BatchCheckLayerAvailability" + ], + "Condition": { + "StringEquals": { + "aws:SourceArn": "arn:aws:codebuild:us-west-2:YOUR_AWS_ACCOUNT:project/*", + "aws:SourceAccount": "YOUR_AWS_ACCOUNT" + } + } + }, + { + "Sid": "CodeBuildAccessCrossAccount", + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::YOUR_AWS_ACCOUNT:root" + }, + "Action": [ + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage", + "ecr:BatchCheckLayerAvailability" + ] + } + ] +} \ No newline at end of file diff --git a/_infra/iam/policy-cicd.json b/_infra/iam/policy-cicd.json new file mode 100644 index 00000000..53bc848c --- /dev/null +++ b/_infra/iam/policy-cicd.json @@ -0,0 +1,55 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "AllowAccess", + "Effect": "Allow", + "Action": [ + "codecommit:CancelUploadArchive", + "codecommit:GetBranch", + "codecommit:GetCommit", + "codecommit:GetUploadArchiveStatus", + "codecommit:UploadArchive", + "codecommit:GetBranch", + "codedeploy:CreateDeployment", + "codedeploy:GetApplication", + "codedeploy:GetApplicationRevision", + "codedeploy:GetDeployment", + "codedeploy:GetDeploymentConfig", + "codedeploy:RegisterApplicationRevision", + "ecr:GetAuthorizationToken", + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + "ecr:GetRepositoryPolicy", + "ecr:DescribeRepositories", + "ecr:ListImages", + "ecr:DescribeImages", + "ecr:BatchGetImage", + "ecr:GetLifecyclePolicy", + "ecr:GetLifecyclePolicyPreview", + "ecr:ListTagsForResource", + "ecr:DescribeImageScanFindings", + "lambda:InvokeFunction", + "lambda:ListFunctions", + "servicecatalog:ListProvisioningArtifacts", + "servicecatalog:CreateProvisioningArtifact", + "servicecatalog:DescribeProvisioningArtifact", + "servicecatalog:DeleteProvisioningArtifact", + "servicecatalog:UpdateProduct" + ], + "Resource": [ + "arn:aws:ecr:us-west-2:YOUR_AWS_ACCOUNT:repository/*" + ] + }, + { + "Effect": "Allow", + "Action": "kms:*", + "Resource": "*", + "Condition": { + "StringEquals": { + "kms:KeySpec": "SYMMETRIC_DEFAULT" + } + } + } + ] +} \ No newline at end of file diff --git a/_infra/iam/policy-kms-GenerateDataKey.json b/_infra/iam/policy-kms-GenerateDataKey.json new file mode 100644 index 00000000..43668e38 --- /dev/null +++ b/_infra/iam/policy-kms-GenerateDataKey.json @@ -0,0 +1,13 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": ["kms:GenerateDataKey"], + "Resource": [ + "arn:aws:kms:us-west-2:YOUR_AWS_ACCOUNT:key/CMK_STAGING_HASH_ID", + "arn:aws:kms:us-west-2:YOUR_AWS_ACCOUNT:key/CMK_PROD_HASH_ID" + ] + } + ] +} diff --git a/_infra/iam/policy-kms.json b/_infra/iam/policy-kms.json new file mode 100644 index 00000000..8191f018 --- /dev/null +++ b/_infra/iam/policy-kms.json @@ -0,0 +1,15 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "kms:*", + "Resource": "*", + "Condition": { + "StringEquals": { + "kms:KeySpec": "SYMMETRIC_DEFAULT" + } + } + } + ] +} \ No newline at end of file diff --git a/clone.json b/clone.json new file mode 100644 index 00000000..17a5c315 --- /dev/null +++ b/clone.json @@ -0,0 +1,81 @@ +{ + "count": 4478, + "uniques": 377, + "clones": [ + { + "timestamp": "2023-03-12T00:00:00Z", + "count": 85, + "uniques": 62 + }, + { + "timestamp": "2023-03-13T00:00:00Z", + "count": 316, + "uniques": 145 + }, + { + "timestamp": "2023-03-14T00:00:00Z", + "count": 282, + "uniques": 137 + }, + { + "timestamp": "2023-03-15T00:00:00Z", + "count": 318, + "uniques": 152 + }, + { + "timestamp": "2023-03-16T00:00:00Z", + "count": 316, + "uniques": 155 + }, + { + "timestamp": "2023-03-17T00:00:00Z", + "count": 332, + "uniques": 133 + }, + { + "timestamp": "2023-03-18T00:00:00Z", + "count": 344, + "uniques": 135 + }, + { + "timestamp": "2023-03-19T00:00:00Z", + "count": 370, + "uniques": 155 + }, + { + "timestamp": "2023-03-20T00:00:00Z", + "count": 337, + "uniques": 153 + }, + { + "timestamp": "2023-03-21T00:00:00Z", + "count": 322, + "uniques": 152 + }, + { + "timestamp": "2023-03-22T00:00:00Z", + "count": 308, + "uniques": 140 + }, + { + "timestamp": "2023-03-23T00:00:00Z", + "count": 305, + "uniques": 143 + }, + { + "timestamp": "2023-03-24T00:00:00Z", + "count": 306, + "uniques": 133 + }, + { + "timestamp": "2023-03-25T00:00:00Z", + "count": 306, + "uniques": 128 + }, + { + "timestamp": "2023-03-26T00:00:00Z", + "count": 231, + "uniques": 123 + } + ] +} diff --git a/docker-compose-monitoring.yml b/docker-compose-monitoring.yml new file mode 100644 index 00000000..796aadd4 --- /dev/null +++ b/docker-compose-monitoring.yml @@ -0,0 +1,174 @@ +version: '3.7' + +#================================================================================================ +# NETWORK SETUP +#================================================================================================ +networks: + devopscorner_net: + name: devopscorner_net + driver: bridge + ipam: + config: + - subnet: 172.148.0.0/16 + +#================================================================================================ +# VOLUME SETUP +#================================================================================================ +volumes: + vol_portainer: + driver: ${VOLUMES_DRIVER:-local} + driver_opts: + o: bind + type: none + device: ${DATA_PORTAINER:-/opt/data/docker/portainer2.9} + vol_go_bookstore_adot: + driver: ${VOLUMES_DRIVER:-local} + driver_opts: + o: bind + type: none + device: ${DATA_GO_BOOKSTORE_ADOT:-/opt/data/docker/go-bookstore-adot} + vol_prometheus_adot: + driver: ${VOLUMES_DRIVER:-local} + driver_opts: + o: bind + type: none + device: ${DATA_PROMETHEUS_ADOT:-/opt/data/docker/prometheus-adot} + +services: + #================================================================================================ + # PORTAINER + #================================================================================================ + portainer: + image: dockerframework/portainer:${PORTAINER_VERSION:-2.9} + container_name: ${CONTAINER_PORTAINER:-devopscorner_portainer} + restart: unless-stopped + ports: + - "${PORT_PORTAINER:-5212}:9000" + volumes: + # - /etc/localtime:/etc/localtime:ro ## Do not use it in mac + - /var/run/docker.sock:/var/run/docker.sock ## Do not use it in k8s + - vol_portainer:/data + environment: + - PORTAINER_TEMPLATE=generic + - PORTAINER_VERSION=${PORTAINER_VERSION:-2.9} + privileged: true + networks: + devopscorner_net: + ipv4_address: ${CONTAINER_IP_PORTAINER:-172.148.148.5} + + #================================================================================================ + # PROMETHEUS + #================================================================================================ + prometheus: + image: prom/prometheus:v2.43.0 + container_name: ${CONTAINER_PROMETHEUS_ADOT:-devopscorner_prometheus} + restart: unless-stopped + volumes: + - ./docker/config/prometheus/alert.rules:/etc/prometheus/alert.rules + - ./docker/config/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml + - vol_prometheus_adot:/prometheus + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + - '--web.console.libraries=/etc/prometheus/console_libraries' + - '--web.console.templates=/etc/prometheus/consoles' + - '--storage.tsdb.retention=200h' + - '--web.enable-lifecycle' + ports: + - "${PORT_PROMETHEUS}:9090" + networks: + devopscorner_net: + ipv4_address: ${CONTAINER_IP_PROMETHEUS_ADOT:-172.148.148.226} + + #================================================================================================ + # ALERTMANAGER + #================================================================================================ + alertmanager: + image: prom/alertmanager:v0.25.0 + restart: unless-stopped + container_name: ${CONTAINER_ALERTMANAGER_ADOT:-devopscorner_alertmanager} + volumes: + - ./docker/config/alertmanager/:/etc/alertmanager/ + command: + - '--config.file=/etc/alertmanager/config.yml' + - '--storage.path=/alertmanager' + ports: + - "${PORT_ALERTMANAGER}:9093" + networks: + devopscorner_net: + ipv4_address: ${CONTAINER_IP_ALERTMANAGER_ADOT:-172.148.148.227} + + #================================================================================================ + # GOLANG-BOOKSTORE-ADOT + #================================================================================================ + go-bookstore-adot: + build: + context: . + dockerfile: Dockerfile-amd64 + container_name: ${CONTAINER_GO_BOOKSTORE_ADOT:-devopscorner_go_bookstore_adot} + restart: unless-stopped + ports: + - "${PORT_GO_BOOKSTORE_ADOT:-8080}:8080" + volumes: + # - /etc/localtime:/etc/localtime:ro ## Do not use it in mac + - /var/run/docker.sock:/var/run/docker.sock ## Do not use it in k8s + environment: + - TZ="Asia/Jakarta" + - ALPINE_VERSION=${ALPINE_VERSION:-3.17} + - CODEBUILD_VERSION=${CODEBUILD_VERSION:-4.0} + - GIN_MODE=release + - APP_URL=${APP_URL:-http://localhost} + - APP_PORT=${APP_PORT:-8080} + - DB_CONNECTION=${DB_CONNECTION:-sqlite} + - DB_HOST=${DB_HOST:-localhost} + - DB_PORT=${DB_PORT} + - DB_DATABASE=${DB_DATABASE:-go-bookstore.db} + - DB_USERNAME=${DB_USERNAME:-root} + - DB_PASSWORD=${DB_PASSWORD} + - JWT_AUTH_USERNAME=${JWT_AUTH_USERNAME:-devopscorner} + - JWT_AUTH_PASSWORD=${JWT_AUTH_PASSWORD:-DevOpsCorner2023} + - JWT_SECRET=${JWT_SECRET:-s3cr3t} + # Logger + - LOG_LEVEL=${LOG_LEVEL:-INFO} + # AWS Credentials + - AWS_REGION=${AWS_REGION:-us-west-2} + - AWS_ACCESS_KEY=${AWS_ACCESS_KEY:-YOUR_AWS_ACCESS_KEY} + - AWS_SECRET_KEY_ID=${AWS_SECRET_KEY_ID:-YOUR_AWS_SECRET_KEY_ID} + # OpenSearch + - OPENSEARCH_ENDPOINT=${OPENSEARCH_ENDPOINT:-https://opensearch.us-west-2.es.amazonaws.com} + - OPENSEARCH_USERNAME=${OPENSEARCH_USERNAME:-devopscorner} + - OPENSEARCH_PASSWORD=${OPENSEARCH_PASSWORD:-DevOpsCorner2023} + # Prometheus + - PROMETHEUS_ENDPOINT=${PROMETHEUS_ENDPOINT:-http://localhost:9090} + # Grafana + - GRAFANA_ENDPOINT=${GRAFANA_ENDPOINT:-http://localhost:3000} + - GRAFANA_API_KEY=${GRAFANA_API_KEY:-YOUR_GRAFANA_API_KEY} + # OpenTelemetry + - OTEL_INSTRUMENTATION_METRIC_ENABLED=${OTEL_INSTRUMENTATION_METRIC_ENABLED:-true} + - OTEL_INSTRUMENTATION_TRACE_ENABLED=${OTEL_INSTRUMENTATION_TRACE_ENABLED:-true} + - OTEL_INSTRUMENTATION_LOG_ENABLED=${OTEL_INSTRUMENTATION_LOG_ENABLED:-true} + - OTEL_SERVICE_NAME=${OTEL_SERVICE_NAME:-bookstore-adot} + - OTEL_EXPORTER_OTLP_ENDPOINT=${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4317} + - OTEL_EXPORTER_OTLP_INSECURE=${OTEL_EXPORTER_OTLP_INSECURE:-true} + - OTEL_EXPORTER_OTLP_HEADERS=${OTEL_EXPORTER_OTLP_HEADERS} + - OTEL_RESOURCE_ATTRIBUTES=${OTEL_RESOURCE_ATTRIBUTES} + # Jaeger + - JAEGER_AGENT_PORT=${JAEGER_AGENT_PORT:-6831} + - JAEGER_SAMPLER_TYPE=${JAEGER_SAMPLER_TYPE:-const} + - JAEGER_SAMPLER_PARAM=${JAEGER_SAMPLER_PARAM:-1} + - JAEGER_SAMPLER_MANAGER_HOST_PORT=${JAEGER_SAMPLER_MANAGER_HOST_PORT} + - JAEGER_REPORTER_LOG_SPANS=${JAEGER_REPORTER_LOG_SPANS:-true} + - JAEGER_REPORTER_BUFFER_FLUSH_INTERVAL=${JAEGER_REPORTER_BUFFER_FLUSH_INTERVAL:-5} + - JAEGER_REPORTER_MAX_QUEUE_SIZE=${JAEGER_REPORTER_MAX_QUEUE_SIZE:-100} + - JAEGER_REPORTER_LOCAL_AGENT_HOST_PORT=${JAEGER_REPORTER_LOCAL_AGENT_HOST_PORT} + - JAEGER_REPORTER_COLLECTOR_ENDPOINT=${JAEGER_REPORTER_COLLECTOR_ENDPOINT:-http://localhost:14268/api/traces} + - JAEGER_REPORTER_COLLECTOR_USER=${JAEGER_REPORTER_COLLECTOR_USER:-devopscorner} + - JAEGER_REPORTER_COLLECTOR_PASSWORD=${JAEGER_REPORTER_COLLECTOR_PASSWORD:-DevOpsCorner2023} + - JAEGER_TAGS=${JAEGER_TAGS:-golang,otel,restful,api,bookstore} + # X-Ray + - XRAY_VERSION=${XRAY_VERSION:-latest} + privileged: true + tty: true + networks: + devopscorner_net: + ipv4_address: ${CONTAINER_IP_GO_BOOKSTORE_ADOT:-172.148.148.225} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..c649f909 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,126 @@ +version: '3.7' + +#================================================================================================ +# NETWORK SETUP +#================================================================================================ +networks: + devopscorner_net: + name: devopscorner_net + driver: bridge + ipam: + config: + - subnet: 172.148.0.0/16 + +#================================================================================================ +# VOLUME SETUP +#================================================================================================ +volumes: + vol_portainer: + driver: ${VOLUMES_DRIVER:-local} + driver_opts: + o: bind + type: none + device: ${DATA_PORTAINER:-/opt/data/docker/portainer2.9} + vol_go_bookstore_adot: + driver: ${VOLUMES_DRIVER:-local} + driver_opts: + o: bind + type: none + device: ${DATA_GO_BOOKSTORE_ADOT:-/opt/data/docker/go-bookstore-adot} + +services: + #================================================================================================ + # PORTAINER + #================================================================================================ + portainer: + image: dockerframework/portainer:${PORTAINER_VERSION:-2.9} + container_name: ${CONTAINER_PORTAINER:-devopscorner_portainer} + restart: unless-stopped + ports: + - "${PORT_PORTAINER:-5212}:9000" + volumes: + # - /etc/localtime:/etc/localtime:ro ## Do not use it in mac + - /var/run/docker.sock:/var/run/docker.sock ## Do not use it in k8s + - vol_portainer:/data + environment: + - PORTAINER_TEMPLATE=generic + - PORTAINER_VERSION=${PORTAINER_VERSION:-2.9} + privileged: true + networks: + devopscorner_net: + ipv4_address: ${CONTAINER_IP_PORTAINER:-172.148.148.5} + + #================================================================================================ + # GOLANG-BOOKSTORE-ADOT + #================================================================================================ + go-bookstore-adot: + build: + context: . + dockerfile: Dockerfile-amd64 + container_name: ${CONTAINER_GO_BOOKSTORE_ADOT:-devopscorner_go_bookstore_adot} + restart: unless-stopped + ports: + - "${PORT_GO_BOOKSTORE_ADOT:-8080}:8080" + volumes: + # - /etc/localtime:/etc/localtime:ro ## Do not use it in mac + - /var/run/docker.sock:/var/run/docker.sock ## Do not use it in k8s + environment: + - TZ="Asia/Jakarta" + - ALPINE_VERSION=${ALPINE_VERSION:-3.17} + - CODEBUILD_VERSION=${CODEBUILD_VERSION:-4.0} + - GIN_MODE=release + - APP_URL=${APP_URL:-http://localhost} + - APP_PORT=${APP_PORT:-8080} + - DB_CONNECTION=${DB_CONNECTION:-sqlite} + - DB_HOST=${DB_HOST:-localhost} + - DB_PORT=${DB_PORT} + - DB_DATABASE=${DB_DATABASE:-go-bookstore.db} + - DB_USERNAME=${DB_USERNAME:-root} + - DB_PASSWORD=${DB_PASSWORD} + - JWT_AUTH_USERNAME=${JWT_AUTH_USERNAME:-devopscorner} + - JWT_AUTH_PASSWORD=${JWT_AUTH_PASSWORD:-DevOpsCorner2023} + - JWT_SECRET=${JWT_SECRET:-s3cr3t} + # Logger + - LOG_LEVEL=${LOG_LEVEL:-INFO} + # AWS Credentials + - AWS_REGION=${AWS_REGION:-us-west-2} + - AWS_ACCESS_KEY=${AWS_ACCESS_KEY:-YOUR_AWS_ACCESS_KEY} + - AWS_SECRET_KEY_ID=${AWS_SECRET_KEY_ID:-YOUR_AWS_SECRET_KEY_ID} + # OpenSearch + - OPENSEARCH_ENDPOINT=${OPENSEARCH_ENDPOINT:-https://opensearch.us-west-2.es.amazonaws.com} + - OPENSEARCH_USERNAME=${OPENSEARCH_USERNAME:-devopscorner} + - OPENSEARCH_PASSWORD=${OPENSEARCH_PASSWORD:-DevOpsCorner2023} + # Prometheus + - PROMETHEUS_ENDPOINT=${PROMETHEUS_ENDPOINT:-http://localhost:9090} + # Grafana + - GRAFANA_ENDPOINT=${GRAFANA_ENDPOINT:-http://localhost:3000} + - GRAFANA_API_KEY=${GRAFANA_API_KEY:-YOUR_GRAFANA_API_KEY} + # OpenTelemetry + - OTEL_INSTRUMENTATION_METRIC_ENABLED=${OTEL_INSTRUMENTATION_METRIC_ENABLED:-true} + - OTEL_INSTRUMENTATION_TRACE_ENABLED=${OTEL_INSTRUMENTATION_TRACE_ENABLED:-true} + - OTEL_INSTRUMENTATION_LOG_ENABLED=${OTEL_INSTRUMENTATION_LOG_ENABLED:-true} + - OTEL_SERVICE_NAME=${OTEL_SERVICE_NAME:-bookstore-adot} + - OTEL_EXPORTER_OTLP_ENDPOINT=${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4317} + - OTEL_EXPORTER_OTLP_INSECURE=${OTEL_EXPORTER_OTLP_INSECURE:-true} + - OTEL_EXPORTER_OTLP_HEADERS=${OTEL_EXPORTER_OTLP_HEADERS} + - OTEL_RESOURCE_ATTRIBUTES=${OTEL_RESOURCE_ATTRIBUTES} + # Jaeger + - JAEGER_AGENT_PORT=${JAEGER_AGENT_PORT:-6831} + - JAEGER_SAMPLER_TYPE=${JAEGER_SAMPLER_TYPE:-const} + - JAEGER_SAMPLER_PARAM=${JAEGER_SAMPLER_PARAM:-1} + - JAEGER_SAMPLER_MANAGER_HOST_PORT=${JAEGER_SAMPLER_MANAGER_HOST_PORT} + - JAEGER_REPORTER_LOG_SPANS=${JAEGER_REPORTER_LOG_SPANS:-true} + - JAEGER_REPORTER_BUFFER_FLUSH_INTERVAL=${JAEGER_REPORTER_BUFFER_FLUSH_INTERVAL:-5} + - JAEGER_REPORTER_MAX_QUEUE_SIZE=${JAEGER_REPORTER_MAX_QUEUE_SIZE:-100} + - JAEGER_REPORTER_LOCAL_AGENT_HOST_PORT=${JAEGER_REPORTER_LOCAL_AGENT_HOST_PORT} + - JAEGER_REPORTER_COLLECTOR_ENDPOINT=${JAEGER_REPORTER_COLLECTOR_ENDPOINT:-http://localhost:14268/api/traces} + - JAEGER_REPORTER_COLLECTOR_USER=${JAEGER_REPORTER_COLLECTOR_USER:-devopscorner} + - JAEGER_REPORTER_COLLECTOR_PASSWORD=${JAEGER_REPORTER_COLLECTOR_PASSWORD:-DevOpsCorner2023} + - JAEGER_TAGS=${JAEGER_TAGS:-golang,otel,restful,api,bookstore} + # X-Ray + - XRAY_VERSION=${XRAY_VERSION:-latest} + privileged: true + tty: true + networks: + devopscorner_net: + ipv4_address: ${CONTAINER_IP_GO_BOOKSTORE_ADOT:-172.148.148.225} diff --git a/docker/config/alertmanager/config.yml b/docker/config/alertmanager/config.yml new file mode 100644 index 00000000..558b271a --- /dev/null +++ b/docker/config/alertmanager/config.yml @@ -0,0 +1,11 @@ +route: + receiver: 'slack' + +receivers: + - name: 'slack' + slack_configs: + - send_resolved: true + text: "{{ .CommonAnnotations.description }}" + username: 'Prometheus' + channel: '#' + api_url: 'https://hooks.slack.com/services/' \ No newline at end of file diff --git a/docker/config/prometheus/alert.rules b/docker/config/prometheus/alert.rules new file mode 100644 index 00000000..b371301f --- /dev/null +++ b/docker/config/prometheus/alert.rules @@ -0,0 +1,69 @@ +groups: +- name: targets + rules: + - alert: monitor_service_down + expr: up == 0 + for: 30s + labels: + severity: critical + annotations: + summary: "Monitor service non-operational" + description: "Service {{ $labels.instance }} is down." + +- name: host + rules: + - alert: high_cpu_load + expr: node_load1 > 1.5 + for: 30s + labels: + severity: warning + annotations: + summary: "Server under high load" + description: "Docker host is under high load, the avg load 1m is at {{ $value}}. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}." + + - alert: high_memory_load + expr: (sum(node_memory_MemTotal) - sum(node_memory_MemFree + node_memory_Buffers + node_memory_Cached) ) / sum(node_memory_MemTotal) * 100 > 85 + for: 30s + labels: + severity: warning + annotations: + summary: "Server memory is almost full" + description: "Docker host memory usage is {{ humanize $value}}%. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}." + + - alert: high_storage_load + expr: (node_filesystem_size{fstype="aufs"} - node_filesystem_free{fstype="aufs"}) / node_filesystem_size{fstype="aufs"} * 100 > 85 + for: 30s + labels: + severity: warning + annotations: + summary: "Server storage is almost full" + description: "Docker host storage usage is {{ humanize $value}}%. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}." + +- name: containers + rules: + - alert: jenkins_down + expr: absent(container_memory_usage_bytes{name="jenkins"}) + for: 30s + labels: + severity: critical + annotations: + summary: "Jenkins down" + description: "Jenkins container is down for more than 30 seconds." + + - alert: jenkins_high_cpu + expr: sum(rate(container_cpu_usage_seconds_total{name="jenkins"}[1m])) / count(node_cpu{mode="system"}) * 100 > 10 + for: 30s + labels: + severity: warning + annotations: + summary: "Jenkins high CPU usage" + description: "Jenkins CPU usage is {{ humanize $value}}%." + + - alert: jenkins_high_memory + expr: sum(container_memory_usage_bytes{name="jenkins"}) > 1200000000 + for: 30s + labels: + severity: warning + annotations: + summary: "Jenkins high memory usage" + description: "Jenkins memory consumption is at {{ humanize $value}}." diff --git a/docker/config/prometheus/prometheus.yml b/docker/config/prometheus/prometheus.yml new file mode 100644 index 00000000..09a1db5a --- /dev/null +++ b/docker/config/prometheus/prometheus.yml @@ -0,0 +1,43 @@ +global: + scrape_interval: 15s + evaluation_interval: 15s + + # Attach these labels to any time series or alerts when communicating with + # external systems (federation, remote storage, Alertmanager). + external_labels: + monitor: 'docker-host-alpha' + +# Load and evaluate rules in this file every 'evaluation_interval' seconds. +rule_files: + - "alert.rules" + +# A scrape configuration containing exactly one endpoint to scrape. +scrape_configs: + - job_name: 'nodeexporter' + scrape_interval: 5s + static_configs: + - targets: ['nodeexporter:9100'] + + - job_name: 'cadvisor' + scrape_interval: 5s + static_configs: + - targets: ['cadvisor:8080'] + + - job_name: 'prometheus' + scrape_interval: 10s + static_configs: + - targets: ['localhost:9090'] + + - job_name: 'pushgateway' + scrape_interval: 10s + honor_labels: true + static_configs: + - targets: ['pushgateway:9091'] + + +alerting: + alertmanagers: + - scheme: http + static_configs: + - targets: + - 'alertmanager:9093' diff --git a/dockerhub-build.sh b/dockerhub-build.sh new file mode 100755 index 00000000..99a4ec55 --- /dev/null +++ b/dockerhub-build.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env sh +# ----------------------------------------------------------------------------- +# Docker Build Container (DockerHub) +# ----------------------------------------------------------------------------- +# Author : Dwi Fahni Denni +# License : Apache v2 +# ----------------------------------------------------------------------------- +set -e + +# export CI_PROJECT_PATH="devopscorner" +# export CI_PROJECT_NAME="bookstore-adot" + +# export IMAGE="$CI_PROJECT_PATH/$CI_PROJECT_NAME" +export IMAGE=$2 + +docker_build() { + export FILE=$1 + export BASE_IMAGE=$3 + export TAGS_ID=$4 + export CUSTOM_TAGS=$5 + + if [ "$CUSTOM_TAGS" = "" ]; then + echo "Build Image => $IMAGE:$BASE_IMAGE" + echo ">> docker build -t $IMAGE:$BASE_IMAGE -f $FILE ." + docker build -t $IMAGE:$BASE_IMAGE -f $FILE . + echo '---' + + echo "Build Image => $IMAGE:$TAGS_ID" + echo ">> docker build -t $IMAGE:$TAGS_ID -f $FILE ." + docker build -t $IMAGE:$TAGS_ID -f $FILE . + echo '---' + + echo "Build Image => $IMAGE:$BASE_IMAGE-$TAGS_ID" + echo ">> docker build -t $IMAGE:$BASE_IMAGE-$TAGS_ID -f $FILE ." + docker build -t $IMAGE:$BASE_IMAGE-$TAGS_ID -f $FILE . + echo '---' + else + echo "Build Image => $IMAGE:$BASE_IMAGE" + echo ">> docker build -t $IMAGE:$BASE_IMAGE -f $FILE ." + docker build -t $IMAGE:$BASE_IMAGE -f $FILE . + echo '---' + + echo "Build Image => $IMAGE:$TAGS_ID" + echo "docker build -t $IMAGE:$TAGS_ID -f $FILE ." + docker build -t $IMAGE:$TAGS_ID -f $FILE . + echo '---' + + echo "Build Image => $IMAGE:$BASE_IMAGE-$TAGS_ID" + echo ">> docker build -t $IMAGE:$BASE_IMAGE-$TAGS_ID -f $FILE ." + docker build -t $IMAGE:$BASE_IMAGE-$TAGS_ID -f $FILE . + echo '---' + + echo "Build Image => $IMAGE:$TAGS_ID-$CUSTOM_TAGS" + docker build -t $IMAGE:$TAGS_ID-$CUSTOM_TAGS -f $FILE . + echo ">> docker build -t $IMAGE:$TAGS_ID-$CUSTOM_TAGS -f $FILE ." + echo '---' + + echo "Build Image => $IMAGE:$BASE_IMAGE-$TAGS_ID-$CUSTOM_TAGS" + echo ">> docker build -t $IMAGE:$BASE_IMAGE-$TAGS_ID-$CUSTOM_TAGS -f $FILE ." + docker build -t $IMAGE:$BASE_IMAGE-$TAGS_ID-$CUSTOM_TAGS -f $FILE . + echo '---' + fi +} + +main() { + # docker_build Dockerfile devopscorner/bookstore-adot alpine [version|latest|tags] [custom-tags] + docker_build $1 $2 $3 $4 $5 + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main $1 $2 $3 $4 $5 + +### How to Execute ### +# ./dockerhub-build.sh Dockerfile [DOCKERHUB_IMAGE_PATH] [alpine] [version|latest|tags] [custom-tags] diff --git a/dockerhub-push.sh b/dockerhub-push.sh new file mode 100755 index 00000000..76cd852c --- /dev/null +++ b/dockerhub-push.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env sh +# ----------------------------------------------------------------------------- +# Docker Push Container (DockerHub) +# ----------------------------------------------------------------------------- +# Author : Dwi Fahni Denni +# License : Apache v2 +# ----------------------------------------------------------------------------- +set -e + +# export CI_PROJECT_PATH="devopscorner" +# export CI_PROJECT_NAME="bookstore-adot" + +# export IMAGE="$CI_PROJECT_PATH/$CI_PROJECT_NAME" +export IMAGE=$1 + +login_docker() { + echo '===================' + echo ' Login DockerHub ' + echo '===================' + echo $DOCKERHUB_PASSWORD | docker login --username $DOCKERHUB_USERNAME --password-stdin + echo '- DONE -' + echo '' +} + +docker_push() { + export TAGS_ID=$2 + IMAGES=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep $IMAGE:$TAGS_ID) + for IMG in $IMAGES; do + echo "Docker Push => $IMG" + echo ">> docker push $IMG" + docker push $IMG + echo '- DONE -' + echo '' + done +} + +main() { + login_docker + # docker_push devopscorner/bookstore-adot [alpine|version|latest|tags|custom-tags] + docker_push $1 $2 + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main $1 $2 + +### How to Execute ### +# ./dockerhub-push.sh [DOCKERHUB_IMAGE_PATH] [alpine|version|latest|tags|custom-tags] diff --git a/dockerhub-tag.sh b/dockerhub-tag.sh new file mode 100755 index 00000000..ba1de076 --- /dev/null +++ b/dockerhub-tag.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env sh +# ----------------------------------------------------------------------------- +# Docker Tag Container (DockerHub) +# ----------------------------------------------------------------------------- +# Author : Dwi Fahni Denni +# License : Apache v2 +# ----------------------------------------------------------------------------- +set -e + +# export CI_PROJECT_PATH="devopscorner" +# export CI_PROJECT_NAME="bookstore-adot" + +# export IMAGE="$CI_PROJECT_PATH/$CI_PROJECT_NAME" +export IMAGE=$1 + +set_tag() { + export BASE_IMAGE=$2 + export TAGS_ID=$3 + export CUSTOM_TAGS=$4 + export COMMIT_HASH=$(git log -1 --format=format:"%H") + + if [ "$CUSTOM_TAGS" = "" ]; then + export TAGS="$TAGS_ID \ + $BASE_IMAGE-$TAGS_ID \ + $TAGS_ID-$COMMIT_HASH \ + $BASE_IMAGE-$COMMIT_HASH " + else + export TAGS="$TAGS_ID \ + $BASE_IMAGE-$TAGS_ID \ + $TAGS_ID-$COMMIT_HASH \ + $BASE_IMAGE-$COMMIT_HASH \ + $TAGS_ID-$CUSTOM_TAGS" + fi +} + +docker_tag() { + for TAG in $TAGS; do + echo "Docker Tags => $IMAGE:$TAG" + echo ">> docker tag $IMAGE:$BASE_IMAGE $IMAGE:$TAG" + docker tag $IMAGE:$BASE_IMAGE $IMAGE:$TAG + echo '- DONE -' + echo '' + done +} + +main() { + # set_tag devopscorner/bookstore-adot alpine [version|latest|tags] [custom-tags] + set_tag $1 $2 $3 $4 + docker_tag + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main $1 $2 $3 $4 + +### How to Execute ### +# ./dockerhub-tag.sh [DOCKERHUB_IMAGE_PATH] [alpine] [version|latest|tags] [custom-tags] diff --git a/docs/Configuration-Account.md b/docs/Configuration-Account.md new file mode 100644 index 00000000..98d193da --- /dev/null +++ b/docs/Configuration-Account.md @@ -0,0 +1,27 @@ +## Setup Account + +Setup Account for VPS (Virtual Private Server) Ubuntu version 16.04 + +### Create Deploy User & Authorize +``` +sudo adduser deploy # password: d3pl0y_zeroc0d3 (default) +sudo usermod -aG sudo ubuntu +sudo usermod -aG sudo ec2-user +sudo usermod -aG sudo deploy + +sudo visudo +----- +root ALL=(ALL:ALL) ALL +ubuntu ALL=(ALL:ALL) ALL +deploy ALL=(ALL:ALL) ALL +``` + +### Generate Public-Key (**without password**) +``` +/usr/bin/ssh-keygen -t rsa -b 4096 -C "deploy@devopscorner.cloud9" -f $HOME/.ssh/id_rsa -q -N ""; +``` + +### Generate `pem` file +``` +/usr/bin/openssl rsa -in ~/.ssh/id_rsa -outform pem > id_rsa.pem +``` diff --git a/docs/Configuration-Bash.md b/docs/Configuration-Bash.md new file mode 100644 index 00000000..0a1ab7d1 --- /dev/null +++ b/docs/Configuration-Bash.md @@ -0,0 +1,235 @@ +## Bash Configuration + +### Default `~/.bashrc` Configuration +``` +# ~/.bashrc: executed by bash(1) for non-login shells. +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) +# for examples + +# If not running interactively, don't do anything +case $- in + *i*) ;; + *) return;; +esac + +# don't put duplicate lines or lines starting with space in the history. +# See bash(1) for more options +HISTCONTROL=ignoreboth + +# append to the history file, don't overwrite it +shopt -s histappend + +# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) +HISTSIZE=1000 +HISTFILESIZE=2000 + +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# If set, the pattern "**" used in a pathname expansion context will +# match all files and zero or more directories and subdirectories. +#shopt -s globstar + +# make less more friendly for non-text input files, see lesspipe(1) +[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" + +# set a fancy prompt (non-color, unless we know we "want" color) +case "$TERM" in + xterm-color|*-256color) color_prompt=yes;; +esac + +# uncomment for a colored prompt, if the terminal has the capability; turned +# off by default to not distract the user: the focus in a terminal window +# should be on the output of commands, not on the prompt +#force_color_prompt=yes + +if [ -n "$force_color_prompt" ]; then + if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + # We have color support; assume it's compliant with Ecma-48 + # (ISO/IEC-6429). (Lack of such support is extremely rare, and such + # a case would tend to support setf rather than setaf.) + color_prompt=yes + else + color_prompt= + fi +fi + +unset color_prompt force_color_prompt + +# If this is an xterm set the title to user@host:dir +case "$TERM" in +xterm*|rxvt*) + PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" + ;; +*) + ;; +esac + +# enable color support of ls and also add handy aliases +if [ -x /usr/bin/dircolors ]; then + test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + alias ls='ls --color=auto' + #alias dir='dir --color=auto' + #alias vdir='vdir --color=auto' + + alias grep='grep --color=auto' + alias fgrep='fgrep --color=auto' + alias egrep='egrep --color=auto' +fi + +# colored GCC warnings and errors +#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' + +# some more ls aliases +alias ll='ls -alF' +alias la='ls -A' +alias l='ls -CF' + +# Add an "alert" alias for long running commands. Use like so: +# sleep 10; alert +alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' + +# Alias definitions. +# You may want to put all your additions into a separate file like +# ~/.bash_aliases, instead of adding them here directly. +# See /usr/share/doc/bash-doc/examples in the bash-doc package. + +if [ -f ~/.bash_aliases ]; then + . ~/.bash_aliases +fi + +# enable programmable completion features (you don't need to enable +# this, if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if ! shopt -oq posix; then + if [ -f /usr/share/bash-completion/bash_completion ]; then + . /usr/share/bash-completion/bash_completion + elif [ -f /etc/bash_completion ]; then + . /etc/bash_completion + fi +fi + +# Path to the bash it configuration +export BASH_IT="$HOME/.bash_it" + +# Lock and Load a custom theme file +# location /.bash_it/themes/ +# export BASH_IT_THEME='zork' + +# (Advanced): Change this to the name of your remote repo if you +# cloned bash-it with a remote other than origin such as `bash-it`. +# export BASH_IT_REMOTE='bash-it' + +# Your place for hosting Git repos. I use this for private repos. +export GIT_HOSTING='git@git.domain.com' + +# Don't check mail when opening terminal. +unset MAILCHECK + +# Change this to your console based IRC client of choice. +export IRC_CLIENT='irssi' + +# Set this to the command you use for todo.txt-cli +export TODO="t" + +# Set this to false to turn off version control status checking within the prompt for all themes +export SCM_CHECK=true + +# Set Xterm/screen/Tmux title with only a short hostname. +# Uncomment this (or set SHORT_HOSTNAME to something else), +# Will otherwise fall back on $HOSTNAME. +#export SHORT_HOSTNAME=$(hostname -s) + +# Set vcprompt executable path for scm advance info in prompt (demula theme) +# https://github.com/djl/vcprompt +#export VCPROMPT_EXECUTABLE=~/.vcprompt/bin/vcprompt + +# (Advanced): Uncomment this to make Bash-it reload itself automatically +# after enabling or disabling aliases, plugins, and completions. +# export BASH_IT_AUTOMATIC_RELOAD_AFTER_CONFIG_CHANGE=1 + +# Load Bash It +# source $BASH_IT/bash_it.sh + +export THEME=$HOME/.bash_it/themes/agnoster-bash/agnoster.bash +if [[ -f $THEME ]]; then + export DEFAULT_USER=`whoami` + source $THEME +fi + +### Path Ruby RBENV / RVM ### +export RBENV_ROOT="$HOME/.rbenv" +export RVM_ROOT="/usr/local/rvm" + +### rbenv (Ruby) default ### +if [ -d "$RBENV_ROOT" ] +then + export PATH="$RBENV_ROOT/bin:${PATH}" + eval "$(rbenv init -)" + export PATH="$RBENV_ROOT/plugins/ruby-build/bin:$PATH" + # export RAILS_ENV=staging +else + ### rvm (Ruby) - alternative ### + if [ -d "$RVM_ROOT" ] + then + export PATH="$PATH:$RVM_ROOT/bin" + source $RVM_ROOT/scripts/rvm + + # Set PATH alternatives using this: + [[ -s "$RVM_ROOT/scripts/rvm" ]] && source "$RVM_ROOT/scripts/rvm" + + ### rvm selector ### + # function gemdir { + # if [[ -z "$1" ]] ; then + # echo "gemdir expects a parameter, which should be a valid RVM Ruby selector" + # else + # rvm "$1" + # cd $(rvm gemdir) + # pwd + # fi + # } + fi +fi + +### Path NVM (NodeJS Version Manager) ### +export NVM_ROOT="$HOME/.nvm" + +if [ -d "$NVM_ROOT" ] +then + [ -s "$NVM_ROOT/nvm.sh" ] && . "$NVM_ROOT/nvm.sh" # This loads nvm +fi + +### TMUX ### +# export TMUX_TMPDIR=~/.tmux/tmp + +### JAVA PATH ### +# JAVA_HOME="/usr/lib/jvm/java-8-oracle" +# JRE_HOME="/usr/lib/jvm/java-8-oracle/jre" +# JAVA_HOME=/usr/lib/jvm/jdk1.8.0_121 +# JRE_HOME=/usr/lib/jvm/jdk.1.8.0_121/jre +# PATH=$PATH:$HOME/bin:$JAVA_HOME/bin:$JRE_HOME/bin +# export JAVA_HOME +# export JRE_HOME +# export PATH + +### GO-Lang $GOPATH ### +export GOPATH=$HOME/go +export GOROOT=/usr/local/go +export PATH=$PATH:$GOROOT/bin:$GOPATH/bin + +### Docker ### +export DOCKER_CLIENT_TIMEOUT=300 +export COMPOSE_HTTP_TIMEOUT=300 + +### Path pyenv (Python Version Manager) ### +export PYENV_ROOT="$HOME/.pyenv" +export PATH="$PYENV_ROOT/bin:$PATH" + +if [ -d "$PYENV_ROOT" ] +then + # echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' + eval "$(pyenv init -)" +fi +[ -f ~/.fzf.bash ] && source ~/.fzf.bash +``` \ No newline at end of file diff --git a/docs/Configuration-Fstab.md b/docs/Configuration-Fstab.md new file mode 100644 index 00000000..45799beb --- /dev/null +++ b/docs/Configuration-Fstab.md @@ -0,0 +1,99 @@ +## Fstab Configuration + +Volume configuration + +### Install Dependency +``` +sudo apt-get -y update +sudo apt-get -y install libblkid1 +``` + +### Backup & Configure `/etc/fstab` +* Copy / Backup `/etc/fstab` +``` +sudo cp /etc/fstab /etc/fstab_old +``` + +* Show `/etc/fstab` file +``` +LABEL=cloudimg-rootfs / ext4 defaults 0 0 +``` + +* Find disk UUID or view block partition +``` +sudo lsblk -f +------- +NAME FSTYPE LABEL UUID MOUNTPOINT +vda +└─vda1 ext4 cloudimg-rootfs 82ca1e17-8bc2-4895-96bb-3c39e5863238 / +vdb +vdc +``` + +* Format volume partition +``` +sudo mkfs.ext4 /dev/vdb +sudo mkfs.ext4 /dev/vdc +``` + +* Add mount point "assets" to `/home/deploy/assets` +``` +sudo mkdir -p /home/deploy/assets +sudo chmod 777 /home/deploy/assets +sudo chown deploy:deploy /home/deploy/assets +``` + +* Add mount point "database" to `/home/deploy/database` +``` +sudo mkdir -p /home/deploy/database +sudo chmod 777 /home/deploy/database +chown deploy:deploy /home/deploy/database +``` + +* Show mount point UUID +``` +sudo blkid +------- +/dev/vda1: LABEL="cloudimg-rootfs" UUID="82ca1e17-8bc2-4895-96bb-3c39e5863238" TYPE="ext4" PARTUUID="3276fc6f-01" +/dev/vdb: UUID="12c75a16-c392-4dd6-b031-d5acd09fb75f" TYPE="ext4" +/dev/vdc: UUID="ff0301b7-1198-4b3d-afd4-708044cf38d8" TYPE="ext4" +``` + +* Edit `/etc/fstab` file +``` +LABEL=cloudimg-rootfs / ext4 defaults 0 0 +UUID=12c75a16-c392-4dd6-b031-d5acd09fb75f /home/deploy/assets ext4 defaults 0 0 +UUID=ff0301b7-1198-4b3d-afd4-708044cf38d8 /home/deploy/database ext4 defaults 0 0 +``` + +* Remounting all partition +``` +sudo mount -a +``` + +* View all partition mounted +``` +sudo mount -v +------- +/dev/vdc on /home/deploy/database type ext4 (rw,relatime,data=ordered) +/dev/vdb on /home/deploy/assets type ext4 (rw,relatime,data=ordered) +lxcfs on /var/lib/lxcfs type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other) +/dev/vda1 on /var/lib/docker/plugins type ext4 (rw,relatime,data=ordered) +/dev/vda1 on /var/lib/docker/overlay2 type ext4 (rw,relatime,data=ordered) +tmpfs on /run/user/1001 type tmpfs (rw,nosuid,nodev,relatime,size=1643188k,mode=700,uid=1001,gid=1001) +``` + +* View mounting `/dev/vda` only +``` +sudo mount -v | grep vda +``` + +* View mounting `/dev/vdb` only +``` +sudo mount -v | grep vdb +``` + +* View mounting `/dev/vdc` only +``` +sudo mount -v | grep vdc +``` diff --git a/docs/Configuration-Hosts.md b/docs/Configuration-Hosts.md new file mode 100644 index 00000000..6f31e8c9 --- /dev/null +++ b/docs/Configuration-Hosts.md @@ -0,0 +1,16 @@ +## Hosts Configuration + +Hosts configuration at `/etc/hosts` + +### Hosts Development / Staging +``` +127.0.0.1 localhost +192.168.0.10 dev.devopcorner.com +``` + +### Hosts Production +``` +127.0.0.1 localhost +127.0.1.1 devopcorner.com +192.168.0.100 devopcorner.com +``` diff --git a/docs/Configuration-Swap.md b/docs/Configuration-Swap.md new file mode 100644 index 00000000..74b9562d --- /dev/null +++ b/docs/Configuration-Swap.md @@ -0,0 +1,101 @@ +## Swap Configuration + +Swap space configuration for Ubuntu 16.04 + +* Check available swap +``` +sudo swapon --show +sudo free -h +``` + +* Check space available +``` +sudo df -h +``` + +* Create swap file +``` +sudo fallocate -l [size_in_giga] /swapfile +------- +sudo fallocate -l 8.0G /swapfile # set 8GByte +ls -lh /swapfile # verify swap +``` + +* Enabling swap file +``` +sudo chmod 600 /swapfile +ls -lh /swapfile # verify permission +``` + +* Marked swap file +``` +sudo mkswap /swapfile +------- +Setting up swapspace version 1, size = 8 GiB (8589930496 bytes) +no label, UUID=267498be-04b8-48d0-bf67-e43f18d03e49 +``` + +* Allow system to start +``` +sudo swapon /swapfile +``` + +### Test & Validation +* Verify swap available +``` +sudo swapon --show +------- +NAME TYPE SIZE USED PRIO +/swapfile file 8G 0B -1 +``` + +* Check output free +``` +free -h +``` + +### Setup `/etc/fstab` Swap +* Backup old configuration `/etc/fstab` +``` +sudo cp /etc/fstab /etc/fstab.bak +``` + +* Add swap file information +``` +echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab +``` + +* Adjusting the Cache Pressure Setting +``` +sudo sysctl vm.vfs_cache_pressure=50 +sudo sysctl vm.swappiness=10 +``` + +* Edit configration `/etc/sysctl.conf`, add in bottom line: +``` +vm.swappiness=10 +vm.vfs_cache_pressure=50 +``` + +* Remounting all partition & swap +``` +sudo mount -a +``` + +* View free memory +``` +sudo free -m +------- + total used free shared buff/cache available +Mem: 16046 139 15152 20 753 15568 +Swap: 32767 0 32767 + +sudo free -h +------- +Mem: 15G 141M 14G 20M 754M 15G +Swap: 31G 0B 31G +``` + +### Notes +* References: +[Digital Ocean - Swap](https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-16-04) \ No newline at end of file diff --git a/docs/Configuration-Zsh.md b/docs/Configuration-Zsh.md new file mode 100644 index 00000000..fa375f31 --- /dev/null +++ b/docs/Configuration-Zsh.md @@ -0,0 +1,179 @@ +## Zsh Configuration + +### Default `~/.zshrc` Configuration +``` +# If you come from bash you might have to change your $PATH. +# export PATH=$HOME/bin:/usr/local/bin:$PATH + +# set PATH so it includes user's private bin directories +export PATH="$HOME/bin:/usr/local/bin:$PATH:$HOME/.local/bin:$PATH" + +### POWELINE FONTS ### +# powerline-daemon -q +# POWERLINE_BASH_CONTINUATION=1 +# POWERLINE_BASH_SELECT=1 +# . /usr/local/lib/python2.7/dist-packages/powerline/bindings/bash/powerline.sh + +# Path to your oh-my-zsh installation. +export ZSH=$HOME/.oh-my-zsh + +# Path xterm-256-color +export TERM="xterm-256color" + +# Set name of the theme to load. Optionally, if you set this to "random" +# it'll load a random theme each time that oh-my-zsh is loaded. +# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes + +# ZSH_THEME="agnoster" +ZSH_THEME="powerlevel9k/powerlevel9k" + +# Uncomment the following line to use case-sensitive completion. +# CASE_SENSITIVE="true" + +# Uncomment the following line to use hyphen-insensitive completion. Case +# sensitive completion must be off. _ and - will be interchangeable. +# HYPHEN_INSENSITIVE="true" + +# Uncomment the following line to disable bi-weekly auto-update checks. +# DISABLE_AUTO_UPDATE="true" + +# Uncomment the following line to change how often to auto-update (in days). +# export UPDATE_ZSH_DAYS=13 + +# Uncomment the following line to disable colors in ls. +# DISABLE_LS_COLORS="true" + +# Uncomment the following line to disable auto-setting terminal title. +# DISABLE_AUTO_TITLE="true" + +# Uncomment the following line to enable command auto-correction. +# ENABLE_CORRECTION="true" + +# Uncomment the following line to display red dots whilst waiting for completion. +# COMPLETION_WAITING_DOTS="true" + +# Uncomment the following line if you want to disable marking untracked files +# under VCS as dirty. This makes repository status check for large repositories +# much, much faster. +# DISABLE_UNTRACKED_FILES_DIRTY="true" + +# Uncomment the following line if you want to change the command execution time +# stamp shown in the history command output. +# The optional three formats: "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" +# HIST_STAMPS="mm/dd/yyyy" + +# Would you like to use another custom folder than $ZSH/custom? +# ZSH_CUSTOM=/path/to/new-custom-folder + +# Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*) +# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/ +# Example format: plugins=(rails git textmate ruby lighthouse) +# Add wisely, as too many plugins slow down shell startup. +plugins=(git) + +source $ZSH/oh-my-zsh.sh + +# User configuration + +# export MANPATH="/usr/local/man:$MANPATH" + +# You may need to manually set your language environment +# export LANG=en_US.UTF-8 + +# Preferred editor for local and remote sessions +# if [[ -n $SSH_CONNECTION ]]; then +# export EDITOR='vim' +# else +# export EDITOR='mvim' +# fi + +# Compilation flags +# export ARCHFLAGS="-arch x86_64" + +# ssh +# export SSH_KEY_PATH="~/.ssh/rsa_id" + +# Set personal aliases, overriding those provided by oh-my-zsh libs, +# plugins, and themes. Aliases can be placed here, though oh-my-zsh +# users are encouraged to define aliases within the ZSH_CUSTOM folder. +# For a full list of active aliases, run `alias`. +# +# Example aliases +# alias zshconfig="mate ~/.zshrc" +# alias ohmyzsh="mate ~/.oh-my-zsh" + +### Path Ruby RBENV / RVM ### +export RBENV_ROOT="$HOME/.rbenv" +export RVM_ROOT="/usr/local/rvm" + +### rbenv (Ruby) default ### +if [ -d "$RBENV_ROOT" ] +then + export PATH="$RBENV_ROOT/bin:${PATH}" + eval "$(rbenv init -)" + export PATH="$RBENV_ROOT/plugins/ruby-build/bin:$PATH" + # export RAILS_ENV=staging +else + ### rvm (Ruby) - alternative ### + if [ -d "$RVM_ROOT" ] + then + export PATH="$PATH:$RVM_ROOT/bin" + source $RVM_ROOT/scripts/rvm + + # Set PATH alternatives using this: + [[ -s "$RVM_ROOT/scripts/rvm" ]] && source "$RVM_ROOT/scripts/rvm" + + ### rvm selector ### + # function gemdir { + # if [[ -z "$1" ]] ; then + # echo "gemdir expects a parameter, which should be a valid RVM Ruby selector" + # else + # rvm "$1" + # cd $(rvm gemdir) + # pwd + # fi + # } + fi +fi + +### Path NVM (NodeJS Version Manager) ### +export NVM_ROOT="$HOME/.nvm" + +if [ -d "$NVM_ROOT" ] +then + [ -s "$NVM_ROOT/nvm.sh" ] && . "$NVM_ROOT/nvm.sh" # This loads nvm +fi + +### TMUX ### +# export TMUX_TMPDIR=~/.tmux/tmp + +### JAVA PATH ### +# JAVA_HOME="/usr/lib/jvm/java-8-oracle" +# JRE_HOME="/usr/lib/jvm/java-8-oracle/jre" +# JAVA_HOME=/usr/lib/jvm/jdk1.8.0_121 +# JRE_HOME=/usr/lib/jvm/jdk.1.8.0_121/jre +# PATH=$PATH:$HOME/bin:$JAVA_HOME/bin:$JRE_HOME/bin +# export JAVA_HOME +# export JRE_HOME +# export PATH + +### GO-Lang $GOPATH ### +export GOPATH=$HOME/go +export GOROOT=/usr/local/go +export PATH=$PATH:$GOROOT/bin:$GOPATH/bin + +### Docker ### +export DOCKER_CLIENT_TIMEOUT=300 +export COMPOSE_HTTP_TIMEOUT=300 + +### Path pyenv (Python Version Manager) ### +export PYENV_ROOT="$HOME/.pyenv" +export PATH="$PYENV_ROOT/bin:$PATH" + +if [ -d "$PYENV_ROOT" ] +then + # echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' + eval "$(pyenv init -)" +fi +[ -f ~/.fzf.bash ] && source ~/.fzf.bash +``` \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..d632358f --- /dev/null +++ b/docs/README.md @@ -0,0 +1,50 @@ +# Golang Bookstore ADOT + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +![goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## INDEX + +- Build Container `devopscorner/cicd` + - Build Container `devopscorner/cicd` for DockerHub, detail [here](https://github.com/devopscorner/devopscorner-container/blob/master/docs/container-cicd-dockerhub.md) + - Build Container `devopscorner/cicd` for ECR, detail [here](https://github.com/devopscorner/devopscorner-container/blob/master/docs/container-cicd-ecr.md) + +- Build Container `devopscorner/bookstore-adot` + - Build Container `devopscorner/bookstore-adot` for DockerHub, detail [here](container-bookstore-adot-dockerhub.md) + - Build Container `devopscorner/bookstore-adot` for ECR, detail [here](container-bookstore-adot-ecr.md) + +- Workflow CI/CD Pipeline, detail [here](workflow-cicd-bookstore-adot-pipeline.md) + +- Deployments: + - **AWS Developer Tools** (AWS CodeCommit, AWS CodeBuild & AWS CodePipeline), detail [here](deployment-aws-developer-tools.md) link + - **Jenkins CI/CD**, detail [here](deployment-jenkins.md) link + - **Terraform AWS CodeBuild, AWS CodePipeline & Amazon SNS**, detail [here](deployment-terraform.md) link + +- Reproduce Provisioning + 1. Install Terraform Modules, detail [here](reproduce-01-teraform-modules.md) + 2. Provisioning HelmChart Template, detail [here](reproduce-02-helm-template.md) + 3. Provisioning TFState DB & Bucket, detail [here](reproduce-03-provisioning-tfstate-db-bucket.md) + 4. Provisioning Infra Core, detail [here](reproduce-04-provisioning-infra-core.md) + 5. Provisioning Infra CI/CD, detail [here](reproduce-05-provisioning-infra-cicd.md) + 6. Provisioning Resources Amazon EKS, detail [here](reproduce-06-provisioning-resources-eks.md) + 7. Provisioning Resources Managed Services Prometheus (AMP), detail [here](reproduce-07-provisioning-resources-amp.md) + 8. Provisioning Resources Managed Services Grafana (AMG), detail [here](reproduce-08-provisioning-resources-amg.md) + 9. Provisioning Resources Managed Services OpenSearch, detail [here](reproduce-09-provisioning-resources-opensearch.md) + +## Reproduce Testing + +- RESTful API Testing, detail [here](test-restful-api.md) link diff --git a/docs/RESTful API - Golang Bookstore - v2.0.postman_collection.json b/docs/RESTful API - Golang Bookstore - v2.0.postman_collection.json new file mode 100644 index 00000000..e0e4071d --- /dev/null +++ b/docs/RESTful API - Golang Bookstore - v2.0.postman_collection.json @@ -0,0 +1,388 @@ +{ + "info": { + "_postman_id": "7a3478d1-8835-43d5-ac56-dd45dbb6f045", + "name": "RESTful API - Golang bookstore-adot Localhost", + "schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json", + "_exporter_id": "260154" + }, + "item": [ + { + "name": "Fetch PostmanBDD", + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "/* =============== DESCRIPTION FILE ======================================== */", + "/* */", + "/* Module : ZEROC0D3 JSON TEST API - MyCampus.app */", + "/* Type : POSTMAN JSON */", + "/* Author : ZEROC0D3 Team */", + "/* Date : November 2016 */", + "/* */", + "/* __________ _________ _______ .___________ */", + "/* \\____ /___________ ____ \\_ ___ \\\\ _ \\ __| _/\\_____ \\ Team */", + "/* / // __ \\_ __ \\/ _ \\/ \\ \\// /_\\ \\ / __ | _(__ < */ ", + "/* / /\\ ___/| | \\( <_> ) \\___\\ \\_/ \\/ /_/ | / \\ */", + "/* /_______ \\___ >__| \\____/ \\______ /\\_____ /\\____ | /______ / */", + "/* \\/ \\/ \\/ \\/ \\/ \\/ */", + "/* */", + "/* ZeroC0d3 Team */ ", + "/* [ N0th1ng Imp0ss1bl3, Grey Hat Coder ] */", + "/* -------------------------------------------------------- */", + "/* http://pastebin.com/u/zeroc0d3 */", + "/* https://github.com/zeroc0d3 */", + "/* */", + "/* ========================================================================= */", + "", + "var url_restapi = postman.getGlobalVariable(\"url_restapi\");", + "tests[\"Success to open welcome page => \" +url_restapi] = responseCode.code === 200;" + ] + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "formdata", + "formdata": [] + }, + "url": "http://bigstickcarpet.com/postman-bdd/dist/postman-bdd.min.js" + }, + "response": [] + }, + { + "name": "Welcome", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "auth": { + "type": "noauth" + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": "{{local_url}}:8080", + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Healthcheck", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "auth": { + "type": "noauth" + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": "{{local_url}}:8080/health", + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Login", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// ----------------------------------------- //", + "// JSON Response Body //", + "// ----------------------------------------- //", + "/*", + "{", + " \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjIsImlzcyI6Imh0dHA6XC9cL215Y2FtcHVzLmFwcFwvYXBpXC9hdXRoXC9sb2dpbiIsImlhdCI6MTQ4MDkxODgzNiwiZXhwIjoxNDgwOTIyNDM2LCJuYmYiOjE0ODA5MTg4MzYsImp0aSI6IjBhNzRiOTJjMTExNzJkYzdiNDhmMzE5MWQ4MWIyMmYyIn0.7rKJGJfwDRwxhTQql1dlWWLrrRVmIK6rwpjaxewjNZE\"", + "}", + "*/", + "", + "// ----------------------------------------- //", + "// JSON Schema References // ", + "// ----------------------------------------- //", + "// References: https://spacetelescope.github.io/understanding-json-schema/structuring.html", + "", + "var schema_test = {", + " \"$schema\": \"http://json-schema.org/draft-04/schema#\",", + " ", + " \"title\":\"User Login (JWT)\",", + " \"description\":\"User login\",", + " ", + " \"type\": \"object\",", + " \"properties\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"token\": { \"type\": \"string\" }", + " },", + " \"additionalProperties\": false,", + " }", + "};", + "", + "", + "// ----------------------------------------- //", + "// TESTCASE PostmanBDD //", + "// ----------------------------------------- //", + "// Load external library from Environment //", + "// ----------------------------------------- //", + "eval(postman.getGlobalVariable('module:postmanBDD'));", + "", + "var jsonParse = pm.response; //tv4", + "var response_data = tv4.validateResult(responseBody, schema_test);", + "var title_data = \"user login\";", + "", + "var jsonData = jsonParse.json();", + "var token = jsonData.token;", + "", + "// ----------------------------------------- //", + "// Set Global Variable Token //", + "// ----------------------------------------- //", + "postman.setGlobalVariable(\"auth_token\", token);", + "", + "//tv4", + "tests[\"Login user succesfully go through, with token: \"+token] = response_data;" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "noauth" + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"username\": \"devopscorner\",\n \"password\": \"DevOpsCorner2023\"\n}" + }, + "url": "{{local_url}}:8080/v1/login", + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "List Books", + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "url": "{{local_url}}:8080/v1/books", + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Find Book ID", + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "url": "{{local_url}}:8080/v1/books/9", + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Add Books 1", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Mastering Go: Create Golang production applications using network libraries, concurrency, and advanced Go data structures\",\n \"author\": \"Mihalis Tsoukalos\",\n \"year\": \"2023\"\n}" + }, + "url": "{{local_url}}:8080/v1/books", + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Add Books 2", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Introducing Go: Build Reliable, Scalable Programs\",\n \"author\": \"Caleb Doxsey\",\n \"year\": \"2023\"\n}\n" + }, + "url": "{{local_url}}:8080/v1/books", + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Add Books 3", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Learning Functional Programming in Go: Change the way you approach your applications using functional programming in Go\",\n \"author\": \"Lex Sheehan\",\n \"year\": \"2023\"\n}" + }, + "url": "{{local_url}}:8080/v1/books", + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Edit Books 3 ", + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"DevOpsCorner\",\n \"author\": \"DevOpsCorner Indonesia\",\n \"year\": \"2024\"\n}" + }, + "url": "{{local_url}}:8080/v1/books/9", + "description": "localhost:8080/books/3" + }, + "response": [] + }, + { + "name": "Delete Books 3", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Test Book\",\n \"author\": \"Zeroc0D3 Lab\"\n}" + }, + "url": "{{local_url}}:8080/v1/books/9", + "description": "localhost:8080/books/3" + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/docs/RESTful API - Golang Bookstore - v2.1.postman_collection.json b/docs/RESTful API - Golang Bookstore - v2.1.postman_collection.json new file mode 100644 index 00000000..ac569319 --- /dev/null +++ b/docs/RESTful API - Golang Bookstore - v2.1.postman_collection.json @@ -0,0 +1,498 @@ +{ + "info": { + "_postman_id": "7a3478d1-8835-43d5-ac56-dd45dbb6f045", + "name": "RESTful API - Golang bookstore-adot Localhost", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "260154" + }, + "item": [ + { + "name": "Fetch PostmanBDD", + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "/* =============== DESCRIPTION FILE ======================================== */", + "/* */", + "/* Module : ZEROC0D3 JSON TEST API - MyCampus.app */", + "/* Type : POSTMAN JSON */", + "/* Author : ZEROC0D3 Team */", + "/* Date : November 2016 */", + "/* */", + "/* __________ _________ _______ .___________ */", + "/* \\____ /___________ ____ \\_ ___ \\\\ _ \\ __| _/\\_____ \\ Team */", + "/* / // __ \\_ __ \\/ _ \\/ \\ \\// /_\\ \\ / __ | _(__ < */ ", + "/* / /\\ ___/| | \\( <_> ) \\___\\ \\_/ \\/ /_/ | / \\ */", + "/* /_______ \\___ >__| \\____/ \\______ /\\_____ /\\____ | /______ / */", + "/* \\/ \\/ \\/ \\/ \\/ \\/ */", + "/* */", + "/* ZeroC0d3 Team */ ", + "/* [ N0th1ng Imp0ss1bl3, Grey Hat Coder ] */", + "/* -------------------------------------------------------- */", + "/* http://pastebin.com/u/zeroc0d3 */", + "/* https://github.com/zeroc0d3 */", + "/* */", + "/* ========================================================================= */", + "", + "var url_restapi = postman.getGlobalVariable(\"url_restapi\");", + "tests[\"Success to open welcome page => \" +url_restapi] = responseCode.code === 200;" + ] + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "formdata", + "formdata": [] + }, + "url": { + "raw": "http://bigstickcarpet.com/postman-bdd/dist/postman-bdd.min.js", + "protocol": "http", + "host": [ + "bigstickcarpet", + "com" + ], + "path": [ + "postman-bdd", + "dist", + "postman-bdd.min.js" + ] + } + }, + "response": [] + }, + { + "name": "Welcome", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "auth": { + "type": "noauth" + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{local_url}}:8080", + "host": [ + "{{local_url}}" + ], + "port": "8080" + }, + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Healthcheck", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "auth": { + "type": "noauth" + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{local_url}}:8080/health", + "host": [ + "{{local_url}}" + ], + "port": "8080", + "path": [ + "health" + ] + }, + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Login", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// ----------------------------------------- //", + "// JSON Response Body //", + "// ----------------------------------------- //", + "/*", + "{", + " \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjIsImlzcyI6Imh0dHA6XC9cL215Y2FtcHVzLmFwcFwvYXBpXC9hdXRoXC9sb2dpbiIsImlhdCI6MTQ4MDkxODgzNiwiZXhwIjoxNDgwOTIyNDM2LCJuYmYiOjE0ODA5MTg4MzYsImp0aSI6IjBhNzRiOTJjMTExNzJkYzdiNDhmMzE5MWQ4MWIyMmYyIn0.7rKJGJfwDRwxhTQql1dlWWLrrRVmIK6rwpjaxewjNZE\"", + "}", + "*/", + "", + "// ----------------------------------------- //", + "// JSON Schema References // ", + "// ----------------------------------------- //", + "// References: https://spacetelescope.github.io/understanding-json-schema/structuring.html", + "", + "var schema_test = {", + " \"$schema\": \"http://json-schema.org/draft-04/schema#\",", + " ", + " \"title\":\"User Login (JWT)\",", + " \"description\":\"User login\",", + " ", + " \"type\": \"object\",", + " \"properties\": {", + " \"type\": \"object\",", + " \"properties\": {", + " \"token\": { \"type\": \"string\" }", + " },", + " \"additionalProperties\": false,", + " }", + "};", + "", + "", + "// ----------------------------------------- //", + "// TESTCASE PostmanBDD //", + "// ----------------------------------------- //", + "// Load external library from Environment //", + "// ----------------------------------------- //", + "eval(postman.getGlobalVariable('module:postmanBDD'));", + "", + "var jsonParse = pm.response; //tv4", + "var response_data = tv4.validateResult(responseBody, schema_test);", + "var title_data = \"user login\";", + "", + "var jsonData = jsonParse.json();", + "var token = jsonData.token;", + "", + "// ----------------------------------------- //", + "// Set Global Variable Token //", + "// ----------------------------------------- //", + "postman.setGlobalVariable(\"auth_token\", token);", + "", + "//tv4", + "tests[\"Login user succesfully go through, with token: \"+token] = response_data;" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "noauth" + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"username\": \"devopscorner\",\n \"password\": \"DevOpsCorner2023\"\n}" + }, + "url": { + "raw": "{{local_url}}:8080/v1/login", + "host": [ + "{{local_url}}" + ], + "port": "8080", + "path": [ + "v1", + "login" + ] + }, + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "List Books", + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "url": { + "raw": "{{local_url}}:8080/v1/books", + "host": [ + "{{local_url}}" + ], + "port": "8080", + "path": [ + "v1", + "books" + ] + }, + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Find Book ID", + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "url": { + "raw": "{{local_url}}:8080/v1/books/9", + "host": [ + "{{local_url}}" + ], + "port": "8080", + "path": [ + "v1", + "books", + "9" + ] + }, + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Add Books 1", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Mastering Go: Create Golang production applications using network libraries, concurrency, and advanced Go data structures\",\n \"author\": \"Mihalis Tsoukalos\",\n \"year\": \"2023\"\n}" + }, + "url": { + "raw": "{{local_url}}:8080/v1/books", + "host": [ + "{{local_url}}" + ], + "port": "8080", + "path": [ + "v1", + "books" + ] + }, + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Add Books 2", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Introducing Go: Build Reliable, Scalable Programs\",\n \"author\": \"Caleb Doxsey\",\n \"year\": \"2023\"\n}\n" + }, + "url": { + "raw": "{{local_url}}:8080/v1/books", + "host": [ + "{{local_url}}" + ], + "port": "8080", + "path": [ + "v1", + "books" + ] + }, + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Add Books 3", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Learning Functional Programming in Go: Change the way you approach your applications using functional programming in Go\",\n \"author\": \"Lex Sheehan\",\n \"year\": \"2023\"\n}" + }, + "url": { + "raw": "{{local_url}}:8080/v1/books", + "host": [ + "{{local_url}}" + ], + "port": "8080", + "path": [ + "v1", + "books" + ] + }, + "description": "localhost:8080/books" + }, + "response": [] + }, + { + "name": "Edit Books 3 ", + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"DevOpsCorner\",\n \"author\": \"DevOpsCorner Indonesia\",\n \"year\": \"2024\"\n}" + }, + "url": { + "raw": "{{local_url}}:8080/v1/books/9", + "host": [ + "{{local_url}}" + ], + "port": "8080", + "path": [ + "v1", + "books", + "9" + ] + }, + "description": "localhost:8080/books/3" + }, + "response": [] + }, + { + "name": "Delete Books 3", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Authorization", + "value": "Bearer {{auth_token}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Test Book\",\n \"author\": \"Zeroc0D3 Lab\"\n}" + }, + "url": { + "raw": "{{local_url}}:8080/v1/books/9", + "host": [ + "{{local_url}}" + ], + "port": "8080", + "path": [ + "v1", + "books", + "9" + ] + }, + "description": "localhost:8080/books/3" + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/docs/container-bookstore-adot-dockerhub.md b/docs/container-bookstore-adot-dockerhub.md new file mode 100644 index 00000000..5625b68d --- /dev/null +++ b/docs/container-bookstore-adot-dockerhub.md @@ -0,0 +1,129 @@ +# Golang Bookstore ADOT - DockerHub + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +![goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Build Container Image + +- Clone this repository + + ``` + git clone https://github.com/devopscorner/golang-adot.git + ``` + +- Replace "YOUR_AWS_ACCOUNT" with your AWS ACCOUNT ID + + ``` + find ./ -type f -exec sed -i 's/YOUR_AWS_ACCOUNT/123456789012/g' {} \; + ``` + +- Set Environment Variable + + ``` + export ALPINE_VERSION=3.17 # 3.15 | 3.16 | 3.17 + export BASE_IMAGE="alpine" + export IMAGE="devopscorner/bookstore-adot" + export TAG="latest" + ``` + +- Execute Build Image + + ``` + # Golang 1.19.3 - Alpine 3.15 + docker build -f Dockerfile -t ${IMAGE}:alpine . + docker build -f Dockerfile.alpine-3.15 -t ${IMAGE}:alpine-3.15 . + docker build -f Dockerfile.alpine-3.15 -t ${IMAGE}:golang1.19.3-alpine3.15 . + + # Golang 1.19.5 - Alpine 3.16 + docker build -f Dockerfile -t ${IMAGE}:alpine . + docker build -f Dockerfile.alpine-3.16 -t ${IMAGE}:alpine-3.16 . + docker build -f Dockerfile.alpine-3.16 -t ${IMAGE}:golang1.19.5-alpine3.16 . + + # Golang 1.19.5 - Alpine 3.17 + docker build -f Dockerfile -t ${IMAGE}:alpine . + docker build -f Dockerfile.alpine-3.17 -t ${IMAGE}:alpine-3.17 . + docker build -f Dockerfile.alpine-3.17 -t ${IMAGE}:golang1.19.5-alpine3.17 . + + -- or -- + + dockerhub-build.sh alpine Dockerfile ${ALPINE_VERSION} + dockerhub-build.sh alpine Dockerfile.alpine-3.15 ${ALPINE_VERSION} + dockerhub-build.sh alpine Dockerfile.alpine-3.16 ${ALPINE_VERSION} + dockerhub-build.sh alpine Dockerfile.alpine-3.17 ${ALPINE_VERSION} + + -- or -- + + # default: 3.17 + make dockerhub-build-alpine + ``` + +## Push Image to DockerHub + +- Login to your DockerHub Account + +- Add Environment Variable + ``` + export DOCKERHUB_USERNAME=[YOUR_DOCKERHUB_USERNAME] + export DOCKERHUB_PASSWORD=[YOUR_DOCKERHUB_PASSWORD_OR_PERSONAL_TOKEN] + ``` + +- Create Tags Image + - Example: + + ``` + # Alpine + docker tag ${IMAGE}:alpine ${IMAGE}:latest + + docker tag ${IMAGE}:alpine ${IMAGE}:alpine-latest + + docker tag ${IMAGE}:alpine ${IMAGE}:alpine-3.16 + ``` + + - With Script: + + ``` + # default: 3.16 + ./dockerhub-tag.sh alpine ${ALPINE_VERSION} + + -- or -- + + # default: 3.16 + make dockerhub-tag-alpine + ``` + +- Push Image to **DockerHub** with Tags + + - Example: + + ``` + # Alpine + docker push devopscorner-bookstore-adot:alpine + + docker push devopscorner-bookstore-adot:latest + + docker push devopscorner-bookstore-adot:alpine-latest + ``` + + - With Script: + + ``` + ./dockerhub-push.sh alpine CI_PATH="devopscorner/bookstore-adot" + + -- or -- + + make dockerhub-push-alpine + ``` diff --git a/docs/container-bookstore-adot-ecr.md b/docs/container-bookstore-adot-ecr.md new file mode 100644 index 00000000..b9062656 --- /dev/null +++ b/docs/container-bookstore-adot-ecr.md @@ -0,0 +1,125 @@ +# Golang Bookstore ADOT - Amazon ECR (Elastic Container Registry) + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +![goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Build Container Image + +- Clone this repository + + ``` + git clone https://github.com/devopscorner/golang-adot.git + ``` + +- Replace "YOUR_AWS_ACCOUNT" with your AWS ACCOUNT ID + + ``` + find ./ -type f -exec sed -i 's/YOUR_AWS_ACCOUNT/123456789012/g' {} \; + ``` + +- Set Environment Variable + + ``` + export ALPINE_VERSION=3.17 # 3.15 | 3.16 | 3.17 + export BASE_IMAGE="alpine" + export IMAGE="YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot" + export TAG="latest" + ``` + +- Execute Build Image + + ``` + # Golang 1.19.3 - Alpine 3.15 + docker build -f Dockerfile -t ${IMAGE}:alpine . + docker build -f Dockerfile.alpine-3.15 -t ${IMAGE}:alpine-3.15 . + docker build -f Dockerfile.alpine-3.15 -t ${IMAGE}:golang1.19.3-alpine3.15 . + + # Golang 1.19.5 - Alpine 3.16 + docker build -f Dockerfile -t ${IMAGE}:alpine . + docker build -f Dockerfile.alpine-3.16 -t ${IMAGE}:alpine-3.16 . + docker build -f Dockerfile.alpine-3.16 -t ${IMAGE}:golang1.19.5-alpine3.16 . + + # Golang 1.19.5 - Alpine 3.17 + docker build -f Dockerfile -t ${IMAGE}:alpine . + docker build -f Dockerfile.alpine-3.17 -t ${IMAGE}:alpine-3.17 . + docker build -f Dockerfile.alpine-3.17 -t ${IMAGE}:golang1.19.5-alpine3.17 . + + -- or -- + + ecr-build.sh ${YOUR_AWS_ACCOUNT} alpine Dockerfile ${ALPINE_VERSION} + ecr-build.sh ${YOUR_AWS_ACCOUNT} alpine Dockerfile.alpine-3.15 ${ALPINE_VERSION} + ecr-build.sh ${YOUR_AWS_ACCOUNT} alpine Dockerfile.alpine-3.16 ${ALPINE_VERSION} + ecr-build.sh ${YOUR_AWS_ACCOUNT} alpine Dockerfile.alpine-3.17 ${ALPINE_VERSION} + + -- or -- + + # default: 3.17 + make ecr-build-alpine ARGS=YOUR_AWS_ACCOUNT + ``` + +## Push Image to Amazon ECR (Elastic Container Registry) + +- Create Tags Image + - Example: + + ``` + # Alpine + docker tag YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:latest + + docker tag YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine-latest + + docker tag YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine-3.16 + ``` + + - With Script: + + ``` + # default: 3.17 + docker tag ${IMAGE}:${ALPINE_VERSION} + + -- or -- + + # default: 3.17 + ./ecr-tag.sh ARGS=YOUR_AWS_ACCOUNT alpine ${ALPINE_VERSION} CI_PATH=devopscorner/bookstore-adot + + -- or -- + + make ecr-tag-alpine ARGS=YOUR_AWS_ACCOUNT CI_PATH=devopscorner/bookstore-adot + ``` + + Push Image to **Amazon ECR** with Tags + +- Example: + + ``` + # Alpine + docker push YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine + + docker push YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine-latest + + docker push YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine-3.16 + ``` + +- With Script: + + ``` + ./ecr-push.sh ARGS=YOUR_AWS_ACCOUNT alpine CI_PATH="devopscorner/bookstore-adot" + + -- or -- + + make ecr-push-alpine ARGS=YOUR_AWS_ACCOUNT CI_PATH="devopscorner/bookstore-adot" + ``` diff --git a/docs/container-bookstore-dockerhub.md b/docs/container-bookstore-dockerhub.md new file mode 100644 index 00000000..d8ceab50 --- /dev/null +++ b/docs/container-bookstore-dockerhub.md @@ -0,0 +1,129 @@ +# Golang Bookstore ADOT - DockerHub + +Kubernetes Deployment for Simple Golang API + +![goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Build Container Image + +- Clone this repository + + ``` + git clone https://github.com/devopscorner/golang-adot.git + ``` + +- Replace "YOUR_AWS_ACCOUNT" with your AWS ACCOUNT ID + + ``` + find ./ -type f -exec sed -i 's/YOUR_AWS_ACCOUNT/123456789012/g' {} \; + ``` + +- Set Environment Variable + + ``` + export ALPINE_VERSION=3.17 # 3.15 | 3.16 | 3.17 + export BASE_IMAGE="alpine" + export IMAGE="devopscorner/bookstore-adot" + export TAG="latest" + ``` + +- Execute Build Image + + ``` + # Golang 1.19.3 - Alpine 3.15 + docker build -f Dockerfile -t ${IMAGE}:alpine . + docker build -f Dockerfile.alpine-3.15 -t ${IMAGE}:alpine-3.15 . + docker build -f Dockerfile.alpine-3.15 -t ${IMAGE}:golang1.19.3-alpine3.15 . + + # Golang 1.19.5 - Alpine 3.16 + docker build -f Dockerfile -t ${IMAGE}:alpine . + docker build -f Dockerfile.alpine-3.16 -t ${IMAGE}:alpine-3.16 . + docker build -f Dockerfile.alpine-3.16 -t ${IMAGE}:golang1.19.5-alpine3.16 . + + # Golang 1.19.5 - Alpine 3.17 + docker build -f Dockerfile -t ${IMAGE}:alpine . + docker build -f Dockerfile.alpine-3.17 -t ${IMAGE}:alpine-3.17 . + docker build -f Dockerfile.alpine-3.17 -t ${IMAGE}:golang1.19.5-alpine3.17 . + + -- or -- + + dockerhub-build.sh alpine Dockerfile ${ALPINE_VERSION} + dockerhub-build.sh alpine Dockerfile.alpine-3.15 ${ALPINE_VERSION} + dockerhub-build.sh alpine Dockerfile.alpine-3.16 ${ALPINE_VERSION} + dockerhub-build.sh alpine Dockerfile.alpine-3.17 ${ALPINE_VERSION} + + -- or -- + + # default: 3.17 + make dockerhub-build-alpine + ``` + +## Push Image to DockerHub + +- Login to your DockerHub Account + +- Add Environment Variable + ``` + export DOCKERHUB_USERNAME=[YOUR_DOCKERHUB_USERNAME] + export DOCKERHUB_PASSWORD=[YOUR_DOCKERHUB_PASSWORD_OR_PERSONAL_TOKEN] + ``` + +- Create Tags Image + - Example: + + ``` + # Alpine + docker tag ${IMAGE}:alpine ${IMAGE}:latest + + docker tag ${IMAGE}:alpine ${IMAGE}:alpine-latest + + docker tag ${IMAGE}:alpine ${IMAGE}:alpine-3.16 + ``` + + - With Script: + + ``` + # default: 3.16 + ./dockerhub-tag.sh alpine ${ALPINE_VERSION} + + -- or -- + + # default: 3.16 + make dockerhub-tag-alpine + ``` + +- Push Image to **DockerHub** with Tags + + - Example: + + ``` + # Alpine + docker push devopscorner-bookstore-adot:alpine + + docker push devopscorner-bookstore-adot:latest + + docker push devopscorner-bookstore-adot:alpine-latest + ``` + + - With Script: + + ``` + ./dockerhub-push.sh alpine CI_PATH="devopscorner/bookstore-adot" + + -- or -- + + make dockerhub-push-alpine + ``` diff --git a/docs/container-bookstore-ecr.md b/docs/container-bookstore-ecr.md new file mode 100644 index 00000000..7f9ead94 --- /dev/null +++ b/docs/container-bookstore-ecr.md @@ -0,0 +1,125 @@ +# Golang Bookstore ADOT - Amazon ECR (Elastic Container Registry) + +Kubernetes Deployment for Simple Golang API + +![goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Build Container Image + +- Clone this repository + + ``` + git clone https://github.com/devopscorner/golang-adot.git + ``` + +- Replace "YOUR_AWS_ACCOUNT" with your AWS ACCOUNT ID + + ``` + find ./ -type f -exec sed -i 's/YOUR_AWS_ACCOUNT/123456789012/g' {} \; + ``` + +- Set Environment Variable + + ``` + export ALPINE_VERSION=3.17 # 3.15 | 3.16 | 3.17 + export BASE_IMAGE="alpine" + export IMAGE="YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot" + export TAG="latest" + ``` + +- Execute Build Image + + ``` + # Golang 1.19.3 - Alpine 3.15 + docker build -f Dockerfile -t ${IMAGE}:alpine . + docker build -f Dockerfile.alpine-3.15 -t ${IMAGE}:alpine-3.15 . + docker build -f Dockerfile.alpine-3.15 -t ${IMAGE}:golang1.19.3-alpine3.15 . + + # Golang 1.19.5 - Alpine 3.16 + docker build -f Dockerfile -t ${IMAGE}:alpine . + docker build -f Dockerfile.alpine-3.16 -t ${IMAGE}:alpine-3.16 . + docker build -f Dockerfile.alpine-3.16 -t ${IMAGE}:golang1.19.5-alpine3.16 . + + # Golang 1.19.5 - Alpine 3.17 + docker build -f Dockerfile -t ${IMAGE}:alpine . + docker build -f Dockerfile.alpine-3.17 -t ${IMAGE}:alpine-3.17 . + docker build -f Dockerfile.alpine-3.17 -t ${IMAGE}:golang1.19.5-alpine3.17 . + + -- or -- + + ecr-build.sh ${YOUR_AWS_ACCOUNT} alpine Dockerfile ${ALPINE_VERSION} + ecr-build.sh ${YOUR_AWS_ACCOUNT} alpine Dockerfile.alpine-3.15 ${ALPINE_VERSION} + ecr-build.sh ${YOUR_AWS_ACCOUNT} alpine Dockerfile.alpine-3.16 ${ALPINE_VERSION} + ecr-build.sh ${YOUR_AWS_ACCOUNT} alpine Dockerfile.alpine-3.17 ${ALPINE_VERSION} + + -- or -- + + # default: 3.17 + make ecr-build-alpine ARGS=YOUR_AWS_ACCOUNT + ``` + +## Push Image to Amazon ECR (Elastic Container Registry) + +- Create Tags Image + - Example: + + ``` + # Alpine + docker tag YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:latest + + docker tag YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine-latest + + docker tag YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine-3.16 + ``` + + - With Script: + + ``` + # default: 3.17 + docker tag ${IMAGE}:${ALPINE_VERSION} + + -- or -- + + # default: 3.17 + ./ecr-tag.sh ARGS=YOUR_AWS_ACCOUNT alpine ${ALPINE_VERSION} CI_PATH=devopscorner/bookstore-adot + + -- or -- + + make ecr-tag-alpine ARGS=YOUR_AWS_ACCOUNT CI_PATH=devopscorner/bookstore-adot + ``` + + Push Image to **Amazon ECR** with Tags + +- Example: + + ``` + # Alpine + docker push YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine + + docker push YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine-latest + + docker push YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/bookstore-adot:alpine-3.16 + ``` + +- With Script: + + ``` + ./ecr-push.sh ARGS=YOUR_AWS_ACCOUNT alpine CI_PATH="devopscorner/bookstore-adot" + + -- or -- + + make ecr-push-alpine ARGS=YOUR_AWS_ACCOUNT CI_PATH="devopscorner/bookstore-adot" + ``` diff --git a/docs/deployment-aws-developer-tools.md b/docs/deployment-aws-developer-tools.md new file mode 100644 index 00000000..fde36bd1 --- /dev/null +++ b/docs/deployment-aws-developer-tools.md @@ -0,0 +1,254 @@ +# Golang Bookstore ADOT - Deployment with AWS Developer Tools + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +![goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Buildspec Build + +``` +version: 0.2 + +env: + # ==================== # + # Ref: SECRET CONFIG # + # ==================== # + parameter-store: + BUILDNUMBER: /devopscorner/cicd/staging/repo/bookstore-adot/buildnumber + STORE_AWS_ACCOUNT: /devopscorner/cicd/staging/credentials/aws_account + STORE_AWS_ACCESS_KEY: /devopscorner/cicd/staging/credentials/aws_access_key + STORE_AWS_SECRET_KEY: /devopscorner/cicd/staging/credentials/aws_secret_key + STORE_REPO_URL: /devopscorner/cicd/staging/repo/bookstore-adot/url + STORE_REPO_BRANCH: /devopscorner/cicd/staging/repo/bookstore-adot/branch + STORE_REPO_FOLDER: /devopscorner/cicd/staging/repo/bookstore-adot/folder + STORE_EKS_CLUSTER: /devopscorner/cicd/staging/eks_cluster + STORE_BASE64_PUB_KEY: /devopscorner/cicd/staging/credentials/base64_pub_key + STORE_BASE64_PRIV_KEY: /devopscorner/cicd/staging/credentials/base64_priv_key + STORE_BASE64_PEM_KEY: /devopscorner/cicd/staging/credentials/base64_pem_key + STORE_BASE64_SSH_CONFIG: /devopscorner/cicd/staging/credentials/base64_ssh_config + STORE_BASE64_KNOWN_HOSTS: /devopscorner/cicd/staging/credentials/known_hosts + STORE_BASE64_KUBECONFIG: /devopscorner/cicd/staging/credentials/base64_kube_config + + # ===================================== # + # Ref: Pipeline Environment Variables # + # ===================================== # + variables: + ENV_CICD: "dev" + AWS_DEFAULT_REGION: "us-west-2" + INFRA_CICD: "terraform/environment/providers/aws/infra/resources" + INFRA_CICD_PATH: "bookstore-adot" + INFRA_ECR_PATH: "devopscorner/bookstore-adot" + +phases: + pre_build: + commands: + # ======================= # + # Setup Auth Repository # + # ======================= # + - mkdir -p ~/.ssh + - echo "${STORE_BASE64_PUB_KEY}" | base64 -d > ~/.ssh/id_rsa.pub + - echo "${STORE_BASE64_PRIV_KEY}" | base64 -d > ~/.ssh/id_rsa + - echo "${STORE_BASE64_KNOWN_HOSTS}" | base64 -d > ~/.ssh/known_hosts + - chmod 400 ~/.ssh/id_rsa* + - chmod 644 ~/.ssh/known_hosts + - eval "$(ssh-agent -s)" + - ssh-add ~/.ssh/id_rsa + - echo '- DONE -' + build: + commands: + # ========================= # + # Refactoring AWS Account # + # ========================= # + - cd ${CODEBUILD_SRC_DIR} && find ./ -type f -exec sed -i "s/YOUR_AWS_ACCOUNT/${STORE_AWS_ACCOUNT}/g" {} \; + # ============= # + # Build Image # + # ============= # + - make ecr-build-alpine ARGS=${STORE_AWS_ACCOUNT} CI_PATH=${INFRA_ECR_PATH} + # ============== # + # Unit Testing # + # ============== # + # - make unit-test + # ============ # + # Tags Image # + # ============ # + - make ecr-tag-alpine ARGS=${STORE_AWS_ACCOUNT} CI_PATH=${INFRA_ECR_PATH} + - docker images --format "{{.Repository}}:{{.Tag}}" | grep ${INFRA_ECR_PATH} + # ============ # + # Push Image # + # ============ # + - make ecr-push-alpine ARGS=${STORE_AWS_ACCOUNT} TAGS=${INFRA_ECR_PATH} + +artifacts: + files: + - _infra/* + - .aws/* + - docs/* + - src/* + - dockerhub-build.sh + - dockerhub-push.sh + - dockerhub-tag.sh + - ecr-build.sh + - ecr-push.sh + - ecr-tag.sh + - Makefile + name: "artifact-$(date '+%Y%m%d-%H%M%S')" +``` + +## Buildspec Deploy + +``` +version: 0.2 + +env: + # ==================== # + # Ref: SECRET CONFIG # + # ==================== # + parameter-store: + BUILDNUMBER: /devopscorner/cicd/staging/repo/bookstore-adot/buildnumber + STORE_AWS_ACCOUNT: /devopscorner/cicd/staging/credentials/aws_account + STORE_AWS_ACCESS_KEY: /devopscorner/cicd/staging/credentials/aws_access_key + STORE_AWS_SECRET_KEY: /devopscorner/cicd/staging/credentials/aws_secret_key + STORE_REPO_URL: /devopscorner/cicd/staging/repo/bookstore-adot/url + STORE_REPO_BRANCH: /devopscorner/cicd/staging/repo/bookstore-adot/branch + STORE_REPO_FOLDER: /devopscorner/cicd/staging/repo/bookstore-adot/folder + STORE_EKS_CLUSTER: /devopscorner/cicd/staging/eks_cluster + STORE_BASE64_PUB_KEY: /devopscorner/cicd/staging/credentials/base64_pub_key + STORE_BASE64_PRIV_KEY: /devopscorner/cicd/staging/credentials/base64_priv_key + STORE_BASE64_PEM_KEY: /devopscorner/cicd/staging/credentials/base64_pem_key + STORE_BASE64_SSH_CONFIG: /devopscorner/cicd/staging/credentials/base64_ssh_config + STORE_BASE64_KNOWN_HOSTS: /devopscorner/cicd/staging/credentials/known_hosts + STORE_BASE64_KUBECONFIG: /devopscorner/cicd/staging/credentials/base64_kube_config + + # ===================================== # + # Ref: Pipeline Environment Variables # + # ===================================== # + variables: + ENV_CICD: "dev" + AWS_DEFAULT_REGION: "us-west-2" + INFRA_CICD: "terraform/environment/providers/aws/infra/resources" + INFRA_CICD_PATH: "bookstore-adot" + INFRA_ECR_PATH: "devopscorner/bookstore-adot" + +phases: + pre_build: + commands: + # ======================= # + # Setup Auth Repository # + # ======================= # + - mkdir -p ~/.ssh + - mkdir -p ~/.kube + - echo "${STORE_BASE64_PUB_KEY}" | base64 -d > ~/.ssh/id_rsa.pub + - echo "${STORE_BASE64_PRIV_KEY}" | base64 -d > ~/.ssh/id_rsa + - echo "${STORE_BASE64_KNOWN_HOSTS}" | base64 -d > ~/.ssh/known_hosts + - echo "${STORE_BASE64_KUBECONFIG}" | base64 -d > ~/.kube/config + - chmod 400 ~/.ssh/id_rsa* + - chmod 400 ~/.kube/config* + - chmod 644 ~/.ssh/known_hosts + - eval "$(ssh-agent -s)" + - ssh-add ~/.ssh/id_rsa + - echo '- DONE -' + build: + commands: + # ========================= # + # Refactoring AWS Account # + # ========================= # + - cd ${CODEBUILD_SRC_DIR} && find ./ -type f -exec sed -i "s/YOUR_AWS_ACCOUNT/${STORE_AWS_ACCOUNT}/g" {} \; + # ================== # + # Helm Repo Update # + # ================== # + - AWS_REGION=${AWS_DEFAULT_REGION} helm repo add devopscorner-staging s3://devopscorner-adot-chart/staging + - AWS_REGION=${AWS_DEFAULT_REGION} helm repo add devopscorner-prod s3://devopscorner-adot-chart/prod + - helm repo update + # ============ # + # Deploy K8S # + # ============ # + - cd _infra/${ENV_CICD} + - aws eks update-kubeconfig --region ${AWS_DEFAULT_REGION} --name ${STORE_EKS_CLUSTER} + - kubectl version + - kubectl config use-context arn:aws:eks:${AWS_DEFAULT_REGION}:${STORE_AWS_ACCOUNT}:cluster/${STORE_EKS_CLUSTER} + - kubectl get ns -A + - helmfile --version + - helmfile -f helm-template.yml apply + - echo '-- ALL DONE --' + +artifacts: + files: + - _infra/* + - .aws/* + - docs/* + - src/* + - dockerhub-build.sh + - dockerhub-push.sh + - dockerhub-tag.sh + - ecr-build.sh + - ecr-push.sh + - ecr-tag.sh + - Makefile + name: "artifact-$(date '+%Y%m%d-%H%M%S')" +``` + +## Example CI/CD Script `cicd-aws-codepipeline.yml` + +``` +version: 0.2 + +phases: + install: + runtime-versions: + docker: 19 + build: + commands: + - go build -o app + - | + if [[ "$CODEBUILD_WEBHOOK_TRIGGER" == "branch/main" ]]; then + semver=1.0.0-${CODEBUILD_SOURCE_VERSION} + elif [[ "$CODEBUILD_WEBHOOK_TRIGGER" == "branch/features/"* ]]; then + semver=1.0.0-${CODEBUILD_WEBHOOK_TRIGGER#branch/features/}.${CODEBUILD_SOURCE_VERSION} + elif [[ "$CODEBUILD_WEBHOOK_TRIGGER" == "branch/bugfix/"* ]]; then + semver=1.1.0-${CODEBUILD_WEBHOOK_TRIGGER#branch/bugfix/}.${CODEBUILD_SOURCE_VERSION} + elif [[ "$CODEBUILD_WEBHOOK_TRIGGER" == "branch/hotfix/"* ]]; then + semver=1.1.1-${CODEBUILD_WEBHOOK_TRIGGER#branch/hotfix/}.${CODEBUILD_SOURCE_VERSION} + fi + echo "Semantic version: $semver" + echo "imageTag=$semver" >> $CODEBUILD_SRC_DIR/variables.env + $(aws ecr get-login --no-include-email --region $AWS_REGION) + docker build -t $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_NAME:$semver . + docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_NAME:$semver + docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_NAME:$semver $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_NAME:latest + docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_NAME:latest + post_build: + commands: + - | + echo "Deploying to Kubernetes using Helm" + curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash + helmfile sync + +artifacts: + files: + - _infra/* + - .aws/* + - docs/* + - src/* + - dockerhub-build.sh + - dockerhub-push.sh + - dockerhub-tag.sh + - ecr-build.sh + - ecr-push.sh + - ecr-tag.sh + - Makefile + name: "artifact-$(date '+%Y%m%d-%H%M%S')" + discard-paths: yes +``` diff --git a/docs/deployment-jenkins.md b/docs/deployment-jenkins.md new file mode 100644 index 00000000..7ae68d47 --- /dev/null +++ b/docs/deployment-jenkins.md @@ -0,0 +1,95 @@ +# Golang Bookstore ADOT - CI/CD with Jenkins + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +![goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Jenkins CI/CD + +- [Jenkins CI/CD](../.jenkins/jenkins-cicd.jenkinsfile) + +## Example CI/CD Script `cicd-jenkins.jenkinsfile` + +``` +pipeline { + agent any + + environment { + AWS_REGION = 'us-west-2' + AWS_ACCOUNT_ID = '0987612345' + IMAGE_NAME = 'devopscorner/bookstore-adot' + } + + stages { + stage('Build') { + steps { + sh 'go build -o app' + script { + if (env.BRANCH_NAME ==~ /features\/.*/) { + def semver = "1.0.0-${env.BRANCH_NAME.replace('features/', '')}.${env.GIT_COMMIT}" + echo "Semantic version: ${semver}" + sh "echo imageTag=${semver} >> variables.env" + } else if (env.BRANCH_NAME ==~ /bugfix\/.*/) { + def semver = "1.1.0-${env.BRANCH_NAME.replace('bugfix/', '')}.${env.GIT_COMMIT}" + echo "Semantic version: ${semver}" + sh "echo imageTag=${semver} >> variables.env" + } else if (env.BRANCH_NAME ==~ /hotfix\/.*/) { + def semver = "1.1.1-${env.BRANCH_NAME.replace('hotfix/', '')}.${env.GIT_COMMIT}" + echo "Semantic version: ${semver}" + sh "echo imageTag=${semver} >> variables.env" + } else if (env.BRANCH_NAME == 'main') { + def semver = "1.0.0-${env.GIT_COMMIT}" + echo "Semantic version: ${semver}" + sh "echo imageTag=${semver} >> variables.env" + } + } + withCredentials([usernamePassword(credentialsId: 'aws-ecr-login', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_ACCESS_KEY')]) { + sh "aws ecr get-login-password --region ${env.AWS_REGION} | docker login --username AWS --password-stdin ${env.AWS_ACCOUNT_ID}.dkr.ecr.${env.AWS_REGION}.amazonaws.com" + sh "docker build -t ${env.AWS_ACCOUNT_ID}.dkr.ecr.${env.AWS_REGION}.amazonaws.com/${env.IMAGE_NAME}:${imageTag} ." + sh "docker push ${env.AWS_ACCOUNT_ID}.dkr.ecr.${env.AWS_REGION}.amazonaws.com/${env.IMAGE_NAME}:${imageTag}" + sh "docker tag ${env.AWS_ACCOUNT_ID}.dkr.ecr.${env.AWS_REGION}.amazonaws.com/${env.IMAGE_NAME}:${imageTag} ${env.AWS_ACCOUNT_ID}.dkr.ecr.${env.AWS_REGION}.amazonaws.com/${env.IMAGE_NAME}:latest" + sh "docker push ${env.AWS_ACCOUNT_ID}.dkr.ecr.${env.AWS_REGION}.amazonaws.com/${env.IMAGE_NAME}:latest" + } + stash includes: 'app', name: 'app' + } + } + stage('Deploy') { + steps { + unstash 'app' + withAWS(region: env.AWS_REGION, roleAccount: "${env.AWS_ACCOUNT_ID}") { + sh "curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash" + sh "helmfile sync" + } + } + environment { + DEPLOYMENT_ENVIRONMENT_URL = "http://your-deployment-environment-url" + } + post { + success { + script { + currentBuild.description = "Deployment completed successfully. Visit ${env.DEPLOYMENT_ENVIRONMENT_URL} for details." + } + } + failure { + script { + currentBuild.description = "Deployment failed. Visit ${env.DEPLOYMENT_ENVIRONMENT_URL} for details." + } + } + } + } + } +} +``` \ No newline at end of file diff --git a/docs/deployment-terraform.md b/docs/deployment-terraform.md new file mode 100644 index 00000000..32c860cc --- /dev/null +++ b/docs/deployment-terraform.md @@ -0,0 +1,321 @@ +# Golang Bookstore ADOT - CI/CD with Terraform AWS CodeBuild, AWS CodePipeline & Amazon SNS + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +![goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Example CI/CD Terraform Script `cicd-terraform.tf` + +### This script includes: + +- ECR repository creation +- SNS topic creation and subscription +- CodeBuild project creation for production and staging environments +- CodePipeline creation with four stages: Source, Build, ManualApproval, and Deploy (two times) +- ECS task definition and service creation for staging environment +- CloudWatch Event rule and target for manual approval notification +- Outputs for the staging and production URLs, build number, and semantic versions for staging and production. +- Using custom image AWS CodeBuild `devopscorner/cicd:codebuild-4.0` + +``` +### Golang Terraform Pipeline (GitHub, AWS CodeBuild, AWS Pipeline, Amazon SNS) ### + +# This script includes: +# - ECR repository creation +# - SNS topic creation and subscription +# - CodeBuild project creation for production and staging environments +# - CodePipeline creation with four stages: Source, Build, ManualApproval, and Deploy (two times) +# - ECS task definition and service creation for staging environment +# - CloudWatch Event rule and target for manual approval notification +# - Outputs for the staging and production URLs, build number, and semantic versions for staging and production. +# - Using custom image AWS CodeBuild `devopscorner/cicd:codebuild-4.0` + +terraform { + required_version = ">= 1.0.9" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.63.0, < 4.0" + } + } +} + +provider "aws" { + region = "us-west-2" +} + +data "aws_caller_identity" "current" {} + +resource "aws_ecr_repository" "bookstore-adot" { + name = "devopscorner/bookstore-adot" +} + +resource "aws_sns_topic" "bookstore-adot-topic" { + name = "bookstore-adot-topic" +} + +resource "aws_sns_topic_subscription" "bookstore-adot-subscription" { + topic_arn = aws_sns_topic.bookstore-adot-topic.arn + protocol = "email" + endpoint = "support@devopscorner.id" +} + +resource "aws_codebuild_project" "bookstore-adot-prod" { + name = "bookstore-adot-prod" + description = "My Golang app for production" + service_role = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/CodeBuildServiceRole" + build_timeout = "60" + artifacts { + type = "NO_ARTIFACTS" + } + environment { + compute_type = "BUILD_GENERAL1_SMALL" + # image = "aws/codebuild/standard:5.0" + image = "devopscorner/cicd:codebuild-4.0" + type = "LINUX_CONTAINER" + environment_variable { + name = "AWS_REGION" + value = "us-west-2" + } + environment_variable { + name = "ENVIRONMENT" + value = "prod" + } + environment_variable { + name = "ECR_REPOSITORY_URI" + value = aws_ecr_repository.bookstore-adot.repository_url + } + } + source { + type = "GITHUB" + location = "https://github.com/devopscorner/golang-adot" + git_clone_depth = 1 + buildspec = file("${path.module}/buildspec.yaml") + auth { + type = "OAUTH" + } + } +} + +resource "aws_codebuild_project" "bookstore-adot-staging" { + name = "bookstore-adot-staging" + description = "My Golang app for staging" + service_role = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/CodeBuildServiceRole" + build_timeout = "60" + artifacts { + type = "NO_ARTIFACTS" + } + environment { + compute_type = "BUILD_GENERAL1_SMALL" + # image = "aws/codebuild/standard:5.0" + image = "devopscorner/cicd:codebuild-4.0" + type = "LINUX_CONTAINER" + environment_variable { + name = "AWS_REGION" + value = "us-west-2" + } + environment_variable { + name = "ENVIRONMENT" + value = "staging" + } + environment_variable { + name = "ECR_REPOSITORY_URI" + value = aws_ecr_repository.bookstore-adot.repository_url + } + } + source { + type = "GITHUB" + location = "https://github.com/devopscorner/golang-adot" + git_clone_depth = 1 + buildspec = file("${path.module}/buildspec.yaml") + auth { + type = "OAUTH" + } + } +} + +resource "aws_codepipeline" "bookstore-adot" { + name = "bookstore-adot" + role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/CodePipelineServiceRole" + artifact_store { + type = "S3" + location = "your-artifact-store-bucket" + encryption_key { + type = "KMS" + id = "your-kms-key-id" + } + } + + stage { + name = "Source" + action { + name = "Source" + category = "Source" + owner = "AWS" + provider = "GitHub" + version = "1" + output_artifacts = ["SourceArtifact"] + configuration = { + Owner = "your-username" + Repo = "your-repo" + Branch = "main" + OAuthToken = "your-github-token" + } + } + } + + stage { + name = "Build" + actions { + name = "Build" + category = "Build" + owner = "AWS" + provider = "CodeBuild" + version = "1" + input_artifacts = ["SourceArtifact"] + output_artifacts = ["BuildArtifact"] + configuration = { + ProjectName = aws_codebuild_project.bookstore-adot-staging.name + } + } + } + + stage { + name = "ManualApproval" + actions { + name = "ManualApproval" + category = "Approval" + owner = "AWS" + provider = "Manual" + version = "1" + input_artifacts = ["BuildArtifact"] + configuration = { + NotificationArn = aws_sns_topic.bookstore-adot-topic.arn + CustomData = "Do you want to deploy the latest changes to production?" + } + } + } + + stage { + name = "Deploy-Staging" + actions { + name = "Deploy-Staging" + category = "Deploy" + owner = "AWS" + provider = "ECS" + version = "1" + input_artifacts = ["BuildArtifact"] + configuration = { + ClusterName = "bookstore-adot-cluster" + ServiceName = "bookstore-adot-staging" + FileName = "imagedefinitions.json" + ImageUri = "${aws_ecr_repository.bookstore-adot.repository_url}:${var.semver_staging}" + } + } + } + + stage { + name = "Deploy-Prod" + actions { + name = "Deploy-Prod" + category = "Deploy" + owner = "AWS" + provider = "ECS" + version = "1" + input_artifacts = ["BuildArtifact"] + configuration = { + ClusterName = "bookstore-adot-cluster" + ServiceName = "bookstore-adot-prod" + FileName = "imagedefinitions.json" + ImageUri = "${aws_ecr_repository.bookstore-adot.repository_url}:${var.semver_prod}" + } + condition { + type = "StartsWith" + variable = "ApprovalStatus" + value = "Approved" + } + } + } +} + +resource "aws_ecs_task_definition" "bookstore-adot" { + family = "bookstore-adot" + container_definitions = jsonencode([{ + name = "bookstore-adot" + image = "${aws_ecr_repository.bookstore-adot.repository_url}:${var.semver_staging}" + cpu = 512 + memory_reservation = 512 + port_mappings = { + container_port = 8080 + host_port = 0 + } + }]) +} + +resource "aws_ecs_service" "bookstore-adot-staging" { + name = "bookstore-adot-staging" + cluster = "bookstore-adot-cluster" + task_definition = aws_ecs_task_definition.bookstore-adot.arn + desired_count = 2 + launch_type = "EC2" + load_balancer { + target_group_arn = "your-target-group-arn" + container_name = "bookstore-adot" + container_port = 8080 + } +} + +resource "aws_cloudwatch_event_rule" "bookstore-adot-manual-approval" { + name = "bookstore-adot-manual-approval" + description = "Manual approval rule for my Golang app" + event_pattern = jsonencode({ + source = ["aws.codepipeline"] + detail_type = ["CodePipeline Action Execution State Change"] + detail = { + pipeline = ["${aws_codepipeline.bookstore-adot.name}"] + stage = ["ManualApproval"] + action = ["ManualApproval"] + state = ["STARTED", "SUCCEEDED", "FAILED"] + } + }) +} + +resource "aws_cloudwatch_event_target" "bookstore-adot-manual-approval" { + rule = aws_cloudwatch_event_rule.bookstore-adot-manual-approval.name + arn = aws_sns_topic.bookstore-adot-topic.arn +} + +output "bookstore-adot-staging-url" { + value = aws_alb.bookstore-adot-staging.dns_name +} + +output "bookstore-adot-prod-url" { + value = aws_alb.bookstore-adot-prod.dns_name +} + +output "bookstore-adot-build-number" { + value = aws_codebuild_project.bookstore-adot-staging.build_number +} + +output "bookstore-adot-semver-staging" { + value = var.semver_staging +} + +output "bookstore-adot-semver-prod" { + value = var.semver_prod +} +``` \ No newline at end of file diff --git a/docs/reproduce-01-teraform-modules.md b/docs/reproduce-01-teraform-modules.md new file mode 100644 index 00000000..7cee347b --- /dev/null +++ b/docs/reproduce-01-teraform-modules.md @@ -0,0 +1,37 @@ +# Golang Bookstore ADOT + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +[goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Install Dependencies Terraform Modules + +### Check Existing Modules + + ls -al terraform + +### Using Makefile Installation + + make sub-officials # install terraform officials modules dependencies only + + make sub-community # install terraform community modules dependencies only + + make sub-all # install all / both modules (officials & community) + +### Check Modules Installed + + ls -alR terraform/modules/providers/aws/ + diff --git a/docs/reproduce-02-helm-template.md b/docs/reproduce-02-helm-template.md new file mode 100644 index 00000000..ccc590cc --- /dev/null +++ b/docs/reproduce-02-helm-template.md @@ -0,0 +1,140 @@ +# Golang Bookstore ADOT + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +[goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Provisioning HelmChart Template + +### Create S3 Bucket for Helm + +- Create Bucket S3 + + BUCKET_NAME="devopscorner-adot-chart" + + aws s3 mb "s3://${BUCKET_NAME}" --region us-west-2 + +- Check If Bucket S3 Created + + aws s3 ls "s3://${BUCKET_NAME}" --recursive --human-readable --summarize + + +### Check Helm Repo + + helm repo list + + +### Initialize Helm Repo + +- Production Environment + + helm s3 init "s3://${BUCKET_NAME}/prod" + +- Staging Environment + + helm s3 init "s3://${BUCKET_NAME}/staging" + +- Lab Environment + + helm s3 init "s3://${BUCKET_NAME}/lab" + + +### Register Helm Repo + +- Production Environment + + AWS_REGION=us-west-2 helm repo add devopscorner-adot "s3://${BUCKET_NAME}/prod" + +- Staging Environment + + AWS_REGION=us-west-2 helm repo add devopscorner-adot-staging "s3://${BUCKET_NAME}/staging" + +- Lab Environment + + AWS_REGION=us-west-2 helm repo add devopscorner-adot-lab "s3://${BUCKET_NAME}/lab" + + +### Update Helm Repo + + helm repo update + + +### Check If Helm Repo Already Registered + + helm repo list + + +### Goto `helm/template/[environment]` folder + +- Production Environment + + cd helm/template/prod + +- Staging Environment + + cd helm/template/staging + +- Lab Environment + + cd helm/template/lab + + +### Execute Helm Pack + +- Production Environment + + ./helm-pack-prod.sh + +- Staging Environment + + ./helm-pack-staging.sh + +- Lab Environment + + ./helm-pack-lab.sh + + +### Execute Helm Push + +- Production Environment + + ./helm-push-prod.sh + +- Staging Environment + + ./helm-push-staging.sh + +- Lab Environment + + ./helm-push-lab.sh + + +## CleanUp All + +- Empty Bucket + + aws s3 rm "s3://${BUCKET_NAME}" --recursive + +- Delete Bucket + + aws s3 rb "s3://${BUCKET_NAME}" --region us-west-2 + +- Cleanup Helm Repo + + helm repo rm devopscorner-adot + helm repo rm devopscorner-adot-staging + helm repo rm devopscorner-adot-lab + helm repo update diff --git a/docs/reproduce-03-provisioning-tfstate-db-bucket.md b/docs/reproduce-03-provisioning-tfstate-db-bucket.md new file mode 100644 index 00000000..963ee88f --- /dev/null +++ b/docs/reproduce-03-provisioning-tfstate-db-bucket.md @@ -0,0 +1,104 @@ +# Golang Bookstore ADOT + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +[goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Provisioning TFState + +### Clean Cache + +- Goto `terraform/environment/providers/aws/infra/tfstate` folder + + cd terraform/environment/providers/aws/infra/tfstate + +- Cleanup Cache Terraform + + rm -rf .terraform .terraform.lock.hcl terraform.tfstate.d + + + +### Initialize Terraform + + terraform init + + +### Using Terraform Workspace + +- Production Environment + + WORKSPACE_ENV=prod + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Staging Environment + + WORKSPACE_ENV=staging + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Lab Environment + + WORKSPACE_ENV=lab + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + + +### Terraform Plan + +- Save Binary Plan + + terraform plan --out tfplan.binary + +- Export to JSON + + terraform show -json tfplan.binary > tfplan.json + + +### Terraform Security + +- Using: `terrascan` + + terrascan init + terrascan scan -o human + +- Using: `tfsec` + + tfsec . + +- Using: `checkov` + + checkov -f tfplan.json + + +### Terraform Cost Review + +- Using: `infracost` + + infracost breakdown --path tfplan.json + + +### Terraform Apply + + terraform apply -auto-approve + + +## CleanUp All + +- Cleanup Terraform Cache + + rm -rf .terraform .terraform.lock.hcl terraform.tfstate.d + +- Destroy All TFState + + terraform destroy -auto-approve diff --git a/docs/reproduce-04-provisioning-infra-core.md b/docs/reproduce-04-provisioning-infra-core.md new file mode 100644 index 00000000..fc18a7f6 --- /dev/null +++ b/docs/reproduce-04-provisioning-infra-core.md @@ -0,0 +1,103 @@ +# Golang Bookstore ADOT + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +[goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Provisioning Infra Core + +### Clean Cache + +- Goto `terraform/environment/providers/aws/infra/core` folder + + cd terraform/environment/providers/aws/infra/core + +- Cleanup Cache Terraform + + rm -rf .terraform .terraform.lock.hcl terraform.core.d + + +### Initialize Terraform + + terraform init + + +### Using Terraform Workspace + +- Production Environment + + WORKSPACE_ENV=prod + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Staging Environment + + WORKSPACE_ENV=staging + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Lab Environment + + WORKSPACE_ENV=lab + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + + +### Terraform Plan + +- Save Binary Plan + + terraform plan --out tfplan.binary + +- Export to JSON + + terraform show -json tfplan.binary > tfplan.json + + +### Terraform Security + +- Using: [`terrascan`](https://github.com/tenable/terrascan) + + terrascan init + terrascan scan -o human + +- Using: [`tfsec`](https://aquasecurity.github.io/tfsec/v1.28.1/) + + tfsec . + +- Using: [`checkov`](https://github.com/bridgecrewio/checkov) + + checkov -f tfplan.json + + +### Terraform Cost Review + +- Using: [`infracost`](https://github.com/infracost/infracost) + + infracost breakdown --path tfplan.json + + +### Terraform Apply + + terraform apply -auto-approve + + +## CleanUp All + +- Cleanup Terraform Cache + + rm -rf .terraform .terraform.lock.hcl terraform.core.d + +- Destroy All Infra Core + + terraform destroy -auto-approve diff --git a/docs/reproduce-05-provisioning-infra-cicd.md b/docs/reproduce-05-provisioning-infra-cicd.md new file mode 100644 index 00000000..0d6bba48 --- /dev/null +++ b/docs/reproduce-05-provisioning-infra-cicd.md @@ -0,0 +1,103 @@ +# Golang Bookstore ADOT + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +[goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Provisioning Infra CI/CD + +### Clean Cache + +- Goto `terraform/environment/providers/aws/infra/resources/cicd` folder + + cd terraform/environment/providers/aws/infra/resources/cicd + +- Cleanup Cache Terraform + + rm -rf .terraform .terraform.lock.hcl terraform.cicd.d + + +### Initialize Terraform + + terraform init + + +### Using Terraform Workspace + +- Production Environment + + WORKSPACE_ENV=prod + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Staging Environment + + WORKSPACE_ENV=staging + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Lab Environment + + WORKSPACE_ENV=lab + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + + +### Terraform Plan + +- Save Binary Plan + + terraform plan --out tfplan.binary + +- Export to JSON + + terraform show -json tfplan.binary > tfplan.json + + +### Terraform Security + +- Using: [`terrascan`](https://github.com/tenable/terrascan) + + terrascan init + terrascan scan -o human + +- Using: [`tfsec`](https://aquasecurity.github.io/tfsec/v1.28.1/) + + tfsec . + +- Using: [`checkov`](https://github.com/bridgecrewio/checkov) + + checkov -f tfplan.json + + +### Terraform Cost Review + +- Using: [`infracost`](https://github.com/infracost/infracost) + + infracost breakdown --path tfplan.json + + +### Terraform Apply + + terraform apply -auto-approve + + +## CleanUp All + +- Cleanup Terraform Cache + + rm -rf .terraform .terraform.lock.hcl terraform.cicd.d + +- Destroy All Infra CI/CD + + terraform destroy -auto-approve diff --git a/docs/reproduce-06-provisioning-resources-eks.md b/docs/reproduce-06-provisioning-resources-eks.md new file mode 100644 index 00000000..bd031e09 --- /dev/null +++ b/docs/reproduce-06-provisioning-resources-eks.md @@ -0,0 +1,103 @@ +# Golang Bookstore ADOT + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +[goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Provisioning EKS + +### Clean Cache + +- Goto `terraform/environment/providers/aws/infra/resources/eks` folder + + cd terraform/environment/providers/aws/infra/resources/eks + +- Cleanup Cache Terraform + + rm -rf .terraform .terraform.lock.hcl terraform.eks.d + + +### Initialize Terraform + + terraform init + + +### Using Terraform Workspace + +- Production Environment + + WORKSPACE_ENV=prod + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Staging Environment + + WORKSPACE_ENV=staging + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Lab Environment + + WORKSPACE_ENV=lab + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + + +### Terraform Plan + +- Save Binary Plan + + terraform plan --out tfplan.binary + +- Export to JSON + + terraform show -json tfplan.binary > tfplan.json + + +### Terraform Security + +- Using: [`terrascan`](https://github.com/tenable/terrascan) + + terrascan init + terrascan scan -o human + +- Using: [`tfsec`](https://aquasecurity.github.io/tfsec/v1.28.1/) + + tfsec . + +- Using: [`checkov`](https://github.com/bridgecrewio/checkov) + + checkov -f tfplan.json + + +### Terraform Cost Review + +- Using: [`infracost`](https://github.com/infracost/infracost) + + infracost breakdown --path tfplan.json + + +### Terraform Apply + + terraform apply -auto-approve + + +## CleanUp All + +- Cleanup Terraform Cache + + rm -rf .terraform .terraform.lock.hcl terraform.eks.d + +- Destroy All EKS + + terraform destroy -auto-approve diff --git a/docs/reproduce-07-provisioning-resources-amp.md b/docs/reproduce-07-provisioning-resources-amp.md new file mode 100644 index 00000000..f12de547 --- /dev/null +++ b/docs/reproduce-07-provisioning-resources-amp.md @@ -0,0 +1,103 @@ +# Golang Bookstore ADOT + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +[goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Provisioning Managed Services Prometheus (AMP) + +### Clean Cache + +- Goto `terraform/environment/providers/aws/infra/resources/amp` folder + + cd terraform/environment/providers/aws/infra/resources/amp + +- Cleanup Cache Terraform + + rm -rf .terraform .terraform.lock.hcl terraform.amp.d + + +### Initialize Terraform + + terraform init + + +### Using Terraform Workspace + +- Production Environment + + WORKSPACE_ENV=prod + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Staging Environment + + WORKSPACE_ENV=staging + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Lab Environment + + WORKSPACE_ENV=lab + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + + +### Terraform Plan + +- Save Binary Plan + + terraform plan --out tfplan.binary + +- Export to JSON + + terraform show -json tfplan.binary > tfplan.json + + +### Terraform Security + +- Using: [`terrascan`](https://github.com/tenable/terrascan) + + terrascan init + terrascan scan -o human + +- Using: [`tfsec`](https://aquasecurity.github.io/tfsec/v1.28.1/) + + tfsec . + +- Using: [`checkov`](https://github.com/bridgecrewio/checkov) + + checkov -f tfplan.json + + +### Terraform Cost Review + +- Using: [`infracost`](https://github.com/infracost/infracost) + + infracost breakdown --path tfplan.json + + +### Terraform Apply + + terraform apply -auto-approve + + +## CleanUp All + +- Cleanup Terraform Cache + + rm -rf .terraform .terraform.lock.hcl terraform.amp.d + +- Destroy All Managed Services Prometheus (AMP) + + terraform destroy -auto-approve diff --git a/docs/reproduce-08-provisioning-resources-amg.md b/docs/reproduce-08-provisioning-resources-amg.md new file mode 100644 index 00000000..51fccfcb --- /dev/null +++ b/docs/reproduce-08-provisioning-resources-amg.md @@ -0,0 +1,103 @@ +# Golang Bookstore ADOT + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +[goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Provisioning Managed Services Grafana (AMG) + +### Clean Cache + +- Goto `terraform/environment/providers/aws/infra/resources/amg` folder + + cd terraform/environment/providers/aws/infra/resources/amg + +- Cleanup Cache Terraform + + rm -rf .terraform .terraform.lock.hcl terraform.amp.d + + +### Initialize Terraform + + terraform init + + +### Using Terraform Workspace + +- Production Environment + + WORKSPACE_ENV=prod + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Staging Environment + + WORKSPACE_ENV=staging + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Lab Environment + + WORKSPACE_ENV=lab + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + + +### Terraform Plan + +- Save Binary Plan + + terraform plan --out tfplan.binary + +- Export to JSON + + terraform show -json tfplan.binary > tfplan.json + + +### Terraform Security + +- Using: [`terrascan`](https://github.com/tenable/terrascan) + + terrascan init + terrascan scan -o human + +- Using: [`tfsec`](https://aquasecurity.github.io/tfsec/v1.28.1/) + + tfsec . + +- Using: [`checkov`](https://github.com/bridgecrewio/checkov) + + checkov -f tfplan.json + + +### Terraform Cost Review + +- Using: [`infracost`](https://github.com/infracost/infracost) + + infracost breakdown --path tfplan.json + + +### Terraform Apply + + terraform apply -auto-approve + + +## CleanUp All + +- Cleanup Terraform Cache + + rm -rf .terraform .terraform.lock.hcl terraform.amp.d + +- Destroy All Managed Services Grafana (AMG) + + terraform destroy -auto-approve diff --git a/docs/reproduce-09-provisioning-resources-opensearch.md b/docs/reproduce-09-provisioning-resources-opensearch.md new file mode 100644 index 00000000..718e383b --- /dev/null +++ b/docs/reproduce-09-provisioning-resources-opensearch.md @@ -0,0 +1,103 @@ +# Golang Bookstore ADOT + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +[goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Provisioning OpenSearch + +### Clean Cache + +- Goto `terraform/environment/providers/aws/infra/resources/opensearch` folder + + cd terraform/environment/providers/aws/infra/resources/opensearch + +- Cleanup Cache Terraform + + rm -rf .terraform .terraform.lock.hcl terraform.openseach.d + + +### Initialize Terraform + + terraform init + + +### Using Terraform Workspace + +- Production Environment + + WORKSPACE_ENV=prod + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Staging Environment + + WORKSPACE_ENV=staging + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + +- Lab Environment + + WORKSPACE_ENV=lab + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + + +### Terraform Plan + +- Save Binary Plan + + terraform plan --out tfplan.binary + +- Export to JSON + + terraform show -json tfplan.binary > tfplan.json + + +### Terraform Security + +- Using: [`terrascan`](https://github.com/tenable/terrascan) + + terrascan init + terrascan scan -o human + +- Using: [`tfsec`](https://aquasecurity.github.io/tfsec/v1.28.1/) + + tfsec . + +- Using: [`checkov`](https://github.com/bridgecrewio/checkov) + + checkov -f tfplan.json + + +### Terraform Cost Review + +- Using: [`infracost`](https://github.com/infracost/infracost) + + infracost breakdown --path tfplan.json + + +### Terraform Apply + + terraform apply -auto-approve + + +## CleanUp All + +- Cleanup Terraform Cache + + rm -rf .terraform .terraform.lock.hcl terraform.openseach.d + +- Destroy All OpenSearch + + terraform destroy -auto-approve diff --git a/docs/test-restful-api.md b/docs/test-restful-api.md new file mode 100644 index 00000000..7f3f7ca9 --- /dev/null +++ b/docs/test-restful-api.md @@ -0,0 +1,258 @@ +# Golang Bookstore ADOT - Test RESTful API + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +![goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Development + +### Prequests + +- Install jq libraries + + ``` + apt-get install -y jq + ``` + +- Install golang dependencies + + ``` + cd src + go mod init + go mod tidy + ``` + +### Runnning + +``` +go run main.go +``` + +### Runnning Test + +``` +go run main_test.go +``` + +## Folder Structure + +``` +. +├── .env +├── .env.example +├── config +│   ├── config.go +│   ├── config_test.go +│   ├── const.go +│   ├── logger.go +│   └── value.go +├── controller +│   ├── book_controller.go +│   ├── book_controller_test.go +│   ├── login_controller.go +│   └── login_controller_test.go +├── driver +│   ├── db.go +│   ├── dynamo.go +│   ├── mysql.go +│   ├── psql.go +│   └── sqlite.go +├── dynamodb-golang-adot +├── go.mod +├── go.sum +├── main.go +├── main_test.go +├── middleware +│   ├── auth_middleware.go +│   └── auth_middleware_test.go +├── migrate_book.go.example +├── migrate_book_dynamo.go.example +├── model +│   └── book.go +├── observability +│   ├── metrics.go +│   ├── provider.go +│   └── xray.go +├── repository +│   └── book_repository.go +├── routes +│   ├── book_routes.go +│   ├── main_routes.go +│   └── telemetry_routes.go +└── view + ├── book_view.go + ├── error_view.go + └── login_view.go + +10 directories, 36 files +``` + +## Environment Variables (Default) + +``` +GIN_MODE=release +APP_URL=http://localhost +APP_PORT=8080 +DB_CONNECTION=sqlite +DB_REGION=us-west-2 +DB_HOST=localhost +DB_PORT= +DB_DATABASE=go-bookstore-adot.db +DB_USERNAME=root +DB_PASSWORD= +JWT_AUTH_USERNAME=devopscorner +JWT_AUTH_PASSWORD=DevOpsCorner2023 +JWT_SECRET=s3cr3t +``` + +## Multi Driver Connection + +``` +DB_CONNECTION=sqlite +--- +Available for: +- sqlite +- mysql +- postgres +- dynamo +``` + +## DynamoDB Connection + +``` +DB_CONNECTION=dynamo +--- +DB_DATABASE --> Dynamo Table +DB_REGION --> Dynamo Region +``` + +## API Test + +- Generate JWT Token + +``` +POST : /login + curl --location '0.0.0.0:8080/v1/login' \ + --header 'Content-Type: application/json' \ + --data-raw '{ + "username": "devopscorner", + "password": "DevOpsCorner2023" + }' | jq +--- +{ + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg2MTc5MzN9.p92DDMXVJPA8VTRDzDb-0NtzyfpdOtm5o6cJHMuZv44" +} + +TOKEN=$(curl --request POST \ + --location '0.0.0.0:8080/v1/login' \ + --header 'Content-Type: application/json' \ + --data-raw '{ + "username": "devopscorner", + "password": "DevOpsCorner2023" + }' | jq -r '.token' ) +--- +eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg2MTc5MzN9.p92DDMXVJPA8VTRDzDb-0NtzyfpdOtm5o6cJHMuZv44 +``` + +- List Books + +``` +GET : /v1/books + curl --request GET \ + --location '0.0.0.0:8080/v1/books' \ + --header 'Content-Type: application/json' \ + --header 'Authorization: Bearer ${TOKEN}' | jq +``` + +- Find Book ID + +``` +GET : /v1/books/${id} + curl --request GET \ + --location '0.0.0.0:8080/v1/books/${id}' \ + --header 'Content-Type: application/json' \ + --header 'Authorization: Bearer ${TOKEN}' | jq +``` + +- Add Book 1 + +``` +POST : /v1/books + curl --request POST \ + --location '0.0.0.0:8080/v1/books' \ + --header 'Content-Type: application/json' \ + --header 'Authorization: Bearer ${TOKEN}' \ + --data-raw '{ + "title": "Mastering Go: Create Golang production applications using network libraries, concurrency, and advanced Go data structures", + "author": "Mihalis Tsoukalos", + "year": "2023" + }' | jq +``` + +- Add Book 2 + +``` +POST : /v1/books + curl --request POST \ + --location '0.0.0.0:8080/v1/books' \ + --header 'Content-Type: application/json' \ + --header 'Authorization: Bearer ${TOKEN}' \ + --data-raw '{ + "title": "Introducing Go: Build Reliable, Scalable Programs", + "author": "Caleb Doxsey", + "year": "2023" + }' | jq +``` + +- Add Book 3 + +``` +POST : /v1/books + curl --request POST \ + --location '0.0.0.0:8080/v1/books' \ + --header 'Content-Type: application/json' \ + --header 'Authorization: Bearer ${TOKEN}' \ + --data-raw '{ + "title": "Learning Functional Programming in Go: Change the way you approach your applications using functional programming in Go", + "author": "Lex Sheehan", + "year": "2023" + }' | jq +``` + +- Edit Book 3 + +``` +PATCH : /v1/books/3 + curl --request PATCH \ + --location '0.0.0.0:8080/v1/books/3' \ + --header 'Content-Type: application/json' \ + --header 'Authorization: Bearer ${TOKEN}' \ + --data-raw '{ + "title": "DevOpsCorner", + "author": "DevOpsCorner Indonesia", + "year": "2023" + }' | jq +``` + +- Delete Book 3 + +``` +DELETE : /v1/books/3 + curl --request DELETE \ + --location '0.0.0.0:8080/v1/books/3' \ + --header 'Content-Type: application/json' \ + --header 'Authorization: Bearer ${TOKEN}' | jq +``` diff --git a/docs/workflow-cicd-bookstore-adot-pipeline.md b/docs/workflow-cicd-bookstore-adot-pipeline.md new file mode 100644 index 00000000..092cf9f6 --- /dev/null +++ b/docs/workflow-cicd-bookstore-adot-pipeline.md @@ -0,0 +1,80 @@ +# Golang Bookstore ADOT + +ADOT (AWS Distro for OpenTelemetry) Implementation for Simple Golang RESTful API Application (Bookstore) + +![goreport](https://goreportcard.com/badge/github.com/devopscorner/golang-adot/src) +![all contributors](https://img.shields.io/github/contributors/devopscorner/golang-adot) +![tags](https://img.shields.io/github/v/tag/devopscorner/golang-adot?sort=semver) +[![docker pulls](https://img.shields.io/docker/pulls/devopscorner/bookstore-adot.svg)](https://hub.docker.com/r/devopscorner/bookstore-adot/) +![download all](https://img.shields.io/github/downloads/devopscorner/golang-adot/total.svg) +![view](https://views.whatilearened.today/views/github/devopscorner/golang-adot.svg) +![clone](https://img.shields.io/badge/dynamic/json?color=success&label=clone&query=count&url=https://github.com/devopscorner/golang-adot/blob/master/clone.json?raw=True&logo=github) +![issues](https://img.shields.io/github/issues/devopscorner/golang-adot) +![pull requests](https://img.shields.io/github/issues-pr/devopscorner/golang-adot) +![forks](https://img.shields.io/github/forks/devopscorner/golang-adot) +![stars](https://img.shields.io/github/stars/devopscorner/golang-adot) +[![license](https://img.shields.io/github/license/devopscorner/golang-adot)](https://img.shields.io/github/license/devopscorner/golang-adot) + +--- + +## Workflow CI/CD Pipeline + +- Create Container Image CI/CD CodeBuild, refer to this repository: [DevOpsCorner CI/CD CodeBuild](https://github.com/devopscorner/devopscorner-container/tree/main/compose/docker/cicd-codebuild) + +- Create HelmChart Template Global, go to [this](https://github.com/devopscorner/devopscorner-helm) section + - `api` + - `backend` + - `frontend` + - `stateful` + - `secretref` + - `svcrole` +- Deploy HelmChart Template Global to S3 + - `AWS_REGION=us-west-2 helm repo add devopscorner-lab s3://devopscorner-adot-chart/lab` + - `AWS_REGION=us-west-2 helm repo add devopscorner-staging s3://devopscorner-adot-chart/staging` + - `AWS_REGION=us-west-2 helm repo add devopscorner-prod s3://devopscorner-adot-chart/prod` +- Create HelmChart Template for GO App + - Helm template GO App (`_infra/{env}/helm-template.yml`) + - Helm value GO App (`_infra/{env}/helm-value.yml`) + +- Create `Dockerfile` for Container GO App CI/CD +- Create Script CI/CD + - `ecr-build.sh` + - `ecr-push.sh` + - `ecr-tag.sh` + - `git-clone.sh` + - `Makefile` + +- Register Container Image GO App to Amazon ECR (Container Registry) +- Create script for Building Container Image GO App (`.aws/buildspec-build.yml`) +- Create script for Deployment Container Image GO App to EKS (`.aws/buildspec-deploy.yml`) +- Setup Variable Environment / Using Config Secret with **AWS Systems Manager (Parameter Store)** + +- Create Pipeline with AWS CodePipeline + - **Source**: Reference from CodeCommit and/or 3rd Party Repository (GitHub, GitLab, BitBucket, Azure DevOps) + - **Build**: Building Container GO App + - Golang Unit Test + - Code Quality and Code Security + - Build Container GO App + - Tagging Container GO App + - Push Container GO App to Container Registry (ECR / Dockerhub) + - **Deploy**: Deploy Container GO App + - **Static Application Security Testing (SAST)**, or static analysis + - Manual Approval + - **Deploy-DEV** + - Manual Approval + - **Deploy-UAT** + - **Dynamic Application Security Testing (DAST)** + - Manual Approval + - **Deploy-PROD** + +- Running Deployment: Commit -> Push -> Webhook (CodeCommit) + +- CodeBuild Process + - Build Container + - Environment Image: `aws/codebuild/amazonlinux2-x86_64-standard:4.0` + - Environment Type: `Linux` + - Buildspec: `.aws/buildspec-build.yml` + - Deploy Container + - Environment Image: `devopscorner/cicd:codebuild-4.0` or `YOUR_AWS_ACCOUNT.dkr.ecr.us-west-2.amazonaws.com/devopscorner/cicd:codebuild-4.0` + - Environment Type: `Linux` + - Buildspec: `.aws/buildspec-deploy.yml` diff --git a/ecr-build.sh b/ecr-build.sh new file mode 100755 index 00000000..3484c00d --- /dev/null +++ b/ecr-build.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env sh +# ----------------------------------------------------------------------------- +# Docker Build Container (Elastic Container Registry - ECR) +# ----------------------------------------------------------------------------- +# Author : Dwi Fahni Denni +# License : Apache v2 +# ----------------------------------------------------------------------------- +set -e + +export AWS_ACCOUNT_ID=$1 +export AWS_DEFAULT_REGION="us-west-2" +export CI_REGISTRY="$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com" +export CI_ECR_PATH=$3 + +export IMAGE="$CI_REGISTRY/$CI_ECR_PATH" + +docker_build() { + export FILE=$2 + export BASE_IMAGE=$4 + export TAGS_ID=$5 + export CUSTOM_TAGS=$6 + + if [ "$CUSTOM_TAGS" = "" ]; then + echo "Build Image => $IMAGE:$BASE_IMAGE" + echo ">> docker build -t $IMAGE:$BASE_IMAGE -f $FILE ." + docker build -t $IMAGE:$BASE_IMAGE -f $FILE . + echo '---' + + echo "Build Image => $IMAGE:$TAGS_ID" + echo ">> docker build -t $IMAGE:$TAGS_ID -f $FILE ." + docker build -t $IMAGE:$TAGS_ID -f $FILE . + echo '---' + + echo "Build Image => $IMAGE:$BASE_IMAGE-$TAGS_ID" + echo ">> docker build -t $IMAGE:$BASE_IMAGE-$TAGS_ID -f $FILE ." + docker build -t $IMAGE:$BASE_IMAGE-$TAGS_ID -f $FILE . + echo '---' + else + echo "Build Image => $IMAGE:$BASE_IMAGE" + echo ">> docker build -t $IMAGE:$BASE_IMAGE -f $FILE ." + docker build -t $IMAGE:$BASE_IMAGE -f $FILE . + echo '---' + + echo "Build Image => $IMAGE:$TAGS_ID" + echo "docker build -t $IMAGE:$TAGS_ID -f $FILE ." + docker build -t $IMAGE:$TAGS_ID -f $FILE . + echo '---' + + echo "Build Image => $IMAGE:$BASE_IMAGE-$TAGS_ID" + echo ">> docker build -t $IMAGE:$BASE_IMAGE-$TAGS_ID -f $FILE ." + docker build -t $IMAGE:$BASE_IMAGE-$TAGS_ID -f $FILE . + echo '---' + + echo "Build Image => $IMAGE:$TAGS_ID-${CUSTOM_TAGS}" + docker build -t $IMAGE:$TAGS_ID-${CUSTOM_TAGS} -f $FILE . + echo ">> docker build -t $IMAGE:$TAGS_ID-${CUSTOM_TAGS} -f $FILE ." + echo '---' + + echo "Build Image => $IMAGE:$BASE_IMAGE-$TAGS_ID-${CUSTOM_TAGS}" + echo ">> docker build -t $IMAGE:$BASE_IMAGE-$TAGS_ID-${CUSTOM_TAGS} -f $FILE ." + docker build -t $IMAGE:$BASE_IMAGE-$TAGS_ID-${CUSTOM_TAGS} -f $FILE . + echo '---' + fi +} + +main() { + # docker_build 0987654321 Dockerfile devopscorner/bookstore-adot alpine [version|latest|tags] [custom-tags] + # docker_build 0987654321 Dockerfile.alpine-3.16 devopscorner/bookstore-adot alpine [version|latest|tags] [custom-tags] + # docker_build 0987654321 Dockerfile.alpine-3.17 devopscorner/bookstore-adot alpine [version|latest|tags] [custom-tags] + docker_build $1 $2 $3 $4 $5 $6 + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main $1 $2 $3 $4 $5 $6 + +### How to Execute ### +# ./ecr-build.sh [AWS_ACCOUNT] Dockerfile [ECR_PATH] [alpine] [version|latest|tags] [custom-tags] diff --git a/ecr-pull.sh b/ecr-pull.sh new file mode 100755 index 00000000..52e54183 --- /dev/null +++ b/ecr-pull.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env sh +# ----------------------------------------------------------------------------- +# Docker Pull Container +# ----------------------------------------------------------------------------- +# Author : Dwi Fahni Denni +# License : Apache v2 +# ----------------------------------------------------------------------------- +set -e + +export AWS_ACCOUNT_ID=$1 +export AWS_DEFAULT_REGION="us-west-2" +export CI_REGISTRY="$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com" +export CI_ECR_PATH=$2 + +export IMAGE="$CI_REGISTRY/$CI_ECR_PATH" + +# export CICD_VERSION="1.23" +# export ALPINE_VERSION="3.17" +# export UBUNTU_VERSION="22.04" +# export CODEBUILD_VERSION="4.0" + +login_ecr() { + echo "=============" + echo " Login ECR " + echo "=============" + PASSWORD=$(aws ecr get-login-password --region $AWS_DEFAULT_REGION) + echo $PASSWORD | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com + echo '- DONE -' + echo '' +} + +docker_pull() { + export TAGS_ID=$2 + echo "Docker Pull => $IMAGE:$TAGS_ID" + echo ">> docker pull $IMAGE:$TAGS_ID" + docker pull $IMAGE:$TAGS_ID + echo '- DONE -' + echo '' +} + +main() { + login_ecr + # docker_pull 0987654321 devopscorner/bookstore-adot alpine + docker_pull $AWS_ACCOUNT_ID $2 $3 + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main $1 $2 $3 + +### How to Execute ### +# ./ecr-pull.sh [AWS_ACCOUNT] [ECR_PATH] [alpine|version|latest|tags|custom-tags] \ No newline at end of file diff --git a/ecr-push.sh b/ecr-push.sh new file mode 100755 index 00000000..78cf9d5e --- /dev/null +++ b/ecr-push.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env sh +# ----------------------------------------------------------------------------- +# Docker Push Container (Elastic Container Registry - ECR) +# ----------------------------------------------------------------------------- +# Author : Dwi Fahni Denni +# License : Apache v2 +# ----------------------------------------------------------------------------- +set -e + +export AWS_ACCOUNT_ID=$1 +export AWS_DEFAULT_REGION="us-west-2" +export CI_REGISTRY="$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com" +export CI_ECR_PATH=$2 + +export IMAGE="$CI_REGISTRY/$CI_ECR_PATH" + +login_ecr() { + echo "=============" + echo " Login ECR " + echo "=============" + PASSWORD=$(aws ecr get-login-password --region $AWS_DEFAULT_REGION) + echo $PASSWORD | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com + echo '- DONE -' + echo '' +} + +docker_push() { + export TAGS_ID=$3 + IMAGES=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep $IMAGE:${TAGS_ID}) + for IMG in $IMAGES; do + echo "Docker Push => $IMG" + echo ">> docker push $IMG" + docker push $IMG + echo '- DONE -' + echo '' + done +} + +main() { + login_ecr + # docker_push 0987654321 devopscorner/bookstore-adot [alpine|version|latest|tags|custom-tags] + docker_push $1 $2 $3 + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main $1 $2 $3 + +### How to Execute ### +# ./ecr-push.sh [AWS_ACCOUNT] [ECR_PATH] [alpine|latest|tags|custom-tags] diff --git a/ecr-tag.sh b/ecr-tag.sh new file mode 100755 index 00000000..bb517f00 --- /dev/null +++ b/ecr-tag.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env sh +# ----------------------------------------------------------------------------- +# Docker Tag Container (Elastic Container Registry - ECR) +# ----------------------------------------------------------------------------- +# Author : Dwi Fahni Denni +# License : Apache v2 +# ----------------------------------------------------------------------------- +set -e + +export AWS_ACCOUNT_ID=$1 +export AWS_DEFAULT_REGION="us-west-2" +export CI_REGISTRY="$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com" +export CI_ECR_PATH=$2 + +export IMAGE="$CI_REGISTRY/$CI_ECR_PATH" + +set_tag() { + export BASE_IMAGE=$3 + export TAGS_ID=$4 + export CUSTOM_TAGS=$5 + export COMMIT_HASH=$(git log -1 --format=format:"%H") + + if [ "$CUSTOM_TAGS" = "" ]; then + export TAGS="$TAGS_ID \ + $BASE_IMAGE-$TAGS_ID \ + $TAGS_ID-$COMMIT_HASH \ + $BASE_IMAGE-$COMMIT_HASH " + else + export TAGS="$TAGS_ID \ + $BASE_IMAGE-$TAGS_ID \ + $TAGS_ID-$COMMIT_HASH \ + $BASE_IMAGE-$COMMIT_HASH \ + $TAGS_ID-$CUSTOM_TAGS" + fi +} + +docker_tag() { + for TAG in $TAGS; do + echo "Docker Tags => $IMAGE:$TAG" + echo ">> docker tag $IMAGE:$BASE_IMAGE $IMAGE:$TAG" + docker tag $IMAGE:$BASE_IMAGE $IMAGE:$TAG + echo '- DONE -' + echo '' + done +} + +main() { + # set_tag 0987654321 devopscorner/bookstore-adot alpine [version|latest|tags] [custom-tags] + set_tag $1 $2 $3 $4 $5 + docker_tag + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main $1 $2 $3 $4 $5 + +### How to Execute ### +# ./ecr-tag.sh [AWS_ACCOUNT] [ECR_PATH] [alpine|codebuild] [version|latest|tags] [custom-tags] diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 00000000..138852f1 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env ash + +export GIN_MODE=release +export APP_URL=http://localhost +export APP_PORT=8080 + +# Connection Type: sqlite / mysql / postgres / dynamo +export DB_CONNECTION=sqlite +export DB_HOST=localhost +export DB_PORT= +export DB_DATABASE=go-bookstore.db +export DB_USERNAME=root +export DB_PASSWORD= + +export JWT_AUTH_USERNAME=devopscorner +export JWT_AUTH_PASSWORD=DevOpsCorner2023 +export JWT_SECRET=s3cr3t + +export LOG_LEVEL=INFO + +export AWS_REGION=us-west-2 +export AWS_ACCESS_KEY=YOUR_AWS_ACCESS_KEY +export AWS_SECRET_KEY_ID=YOUR_AWS_SECRET_KEY_ID + +export OPENSEARCH_ENDPOINT=https://opensearch.us-west-2.es.amazonaws.com +export OPENSEARCH_USERNAME=devopscorner +export OPENSEARCH_PASSWORD=DevOpsCorner2023 + +export PROMETHEUS_ENDPOINT=http://localhost:9090 + +export GRAFANA_ENDPOINT=http://localhost:3000 +export GRAFANA_API_KEY=YOUR_GRAFANA_API_KEY + +export OTEL_INSTRUMENTATION_METRIC_ENABLED=true +export OTEL_INSTRUMENTATION_TRACE_ENABLED=true +export OTEL_INSTRUMENTATION_LOG_ENABLED=true + +# Trace Type: xray / jaeger +export OTEL_INSTRUMENTATION_TRACE_NAME=xray + +export OTEL_SERVICE_NAME=bookstore-adot +export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 +export OTEL_EXPORTER_OTLP_INSECURE=true +export OTEL_EXPORTER_OTLP_HEADERS= +export OTEL_RESOURCE_ATTRIBUTES= + +export XRAY_VERSION=latest + +export JAEGER_AGENT_PORT=6831 +# Sampler Type: const / probabilistic / rateLimiting / remote +export JAEGER_SAMPLER_TYPE=const +export JAEGER_SAMPLER_PARAM=1 +export JAEGER_SAMPLER_MANAGER_HOST_PORT= +export JAEGER_REPORTER_LOG_SPANS=true +# Interval in seconds (5*time.Second) +export JAEGER_REPORTER_BUFFER_FLUSH_INTERVAL="5*time.Second" +export JAEGER_REPORTER_MAX_QUEUE_SIZE=100 +export JAEGER_REPORTER_LOCAL_AGENT_HOST_PORT= +export JAEGER_REPORTER_COLLECTOR_ENDPOINT=http://localhost:14268/api/traces +export JAEGER_REPORTER_COLLECTOR_PASSWORD=DevOpsCorner2023 +export JAEGER_TAGS=golang,otel,restful,api,bookstore + +/go/goapp \ No newline at end of file diff --git a/get-community.sh b/get-community.sh new file mode 100755 index 00000000..6a90bf7f --- /dev/null +++ b/get-community.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env sh +# ----------------------------------------------------------------------------- +# Get Community Terraform Submodules +# ----------------------------------------------------------------------------- +# Author : DevOps Engineer (support@devopscorner.id) +# License : Apache v2 +# ----------------------------------------------------------------------------- +set -e + +TITLE="TERRAFORM COMMUNITY SUBMODULES" # script name +VER="2.3" # script version + +PATH_FOLDER=$(pwd) +SUBMODULE_TERRAFORM="${PATH_FOLDER}/module_community.lst" +PATH_MODULES="${PATH_FOLDER}/terraform/modules/providers/aws/community" + +COL_RED="\033[22;31m" +COL_GREEN="\033[22;32m" +COL_BLUE="\033[22;34m" +COL_END="\033[0m" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +print_line0() { + echo "$COL_GREEN=====================================================================================$COL_END" +} + +print_line1() { + echo "$COL_GREEN-------------------------------------------------------------------------------------$COL_END" +} + +print_line2() { + echo "-------------------------------------------------------------------------------------" +} + +logo() { + clear + print_line0 + echo "$COL_RED'########:'########:'########:::'#######:::'######::::'#####:::'########:::'#######:: $COL_END" + echo "$COL_RED..... ##:: ##.....:: ##.... ##:'##.... ##:'##... ##::'##.. ##:: ##.... ##:'##.... ##: $COL_END" + echo "$COL_RED:::: ##::: ##::::::: ##:::: ##: ##:::: ##: ##:::..::'##:::: ##: ##:::: ##:..::::: ##: $COL_END" + echo "$COL_RED::: ##:::: ######::: ########:: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::'#######:: $COL_END" + echo "$COL_RED:: ##::::: ##...:::: ##.. ##::: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::...... ##: $COL_END" + echo "$COL_RED: ##:::::: ##::::::: ##::. ##:: ##:::: ##: ##::: ##:. ##:: ##:: ##:::: ##:'##:::: ##: $COL_END" + echo "$COL_RED ########: ########: ##:::. ##:. #######::. ######:::. #####::: ########::. #######:: $COL_END" + echo "$COL_RED........::........::..:::::..:::.......::::......:::::.....::::........::::.......::: $COL_END" + print_line1 + echo "$COL_GREEN# $TITLE :: ver-$VER $COL_END" +} + +header() { + logo + print_line0 + get_time + echo "$COL_RED# BEGIN PROCESS..... (Please Wait) $COL_END" + echo "$COL_RED# Start at: $DATE $COL_END\n" +} + +footer() { + print_line0 + get_time + echo "$COL_RED# Finish at: $DATE $COL_END" + echo "$COL_RED# END PROCESS..... $COL_END\n" +} + +skip_exists() { + if [[ -f "$1" ]]; then + echo ">> Skip for existing file $1 ..." + else + git clone --depth 1 $1 + fi +} + +submodule_terrafom() { + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Download Community Submodule(s): $COL_END" + + cd $PATH_MODULES + while IFS= read line; do + get_time + print_line2 + echo "$COL_GREEN[ $DATE ] git clone --depth 1 $line $COL_END" + print_line2 + # skip_exists $line + git clone --depth 1 $line + echo "" + done <"$SUBMODULE_TERRAFORM" + echo '- DOWNLOAD DONE -' +} + +main() { + header + submodule_terrafom + footer +} + +### START HERE ### +main $@ \ No newline at end of file diff --git a/get-modules-codebuild.sh b/get-modules-codebuild.sh new file mode 100755 index 00000000..c048f1fc --- /dev/null +++ b/get-modules-codebuild.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env sh +# ----------------------------------------------------------------------------- +# Get Terraform Submodules (Inside CodeBuild) +# ----------------------------------------------------------------------------- +# Author : DevOps Engineer (support@devopscorner.id) +# License : Apache v2 +# ----------------------------------------------------------------------------- +set -e + +TITLE="TERRAFORM SUBMODULES" # script name +VER="2.3" # script version + +PATH_CODEBUILD="${CODEBUILD_SRC_DIR}" +SUBMODULE_TERRAFORM_COMMUNITY="${CODEBUILD_SRC_DIR}/module_community.lst" +SUBMODULE_TERRAFORM_OFFICIALS="${CODEBUILD_SRC_DIR}/module_officials.lst" +PATH_MODULES="${PATH_CODEBUILD}/terraform/modules/providers/aws" +PATH_MODULES_COMMUNITY="${PATH_MODULES}/community" +PATH_MODULES_OFFICIALS="${PATH_MODULES}/officials" + +COL_RED="\033[22;31m" +COL_GREEN="\033[22;32m" +COL_BLUE="\033[22;34m" +COL_END="\033[0m" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +print_line0() { + echo "$COL_GREEN=====================================================================================$COL_END" +} + +print_line1() { + echo "$COL_GREEN-------------------------------------------------------------------------------------$COL_END" +} + +print_line2() { + echo "-------------------------------------------------------------------------------------" +} + +logo() { + clear + print_line0 + echo "$COL_RED'########:'########:'########:::'#######:::'######::::'#####:::'########:::'#######:: $COL_END" + echo "$COL_RED..... ##:: ##.....:: ##.... ##:'##.... ##:'##... ##::'##.. ##:: ##.... ##:'##.... ##: $COL_END" + echo "$COL_RED:::: ##::: ##::::::: ##:::: ##: ##:::: ##: ##:::..::'##:::: ##: ##:::: ##:..::::: ##: $COL_END" + echo "$COL_RED::: ##:::: ######::: ########:: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::'#######:: $COL_END" + echo "$COL_RED:: ##::::: ##...:::: ##.. ##::: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::...... ##: $COL_END" + echo "$COL_RED: ##:::::: ##::::::: ##::. ##:: ##:::: ##: ##::: ##:. ##:: ##:: ##:::: ##:'##:::: ##: $COL_END" + echo "$COL_RED ########: ########: ##:::. ##:. #######::. ######:::. #####::: ########::. #######:: $COL_END" + echo "$COL_RED........::........::..:::::..:::.......::::......:::::.....::::........::::.......::: $COL_END" + print_line1 + echo "$COL_GREEN# $TITLE :: ver-$VER $COL_END" +} + +header() { + logo + print_line0 + get_time + echo "$COL_RED# BEGIN PROCESS..... (Please Wait) $COL_END" + echo "$COL_RED# Start at: $DATE $COL_END\n" +} + +footer() { + print_line0 + get_time + echo "$COL_RED# Finish at: $DATE $COL_END" + echo "$COL_RED# END PROCESS..... $COL_END\n" +} + +skip_exists() { + if [[ -f "$1" ]]; then + echo ">> Skip for existing file $1 ..." + else + git clone --depth 1 $1 + fi +} + +submodule_cleanup(){ + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Rebuild Submodule(s): $COL_END" + + cd ${PATH_CODEBUILD} + rm -rf modules + + mkdir -p ${PATH_MODULES_COMMUNITY} + mkdir -p ${PATH_MODULES_OFFICIALS} + echo '- REBUILD DONE -' +} + +submodule_terrafom_community() { + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Download Community Submodule(s): $COL_END" + submodule_download $PATH_MODULES_COMMUNITY $SUBMODULE_TERRAFORM_COMMUNITY +} + +submodule_terrafom_officials() { + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Download Officials Submodule(s): $COL_END" + submodule_download $PATH_MODULES_OFFICIALS $SUBMODULE_TERRAFORM_OFFICIALS +} + +submodule_download() { + cd $1 + while IFS= read line; do + get_time + print_line2 + echo "$COL_GREEN[ $DATE ] git clone --depth 1 $line $COL_END" + print_line2 + # skip_exists $line + git clone --depth 1 $line + echo "" + done <"$2" + echo '- DOWNLOAD DONE -' +} + +main() { + header + submodule_cleanup + submodule_terrafom_community + submodule_terrafom_officials + footer +} + +### START HERE ### +main $@ diff --git a/get-officials.sh b/get-officials.sh new file mode 100755 index 00000000..eaecc632 --- /dev/null +++ b/get-officials.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env sh +# ----------------------------------------------------------------------------- +# Get Official Terraform Submodules +# ----------------------------------------------------------------------------- +# Author : DevOps Engineer DevOpsCornerId (support@devopscorner.id) +# License : Apache v2 +# ----------------------------------------------------------------------------- +set -e + +TITLE="TERRAFORM OFFICIAL SUBMODULES" # script name +VER="2.3" # script version + +PATH_FOLDER=$(pwd) +SUBMODULE_TERRAFORM="${PATH_FOLDER}/module_officials.lst" +PATH_MODULES="${PATH_FOLDER}/terraform/modules/providers/aws/officials" + +COL_RED="\033[22;31m" +COL_GREEN="\033[22;32m" +COL_BLUE="\033[22;34m" +COL_END="\033[0m" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +print_line0() { + echo "$COL_GREEN=====================================================================================$COL_END" +} + +print_line1() { + echo "$COL_GREEN-------------------------------------------------------------------------------------$COL_END" +} + +print_line2() { + echo "-------------------------------------------------------------------------------------" +} + +logo() { + clear + print_line0 + echo "$COL_RED'########:'########:'########:::'#######:::'######::::'#####:::'########:::'#######:: $COL_END" + echo "$COL_RED..... ##:: ##.....:: ##.... ##:'##.... ##:'##... ##::'##.. ##:: ##.... ##:'##.... ##: $COL_END" + echo "$COL_RED:::: ##::: ##::::::: ##:::: ##: ##:::: ##: ##:::..::'##:::: ##: ##:::: ##:..::::: ##: $COL_END" + echo "$COL_RED::: ##:::: ######::: ########:: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::'#######:: $COL_END" + echo "$COL_RED:: ##::::: ##...:::: ##.. ##::: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::...... ##: $COL_END" + echo "$COL_RED: ##:::::: ##::::::: ##::. ##:: ##:::: ##: ##::: ##:. ##:: ##:: ##:::: ##:'##:::: ##: $COL_END" + echo "$COL_RED ########: ########: ##:::. ##:. #######::. ######:::. #####::: ########::. #######:: $COL_END" + echo "$COL_RED........::........::..:::::..:::.......::::......:::::.....::::........::::.......::: $COL_END" + print_line1 + echo "$COL_GREEN# $TITLE :: ver-$VER $COL_END" +} + +header() { + logo + print_line0 + get_time + echo "$COL_RED# BEGIN PROCESS..... (Please Wait) $COL_END" + echo "$COL_RED# Start at: $DATE $COL_END\n" +} + +footer() { + print_line0 + get_time + echo "$COL_RED# Finish at: $DATE $COL_END" + echo "$COL_RED# END PROCESS..... $COL_END\n" +} + +skip_exists() { + if [[ -f "$1" ]]; then + echo ">> Skip for existing file $1 ..." + else + git clone --depth 1 $1 + fi +} + +submodule_terrafom() { + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Download Official Submodule(s): $COL_END" + + cd $PATH_MODULES + while IFS= read line; do + get_time + print_line2 + echo "$COL_GREEN[ $DATE ] git clone --depth 1 $line $COL_END" + print_line2 + # skip_exists $line + git clone --depth 1 $line + echo "" + done <"$SUBMODULE_TERRAFORM" + echo "- DOWNLOAD DONE -" +} + +main() { + header + submodule_terrafom + footer +} + +### START HERE ### +main $@ diff --git a/git-clone.sh b/git-clone.sh new file mode 100755 index 00000000..edb9ee26 --- /dev/null +++ b/git-clone.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env sh +# ----------------------------------------------------------------------------- +# Clone Repository +# ----------------------------------------------------------------------------- +# Author : Dwi Fahni Denni +# License : Apache v2 +# ----------------------------------------------------------------------------- +set -e + +GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa -o IdentitiesOnly=yes -F /dev/null' git clone --depth 5 $1 $2 diff --git a/helm/template/README-test.md b/helm/template/README-test.md new file mode 100644 index 00000000..e2d44bae --- /dev/null +++ b/helm/template/README-test.md @@ -0,0 +1,70 @@ +## README How To Test + +### Prerequirements + +- Add Helm repository + + ``` + ### LAB ### + helm s3 init s3://devopscorner-adot-chart/lab + AWS_REGION=us-west-2 helm repo add devopscorner-adot-lab s3://devopscorner-adot-chart/lab + + ### STAGING ### + helm s3 init s3://devopscorner-adot-chart/staging + AWS_REGION=us-west-2 helm repo add devopscorner-adot-staging s3://devopscorner-adot-chart/staging + + ### PRODUCTION ### + helm s3 init s3://devopscorner-adot-chart/prod + AWS_REGION=us-west-2 helm repo add devopscorner-adot s3://devopscorner-adot-chart/prod + + helm repo update + ``` + +### Helm Production + +- Test Rendering + + ``` + cd prod + helm template api -f api/values.yaml + helm template backend -f backend/values.yaml + helm template frontend -f frontend/values.yaml + helm template stateful -f stateful/values.yaml + helm template config -f config/values.yaml + helm template secret -f secret/values.yaml + ``` + +- Test Deploy + + ``` + helmfile -f test/prod/prod-helm-120-template.yml + ``` + +### Helm Staging and Helm Lab + +- Test Rendering + + ``` + cd lab + helm template api -f api/values.yaml + helm template backend -f backend/values.yaml + helm template frontend -f frontend/values.yaml + helm template stateful -f stateful/values.yaml + helm template config -f config/values.yaml + helm template secret -f secret/values.yaml + + cd staging + helm template api -f api/values.yaml + helm template backend -f backend/values.yaml + helm template frontend -f frontend/values.yaml + helm template stateful -f stateful/values.yaml + helm template config -f config/values.yaml + helm template secret -f secret/values.yaml + ``` + +- Test Deploy + + ``` + helmfile -f test/staging-lab/lab-helm-120-template.yml + helmfile -f test/staging-lab/staging-helm-120-template.yml + ``` diff --git a/helm/template/helm-deploy.pipeline b/helm/template/helm-deploy.pipeline new file mode 100644 index 00000000..868f5218 --- /dev/null +++ b/helm/template/helm-deploy.pipeline @@ -0,0 +1,52 @@ +def GITHUB_REPO = 'https://github.com/devopscorner/golang-adot' + +node { + parameters { + string(name: 'HELM_ENV', defaultValue: 'lab', description: 'Enter Environment') + string(name: 'HELM_VERSION', defaultValue: '1.4.0-rc', description: 'Enter Version Number') + string(name: 'HELM_REPO_PATH', defaultValue: 's3://devopscorner-adot-chart/lab', description: 'Enter Helm Repo S3 Path') + string(name: 'HELM_REPO_NAME', defaultValue: 'devopscorner-lab', description: 'Enter Helm Repo Name') + } + stage('Clone'){ + checkout([$class: 'GitSCM', branches: [[name: '*/develop']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', depth: 2, noTags: true, reference: '', shallow: true]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'github', url: GITHUB_REPO]]]) + } + stage('Helm Pack'){ + withEnv([ + "env=$HELM_ENV", + "ver=$HELM_VERSION", + "repo_path=$HELM_REPO_PATH", + "repo_name=$HELM_REPO_NAME", + ]) { + dir("template"){ + sh ''' + export TERM=xterm + export PATH_SCRIPT=`pwd` + sh $PATH_SCRIPT/helm-pack-jenkins.sh $env $ver $repo_path $repo_name + ''' + } + } + } + stage('Helm Push'){ + withEnv([ + "env=$HELM_ENV", + "ver=$HELM_VERSION", + "repo_path=$HELM_REPO_PATH", + "repo_name=$HELM_REPO_NAME", + ]) { + dir("template"){ + sh ''' + export TERM=xterm + export PATH_SCRIPT=`pwd` + sh $PATH_SCRIPT/helm-push-jenkins.sh $env $ver $repo_path $repo_name + ''' + } + } + } + stage('Helm Update'){ + sh ''' + export TERM=xterm + export PATH_SCRIPT=`pwd` + helm repo update + ''' + } +} \ No newline at end of file diff --git a/helm/template/helm-pack-jenkins.sh b/helm/template/helm-pack-jenkins.sh new file mode 100755 index 00000000..e793a774 --- /dev/null +++ b/helm/template/helm-pack-jenkins.sh @@ -0,0 +1,133 @@ +#!/bin/sh + +### Script Jenkins Pipeline +# Using Parameters: +# 1. Environment (lab, prod, staging) +# 2. Helm Version +# 3. Helm Repo Path +# 4. Helm Repo Name + +### How to Use: +# ./helm-pack-jenkins.sh lab 1.0.0-rc s3://devopscorner-adot-chart/lab devopscorner-lab + +set -e + +TITLE="HELM PACKAGE SCRIPT" # script name +VER="2.2" # script version + +HELM_ENVIRONMENT=`pwd`/$1 +HELM_VERSION=$2 +HELM_TEMPLATE="api \ + backend \ + configmap \ + frontend \ + secretref \ + stateful \ + svcrole +" +HELM_REPO_PATH=$3 +HELM_REPO_NAME=$4 + +COL_RED="\033[22;31m" +COL_GREEN="\033[22;32m" +COL_BLUE="\033[22;34m" +COL_END="\033[0m" + +get_time() { + DATE=`date '+%Y-%m-%d %H:%M:%S'` +} + +print_line0() { + echo "$COL_GREEN=====================================================================================$COL_END" +} + +print_line1() { + echo "$COL_GREEN-------------------------------------------------------------------------------------$COL_END" +} + +print_line2() { + echo "-------------------------------------------------------------------------------------" +} + +logo() { + clear + print_line0 + echo "$COL_RED'########:'########:'########:::'#######:::'######::::'#####:::'########:::'#######:: $COL_END" + echo "$COL_RED..... ##:: ##.....:: ##.... ##:'##.... ##:'##... ##::'##.. ##:: ##.... ##:'##.... ##: $COL_END" + echo "$COL_RED:::: ##::: ##::::::: ##:::: ##: ##:::: ##: ##:::..::'##:::: ##: ##:::: ##:..::::: ##: $COL_END" + echo "$COL_RED::: ##:::: ######::: ########:: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::'#######:: $COL_END" + echo "$COL_RED:: ##::::: ##...:::: ##.. ##::: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::...... ##: $COL_END" + echo "$COL_RED: ##:::::: ##::::::: ##::. ##:: ##:::: ##: ##::: ##:. ##:: ##:: ##:::: ##:'##:::: ##: $COL_END" + echo "$COL_RED ########: ########: ##:::. ##:. #######::. ######:::. #####::: ########::. #######:: $COL_END" + echo "$COL_RED........::........::..:::::..:::.......::::......:::::.....::::........::::.......::: $COL_END" + print_line1 + echo "$COL_BLUE# $TITLE :: ver-$VER $COL_END" + echo "$COL_GREEN# HELM CHART :: ver-$HELM_VERSION $COL_END" + echo "$COL_GREEN# HELM REPO PATH :: $HELM_REPO_PATH $COL_END" + echo "$COL_GREEN# HELM REPO NAME :: $HELM_REPO_NAME $COL_END" +} + +header() { + logo + print_line0 + get_time + echo "$COL_RED# BEGIN PROCESS..... (Please Wait) $COL_END" + echo "$COL_RED# Start at: $DATE $COL_END" +} + +footer() { + echo "" + print_line0 + get_time + echo "$COL_RED# Finish at: $DATE $COL_END" + echo "$COL_RED# END PROCESS..... $COL_END\n" +} + +remove_old() { + cd $HELM_ENVIRONMENT + for TEMPL in $HELM_TEMPLATE + do + msg_remove $TEMPL + rm -f $TEMPL-*.tgz + echo "- DONE -" + done +} + +packaging() { + for TEMPL in $HELM_TEMPLATE + do + msg_package $TEMPL + helm package $TEMPL + echo "- DONE -" + done +} + +msg_remove() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Remove Old Package : $1 " + echo "$COL_GREEN[ $DATE ] rm -f $1-*.tgz $COL_END" + get_time + print_line2 +} + +msg_package() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Packaging Helm : $1 " + echo "$COL_GREEN[ $DATE ] helm package $1 $COL_END" + get_time + print_line2 +} + +main() { + header + remove_old + packaging + footer +} + +### START HERE ### +main $1 $2 $3 $4 diff --git a/helm/template/helm-pack.pipeline b/helm/template/helm-pack.pipeline new file mode 100644 index 00000000..028fdafc --- /dev/null +++ b/helm/template/helm-pack.pipeline @@ -0,0 +1,29 @@ +def GITHUB_REPO = 'https://github.com/devopscorner/golang-adot' + +node { + parameters { + string(name: 'HELM_ENV', defaultValue: 'lab', description: 'Enter Environment') + string(name: 'HELM_VERSION', defaultValue: '1.4.0-rc', description: 'Enter Version Number') + string(name: 'HELM_REPO_PATH', defaultValue: 's3://devopscorner-adot-chart/lab', description: 'Enter Helm Repo S3 Path') + string(name: 'HELM_REPO_NAME', defaultValue: 'devopscorner-lab', description: 'Enter Helm Repo Name') + } + stage('Clone'){ + checkout([$class: 'GitSCM', branches: [[name: '*/develop']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', depth: 2, noTags: true, reference: '', shallow: true]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'github', url: GITHUB_REPO]]]) + } + stage('Helm Pack'){ + withEnv([ + "env=$HELM_ENV", + "ver=$HELM_VERSION", + "repo_path=$HELM_REPO_PATH", + "repo_name=$HELM_REPO_NAME", + ]) { + dir("template"){ + sh ''' + export TERM=xterm + export PATH_SCRIPT=`pwd` + sh $PATH_SCRIPT/helm-pack-jenkins.sh $env $ver $repo_path $repo_name + ''' + } + } + } +} \ No newline at end of file diff --git a/helm/template/helm-push-jenkins.sh b/helm/template/helm-push-jenkins.sh new file mode 100755 index 00000000..c7badd70 --- /dev/null +++ b/helm/template/helm-push-jenkins.sh @@ -0,0 +1,113 @@ +#!/bin/sh + +### Script Jenkins Pipeline +# Using Parameters: +# 1. Environment (lab, prod, staging) +# 2. Helm Version +# 3. Helm Repo Path +# 4. Helm Repo Name + +### How to Use: +# ./helm-push-jenkins.sh lab 1.0.0-rc s3://devopscorner-adot-chart/lab devopscorner-lab + +set -e + +TITLE="HELM PACKAGE SCRIPT" # script name +VER="2.2" # script version + +HELM_ENVIRONMENT=`pwd`/$1 +HELM_VERSION=$2 +HELM_TEMPLATE="api \ + backend \ + configmap \ + frontend \ + secretref \ + stateful \ + svcrole +" +HELM_REPO_PATH=$3 +HELM_REPO_NAME=$4 + +COL_RED="\033[22;31m" +COL_GREEN="\033[22;32m" +COL_BLUE="\033[22;34m" +COL_END="\033[0m" + +get_time() { + DATE=`date '+%Y-%m-%d %H:%M:%S'` +} + +print_line0() { + echo "$COL_GREEN=====================================================================================$COL_END" +} + +print_line1() { + echo "$COL_GREEN-------------------------------------------------------------------------------------$COL_END" +} + +print_line2() { + echo "-------------------------------------------------------------------------------------" +} + +logo() { + clear + print_line0 + echo "$COL_RED'########:'########:'########:::'#######:::'######::::'#####:::'########:::'#######:: $COL_END" + echo "$COL_RED..... ##:: ##.....:: ##.... ##:'##.... ##:'##... ##::'##.. ##:: ##.... ##:'##.... ##: $COL_END" + echo "$COL_RED:::: ##::: ##::::::: ##:::: ##: ##:::: ##: ##:::..::'##:::: ##: ##:::: ##:..::::: ##: $COL_END" + echo "$COL_RED::: ##:::: ######::: ########:: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::'#######:: $COL_END" + echo "$COL_RED:: ##::::: ##...:::: ##.. ##::: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::...... ##: $COL_END" + echo "$COL_RED: ##:::::: ##::::::: ##::. ##:: ##:::: ##: ##::: ##:. ##:: ##:: ##:::: ##:'##:::: ##: $COL_END" + echo "$COL_RED ########: ########: ##:::. ##:. #######::. ######:::. #####::: ########::. #######:: $COL_END" + echo "$COL_RED........::........::..:::::..:::.......::::......:::::.....::::........::::.......::: $COL_END" + print_line1 + echo "$COL_BLUE# $TITLE :: ver-$VER $COL_END" + echo "$COL_GREEN# HELM CHART :: ver-$HELM_VERSION $COL_END" + echo "$COL_GREEN# HELM REPO PATH :: $HELM_REPO_PATH $COL_END" + echo "$COL_GREEN# HELM REPO NAME :: $HELM_REPO_NAME $COL_END" +} + +header() { + logo + print_line0 + get_time + echo "$COL_RED# BEGIN PROCESS..... (Please Wait) $COL_END" + echo "$COL_RED# Start at: $DATE $COL_END" +} + +footer() { + echo "" + print_line0 + get_time + echo "$COL_RED# Finish at: $DATE $COL_END" + echo "$COL_RED# END PROCESS..... $COL_END\n" +} + +push_package() { + cd $HELM_ENVIRONMENT + for TEMPL in $HELM_TEMPLATE + do + msg_push $TEMPL-$HELM_VERSION + helm s3 push $TEMPL-$HELM_VERSION.tgz $HELM_REPO_NAME --force + echo "- DONE -" + done +} + +msg_push() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Push Package Helm : $1 " + echo "$COL_GREEN[ $DATE ] helm s3 push $1.tgz $HELM_REPO_NAME --force $COL_END" + get_time + print_line2 +} + +main() { + header + push_package + footer +} + +### START HERE ### +main $1 $2 $3 $4 diff --git a/helm/template/helm-push.pipeline b/helm/template/helm-push.pipeline new file mode 100644 index 00000000..a4878bca --- /dev/null +++ b/helm/template/helm-push.pipeline @@ -0,0 +1,36 @@ +def GITHUB_REPO = 'https://github.com/devopscorner/golang-adot' + +node { + parameters { + string(name: 'HELM_ENV', defaultValue: 'lab', description: 'Enter Environment') + string(name: 'HELM_VERSION', defaultValue: '1.4.0-rc', description: 'Enter Version Number') + string(name: 'HELM_REPO_PATH', defaultValue: 's3://devopscorner-adot-chart/lab', description: 'Enter Helm Repo S3 Path') + string(name: 'HELM_REPO_NAME', defaultValue: 'devopscorner-lab', description: 'Enter Helm Repo Name') + } + stage('Clone'){ + checkout([$class: 'GitSCM', branches: [[name: '*/develop']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', depth: 2, noTags: true, reference: '', shallow: true]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'github', url: GITHUB_REPO]]]) + } + stage('Helm Push'){ + withEnv([ + "env=$HELM_ENV", + "ver=$HELM_VERSION", + "repo_path=$HELM_REPO_PATH", + "repo_name=$HELM_REPO_NAME", + ]) { + dir("template"){ + sh ''' + export TERM=xterm + export PATH_SCRIPT=`pwd` + sh $PATH_SCRIPT/helm-push-jenkins.sh $env $ver $repo_path $repo_name + ''' + } + } + } + stage('Helm Update'){ + sh ''' + export TERM=xterm + export PATH_SCRIPT=`pwd` + helm repo update + ''' + } +} \ No newline at end of file diff --git a/helm/template/lab/api/.helmignore b/helm/template/lab/api/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/lab/api/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/lab/api/Chart.yaml b/helm/template/lab/api/Chart.yaml new file mode 100644 index 00000000..7da8549f --- /dev/null +++ b/helm/template/lab/api/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: api +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0-rc" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/lab/api/api.yaml b/helm/template/lab/api/api.yaml new file mode 100644 index 00000000..074d358d --- /dev/null +++ b/helm/template/lab/api/api.yaml @@ -0,0 +1,119 @@ +# Default values for api. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +secret: + enabled: false + name: "secret-api" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-api" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Api Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enabled: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: api + +resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/lab/api/templates/_helpers.tpl b/helm/template/lab/api/templates/_helpers.tpl new file mode 100644 index 00000000..5cb8632d --- /dev/null +++ b/helm/template/lab/api/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "api.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "api.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "api.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "api.labels" -}} +helm.sh/chart: {{ include "api.chart" . }} +{{ include "api.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "api.selectorLabels" -}} +app.kubernetes.io/name: {{ include "api.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "api.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "api.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/lab/api/templates/clusterrole.yaml b/helm/template/lab/api/templates/clusterrole.yaml new file mode 100644 index 00000000..9704958d --- /dev/null +++ b/helm/template/lab/api/templates/clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "api.fullname" . }}-rbac +subjects: + - kind: ServiceAccount + name: {{ include "api.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/api/templates/configmap.yaml b/helm/template/lab/api/templates/configmap.yaml new file mode 100644 index 00000000..5bb2f8b9 --- /dev/null +++ b/helm/template/lab/api/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "api.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "api.labels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/api/templates/deployment.yaml b/helm/template/lab/api/templates/deployment.yaml new file mode 100644 index 00000000..ed2824b3 --- /dev/null +++ b/helm/template/lab/api/templates/deployment.yaml @@ -0,0 +1,99 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "api.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "api.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + revisionHistoryLimit: 10 + selector: + matchLabels: + {{- include "api.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "api.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "api.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.application.enabled }} + env: + {{- toYaml .Values.application.env | nindent 12 }} + {{- end }} + {{- if .Values.envFrom.enabled }} + envFrom: + {{- toYaml .Values.envFrom.envFrom | nindent 12 }} + {{- end }} + {{- if .Values.container }} + ports: + {{- with .Values.container.ports }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{ end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumeMounts: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + mountPath: {{ .Values.configMap.mountPath }} + readOnly: {{ .Values.configMap.readOnly }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + mountPath: {{ .Values.secret.mountPath }} + subPath: {{ .Values.secret.subPath }} + readOnly: {{ .Values.secret.readOnly }} + {{- end }} + {{- end }} + {{- if and .Values.volumes .Values.volumes.enabled }} + volumeMounts: + - name: {{ .Values.volumes.name }} + mountPath: {{ .Values.volumes.mountPath }} + {{- end }} + {{- if .Values.nodeSelector.enabled -}} + {{- with .Values.nodeSelector.select }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumes: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + configMap: + name: {{ .Values.configMap.name }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + secret: + secretName: {{ .Values.secret.name }} + {{- end }} + {{- end }} diff --git a/helm/template/lab/api/templates/hpa.yaml b/helm/template/lab/api/templates/hpa.yaml new file mode 100644 index 00000000..b87d6ab1 --- /dev/null +++ b/helm/template/lab/api/templates/hpa.yaml @@ -0,0 +1,29 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "api.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "api.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "api.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/template/lab/api/templates/ingress.yaml b/helm/template/lab/api/templates/ingress.yaml new file mode 100644 index 00000000..2481aebf --- /dev/null +++ b/helm/template/lab/api/templates/ingress.yaml @@ -0,0 +1,32 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "api.fullname" . -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else -}} +apiVersion: extensions/v1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "api.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + {{- with .Values.ingress.hosts }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/api/templates/secret.yaml b/helm/template/lab/api/templates/secret.yaml new file mode 100644 index 00000000..6e392c35 --- /dev/null +++ b/helm/template/lab/api/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "api.labels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/lab/api/templates/service.yaml b/helm/template/lab/api/templates/service.yaml new file mode 100644 index 00000000..a9dc0b71 --- /dev/null +++ b/helm/template/lab/api/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "api.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "api.labels" . | nindent 4 }} +spec: + {{- if .Values.service }} + type: {{ .Values.service.type }} + {{- with .Values.service.ports }} + ports: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + selector: + {{- include "api.selectorLabels" . | nindent 4 }} diff --git a/helm/template/lab/api/templates/serviceaccount.yaml b/helm/template/lab/api/templates/serviceaccount.yaml new file mode 100644 index 00000000..873d15f1 --- /dev/null +++ b/helm/template/lab/api/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "api.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "api.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/lab/api/values.yaml b/helm/template/lab/api/values.yaml new file mode 100644 index 00000000..450ed447 --- /dev/null +++ b/helm/template/lab/api/values.yaml @@ -0,0 +1,115 @@ +--- +replicaCount: 1 + +secret: + enabled: false + name: "secret-api" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-api" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Api Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enabled: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: api + - name: ALLOWED_ORIGINS + value: '*' + - name: PORT + value: "8080" + - name: REFRESH_TOKEN_EXPIRE_HOUR + value: "48" + - name: TOKEN_EXPIRE_HOUR + value: "1" + - name: PASSWORD + valueFrom: + secretKeyRef: + key: password + name: test-secret + +resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/lab/backend/.helmignore b/helm/template/lab/backend/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/lab/backend/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/lab/backend/Chart.yaml b/helm/template/lab/backend/Chart.yaml new file mode 100644 index 00000000..45a3da25 --- /dev/null +++ b/helm/template/lab/backend/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: backend +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0-rc" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/lab/backend/backend.yaml b/helm/template/lab/backend/backend.yaml new file mode 100644 index 00000000..d5e20194 --- /dev/null +++ b/helm/template/lab/backend/backend.yaml @@ -0,0 +1,119 @@ +# Default values for backend. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +secret: + enabled: false + name: "secret-backend" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-backend" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Backend Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enabled: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: backend + +resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/lab/backend/templates/_helpers.tpl b/helm/template/lab/backend/templates/_helpers.tpl new file mode 100644 index 00000000..471310f0 --- /dev/null +++ b/helm/template/lab/backend/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "backend.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "backend.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "backend.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "backend.labels" -}} +helm.sh/chart: {{ include "backend.chart" . }} +{{ include "backend.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "backend.selectorLabels" -}} +app.kubernetes.io/name: {{ include "backend.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "backend.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "backend.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/lab/backend/templates/clusterrole.yaml b/helm/template/lab/backend/templates/clusterrole.yaml new file mode 100644 index 00000000..1f6ec50e --- /dev/null +++ b/helm/template/lab/backend/templates/clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "backend.fullname" . }}-rbac +subjects: + - kind: ServiceAccount + name: {{ include "backend.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/backend/templates/configmap.yaml b/helm/template/lab/backend/templates/configmap.yaml new file mode 100644 index 00000000..b1bbd1ee --- /dev/null +++ b/helm/template/lab/backend/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "backend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "backend.labels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/backend/templates/deployment.yaml b/helm/template/lab/backend/templates/deployment.yaml new file mode 100644 index 00000000..fae6a400 --- /dev/null +++ b/helm/template/lab/backend/templates/deployment.yaml @@ -0,0 +1,99 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "backend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "backend.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + revisionHistoryLimit: 10 + selector: + matchLabels: + {{- include "backend.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "backend.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "backend.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.application.enabled }} + env: + {{- toYaml .Values.application.env | nindent 12 }} + {{- end }} + {{- if .Values.envFrom.enabled }} + envFrom: + {{- toYaml .Values.envFrom.envFrom | nindent 12 }} + {{- end }} + {{- if .Values.container }} + ports: + {{- with .Values.container.ports }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{ end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumeMounts: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + mountPath: {{ .Values.configMap.mountPath }} + readOnly: {{ .Values.configMap.readOnly }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + mountPath: {{ .Values.secret.mountPath }} + subPath: {{ .Values.secret.subPath }} + readOnly: {{ .Values.secret.readOnly }} + {{- end }} + {{- end }} + {{- if and .Values.volumes .Values.volumes.enabled }} + volumeMounts: + - name: {{ .Values.volumes.name }} + mountPath: {{ .Values.volumes.mountPath }} + {{- end }} + {{- if .Values.nodeSelector.enabled -}} + {{- with .Values.nodeSelector.select }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumes: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + configMap: + name: {{ .Values.configMap.name }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + secret: + secretName: {{ .Values.secret.name }} + {{- end }} + {{- end }} diff --git a/helm/template/lab/backend/templates/hpa.yaml b/helm/template/lab/backend/templates/hpa.yaml new file mode 100644 index 00000000..ece60b80 --- /dev/null +++ b/helm/template/lab/backend/templates/hpa.yaml @@ -0,0 +1,29 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "backend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "backend.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "backend.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/template/lab/backend/templates/ingress.yaml b/helm/template/lab/backend/templates/ingress.yaml new file mode 100644 index 00000000..6c2bc877 --- /dev/null +++ b/helm/template/lab/backend/templates/ingress.yaml @@ -0,0 +1,32 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "backend.fullname" . -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else -}} +apiVersion: extensions/v1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "backend.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + {{- with .Values.ingress.hosts }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/backend/templates/secret.yaml b/helm/template/lab/backend/templates/secret.yaml new file mode 100644 index 00000000..30f73eb3 --- /dev/null +++ b/helm/template/lab/backend/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "backend.labels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/lab/backend/templates/service.yaml b/helm/template/lab/backend/templates/service.yaml new file mode 100644 index 00000000..df7f962d --- /dev/null +++ b/helm/template/lab/backend/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "backend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "backend.labels" . | nindent 4 }} +spec: + {{- if .Values.service }} + type: {{ .Values.service.type }} + {{- with .Values.service.ports }} + ports: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + selector: + {{- include "backend.selectorLabels" . | nindent 4 }} diff --git a/helm/template/lab/backend/templates/serviceaccount.yaml b/helm/template/lab/backend/templates/serviceaccount.yaml new file mode 100644 index 00000000..0387d24b --- /dev/null +++ b/helm/template/lab/backend/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "backend.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "backend.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/lab/backend/values.yaml b/helm/template/lab/backend/values.yaml new file mode 100644 index 00000000..2584c5c2 --- /dev/null +++ b/helm/template/lab/backend/values.yaml @@ -0,0 +1,126 @@ +--- +replicaCount: 1 + +secret: + enabled: false + name: "secret-backend" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-backend" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Backend Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: backend + - name: DB_HOST + value: db.internal.service + - name: DB_PORT + value: "5432" + - name: DB_USER + value: postgres + - name: DB_NAME + value: db_name + - name: DB_PASS + valueFrom: + secretKeyRef: + key: db-pass + name: db-secret + - name: DB_TIMEOUT + value: "10" + - name: DB_IDLE_CONN + value: "2" + - name: DB_OPEN_CONN + value: "5" + - name: DB_CONN_LIFETIME + value: "600" + +resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/lab/configmap/Chart.yaml b/helm/template/lab/configmap/Chart.yaml new file mode 100644 index 00000000..f637c2bf --- /dev/null +++ b/helm/template/lab/configmap/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: configmap +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0-rc" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/lab/configmap/configmap.yaml b/helm/template/lab/configmap/configmap.yaml new file mode 100644 index 00000000..c551f4fd --- /dev/null +++ b/helm/template/lab/configmap/configmap.yaml @@ -0,0 +1,12 @@ +configMap: + enabled: true + name: configmap + mountPath: {} + readOnly: true + data: {} + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" \ No newline at end of file diff --git a/helm/template/lab/configmap/templates/_helpers.tpl b/helm/template/lab/configmap/templates/_helpers.tpl new file mode 100644 index 00000000..fa972f28 --- /dev/null +++ b/helm/template/lab/configmap/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "configmap.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "configmap.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "configmap.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "configmap.labels" -}} +helm.sh/chart: {{ include "configmap.chart" . }} +{{ include "configmap.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "configmap.selectorLabels" -}} +app.kubernetes.io/name: {{ include "configmap.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "configmap.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "configmap.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/lab/configmap/templates/configmap.yaml b/helm/template/lab/configmap/templates/configmap.yaml new file mode 100644 index 00000000..0182d63a --- /dev/null +++ b/helm/template/lab/configmap/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.configMap.name }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "configmap.labels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/configmap/values.yaml b/helm/template/lab/configmap/values.yaml new file mode 100644 index 00000000..0ff4af1d --- /dev/null +++ b/helm/template/lab/configmap/values.yaml @@ -0,0 +1,21 @@ +configMap: + enabled: true + name: "configmap" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "configMap Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" \ No newline at end of file diff --git a/helm/template/lab/frontend/.helmignore b/helm/template/lab/frontend/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/lab/frontend/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/lab/frontend/Chart.yaml b/helm/template/lab/frontend/Chart.yaml new file mode 100644 index 00000000..3c79d5b1 --- /dev/null +++ b/helm/template/lab/frontend/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: frontend +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0-rc" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/lab/frontend/frontend.yaml b/helm/template/lab/frontend/frontend.yaml new file mode 100644 index 00000000..55c9b3c0 --- /dev/null +++ b/helm/template/lab/frontend/frontend.yaml @@ -0,0 +1,121 @@ +# Default values for frontend. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +secret: + enabled: false + name: "secret-frontend" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-frontend" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json: |- + { + "AppName": "Frontend Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: + {} + # fsGroup: 2000 + +securityContext: + {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enable: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 3000 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: frontend + +resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/lab/frontend/templates/_helpers.tpl b/helm/template/lab/frontend/templates/_helpers.tpl new file mode 100644 index 00000000..92c6c3b2 --- /dev/null +++ b/helm/template/lab/frontend/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "frontend.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "frontend.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "frontend.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "frontend.labels" -}} +helm.sh/chart: {{ include "frontend.chart" . }} +{{ include "frontend.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "frontend.selectorLabels" -}} +app.kubernetes.io/name: {{ include "frontend.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "frontend.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "frontend.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/lab/frontend/templates/clusterrole.yaml b/helm/template/lab/frontend/templates/clusterrole.yaml new file mode 100644 index 00000000..009f3ee6 --- /dev/null +++ b/helm/template/lab/frontend/templates/clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "frontend.fullname" . }}-rbac +subjects: + - kind: ServiceAccount + name: {{ include "frontend.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/frontend/templates/configmap.yaml b/helm/template/lab/frontend/templates/configmap.yaml new file mode 100644 index 00000000..2b68493f --- /dev/null +++ b/helm/template/lab/frontend/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "frontend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "frontend.labels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/frontend/templates/deployment.yaml b/helm/template/lab/frontend/templates/deployment.yaml new file mode 100644 index 00000000..83dcf742 --- /dev/null +++ b/helm/template/lab/frontend/templates/deployment.yaml @@ -0,0 +1,106 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "frontend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "frontend.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "frontend.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "frontend.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "frontend.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.application.enabled }} + env: + {{- toYaml .Values.application.env | nindent 12 }} + {{- end }} + {{- if .Values.envFrom.enabled }} + envFrom: + {{- toYaml .Values.envFrom.envFrom | nindent 12 }} + {{- end }} + {{- if .Values.container }} + ports: + {{- with .Values.container.ports }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{ end }} + # livenessProbe: + # httpGet: + # path: / + # port: http + # readinessProbe: + # httpGet: + # path: / + # port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumeMounts: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + mountPath: {{ .Values.configMap.mountPath }} + readOnly: {{ .Values.configMap.readOnly }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + mountPath: {{ .Values.secret.mountPath }} + subPath: {{ .Values.secret.subPath }} + readOnly: {{ .Values.secret.readOnly }} + {{- end }} + {{- end }} + {{- if and .Values.volumes .Values.volumes.enabled }} + volumeMounts: + - name: {{ .Values.volumes.name }} + mountPath: {{ .Values.volumes.mountPath }} + {{- end }} + {{- if .Values.nodeSelector.enabled -}} + {{- with .Values.nodeSelector.select }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumes: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + configMap: + name: {{ .Values.configMap.name }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + secret: + secretName: {{ .Values.secret.name }} + {{- end }} + {{- end }} diff --git a/helm/template/lab/frontend/templates/hpa.yaml b/helm/template/lab/frontend/templates/hpa.yaml new file mode 100644 index 00000000..18b75bc2 --- /dev/null +++ b/helm/template/lab/frontend/templates/hpa.yaml @@ -0,0 +1,29 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "frontend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "frontend.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "frontend.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/template/lab/frontend/templates/ingress.yaml b/helm/template/lab/frontend/templates/ingress.yaml new file mode 100644 index 00000000..672f79eb --- /dev/null +++ b/helm/template/lab/frontend/templates/ingress.yaml @@ -0,0 +1,32 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "frontend.fullname" . -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else -}} +apiVersion: extensions/v1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "frontend.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + {{- with .Values.ingress.hosts }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/frontend/templates/secret.yaml b/helm/template/lab/frontend/templates/secret.yaml new file mode 100644 index 00000000..ccf67c73 --- /dev/null +++ b/helm/template/lab/frontend/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "frontend.labels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/lab/frontend/templates/service.yaml b/helm/template/lab/frontend/templates/service.yaml new file mode 100644 index 00000000..1c2ae5c8 --- /dev/null +++ b/helm/template/lab/frontend/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "frontend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "frontend.labels" . | nindent 4 }} +spec: + {{- if .Values.service }} + type: {{ .Values.service.type }} + {{- with .Values.service.ports }} + ports: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + selector: + {{- include "frontend.selectorLabels" . | nindent 4 }} diff --git a/helm/template/lab/frontend/templates/serviceaccount.yaml b/helm/template/lab/frontend/templates/serviceaccount.yaml new file mode 100644 index 00000000..f83617f1 --- /dev/null +++ b/helm/template/lab/frontend/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "frontend.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "frontend.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/lab/frontend/values.yaml b/helm/template/lab/frontend/values.yaml new file mode 100644 index 00000000..9dd06f60 --- /dev/null +++ b/helm/template/lab/frontend/values.yaml @@ -0,0 +1,108 @@ +--- +replicaCount: 1 + +secret: + enabled: false + name: "secret-frontend" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-frontend" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Frontend Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + create: false + annotations: {} + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 3000 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: frontend + - name: ALLOWED_ORIGINS + value: '*' + - name: PORT + value: "8080" + - name: REFRESH_TOKEN_EXPIRE_HOUR + value: "48" + - name: TOKEN_EXPIRE_HOUR + value: "1" + +resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/lab/helm-pack-lab.sh b/helm/template/lab/helm-pack-lab.sh new file mode 100755 index 00000000..096f836c --- /dev/null +++ b/helm/template/lab/helm-pack-lab.sh @@ -0,0 +1,121 @@ +#!/bin/sh + +set -e + +TITLE="HELM PACKAGE SCRIPT" # script name +VER="2.2" # script version + +HELM_VERSION="1.4.0-rc" +HELM_TEMPLATE="api \ + backend \ + configmap \ + frontend \ + secretref \ + stateful \ + svcrole +" +HELM_REPO_PATH="s3://devopscorner-adot-chart/lab" +HELM_REPO_NAME="devopscorner-adot-lab" + +COL_RED="\033[22;31m" +COL_GREEN="\033[22;32m" +COL_BLUE="\033[22;34m" +COL_END="\033[0m" + +get_time() { + DATE=`date '+%Y-%m-%d %H:%M:%S'` +} + +print_line0() { + echo "$COL_GREEN=====================================================================================$COL_END" +} + +print_line1() { + echo "$COL_GREEN-------------------------------------------------------------------------------------$COL_END" +} + +print_line2() { + echo "-------------------------------------------------------------------------------------" +} + +logo() { + clear + print_line0 + echo "$COL_RED'########:'########:'########:::'#######:::'######::::'#####:::'########:::'#######:: $COL_END" + echo "$COL_RED..... ##:: ##.....:: ##.... ##:'##.... ##:'##... ##::'##.. ##:: ##.... ##:'##.... ##: $COL_END" + echo "$COL_RED:::: ##::: ##::::::: ##:::: ##: ##:::: ##: ##:::..::'##:::: ##: ##:::: ##:..::::: ##: $COL_END" + echo "$COL_RED::: ##:::: ######::: ########:: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::'#######:: $COL_END" + echo "$COL_RED:: ##::::: ##...:::: ##.. ##::: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::...... ##: $COL_END" + echo "$COL_RED: ##:::::: ##::::::: ##::. ##:: ##:::: ##: ##::: ##:. ##:: ##:: ##:::: ##:'##:::: ##: $COL_END" + echo "$COL_RED ########: ########: ##:::. ##:. #######::. ######:::. #####::: ########::. #######:: $COL_END" + echo "$COL_RED........::........::..:::::..:::.......::::......:::::.....::::........::::.......::: $COL_END" + print_line1 + echo "$COL_BLUE# $TITLE :: ver-$VER $COL_END" + echo "$COL_GREEN# HELM CHART :: ver-$HELM_VERSION $COL_END" + echo "$COL_GREEN# HELM REPO PATH :: $HELM_REPO_PATH $COL_END" + echo "$COL_GREEN# HELM REPO NAME :: $HELM_REPO_NAME $COL_END" +} + +header() { + logo + print_line0 + get_time + echo "$COL_RED# BEGIN PROCESS..... (Please Wait) $COL_END" + echo "$COL_RED# Start at: $DATE $COL_END" +} + +footer() { + echo "" + print_line0 + get_time + echo "$COL_RED# Finish at: $DATE $COL_END" + echo "$COL_RED# END PROCESS..... $COL_END\n" +} + +remove_old() { + for TEMPL in $HELM_TEMPLATE + do + msg_remove $TEMPL + rm -f $TEMPL-*.tgz + echo "- DONE -" + done +} + +packaging() { + for TEMPL in $HELM_TEMPLATE + do + msg_package $TEMPL + helm package $TEMPL + echo "- DONE -" + done +} + +msg_remove() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Remove Old Package : $1 " + echo "$COL_GREEN[ $DATE ] rm -f $1-*.tgz $COL_END" + get_time + print_line2 +} + +msg_package() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Packaging Helm : $1 " + echo "$COL_GREEN[ $DATE ] helm package $1 $COL_END" + get_time + print_line2 +} + +main() { + header + remove_old + packaging + footer +} + +### START HERE ### +main $@ diff --git a/helm/template/lab/helm-push-lab.sh b/helm/template/lab/helm-push-lab.sh new file mode 100755 index 00000000..9b0cb29a --- /dev/null +++ b/helm/template/lab/helm-push-lab.sh @@ -0,0 +1,111 @@ +#!/bin/sh + +set -e + +TITLE="HELM PACKAGE SCRIPT" # script name +VER="2.2" # script version + +HELM_VERSION="1.4.0-rc" +HELM_TEMPLATE="api \ + backend \ + configmap \ + frontend \ + secretref \ + stateful \ + svcrole +" +HELM_REPO_PATH="s3://devopscorner-adot-chart/lab" +HELM_REPO_NAME="devopscorner-adot-lab" + +COL_RED="\033[22;31m" +COL_GREEN="\033[22;32m" +COL_BLUE="\033[22;34m" +COL_END="\033[0m" + +get_time() { + DATE=`date '+%Y-%m-%d %H:%M:%S'` +} + +print_line0() { + echo "$COL_GREEN=====================================================================================$COL_END" +} + +print_line1() { + echo "$COL_GREEN-------------------------------------------------------------------------------------$COL_END" +} + +print_line2() { + echo "-------------------------------------------------------------------------------------" +} + +logo() { + clear + print_line0 + echo "$COL_RED'########:'########:'########:::'#######:::'######::::'#####:::'########:::'#######:: $COL_END" + echo "$COL_RED..... ##:: ##.....:: ##.... ##:'##.... ##:'##... ##::'##.. ##:: ##.... ##:'##.... ##: $COL_END" + echo "$COL_RED:::: ##::: ##::::::: ##:::: ##: ##:::: ##: ##:::..::'##:::: ##: ##:::: ##:..::::: ##: $COL_END" + echo "$COL_RED::: ##:::: ######::: ########:: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::'#######:: $COL_END" + echo "$COL_RED:: ##::::: ##...:::: ##.. ##::: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::...... ##: $COL_END" + echo "$COL_RED: ##:::::: ##::::::: ##::. ##:: ##:::: ##: ##::: ##:. ##:: ##:: ##:::: ##:'##:::: ##: $COL_END" + echo "$COL_RED ########: ########: ##:::. ##:. #######::. ######:::. #####::: ########::. #######:: $COL_END" + echo "$COL_RED........::........::..:::::..:::.......::::......:::::.....::::........::::.......::: $COL_END" + print_line1 + echo "$COL_BLUE# $TITLE :: ver-$VER $COL_END" + echo "$COL_GREEN# HELM CHART :: ver-$HELM_VERSION $COL_END" + echo "$COL_GREEN# HELM REPO PATH :: $HELM_REPO_PATH $COL_END" + echo "$COL_GREEN# HELM REPO NAME :: $HELM_REPO_NAME $COL_END" +} + +header() { + logo + print_line0 + get_time + echo "$COL_RED# BEGIN PROCESS..... (Please Wait) $COL_END" + echo "$COL_RED# Start at: $DATE $COL_END" +} + +footer() { + echo "" + print_line0 + get_time + echo "$COL_RED# Finish at: $DATE $COL_END" + echo "$COL_RED# END PROCESS..... $COL_END\n" +} + +push_package() { + for TEMPL in $HELM_TEMPLATE + do + msg_push $TEMPL + helm s3 push $TEMPL*.tgz $HELM_REPO_NAME --force + echo "- DONE -" + done +} + +msg_push() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Push Package Helm : $1 " + echo "$COL_GREEN[ $DATE ] helm s3 push $1 $HELM_REPO_NAME --force $COL_END" + print_line2 +} + +helm_update() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Update Helm Repository : " + echo "$COL_GREEN[ $DATE ] helm repo update" + helm repo update + echo "- DONE -" +} + +main() { + header + push_package + helm_update + footer +} + +### START HERE ### +main $@ diff --git a/helm/template/lab/secretref/Chart.yaml b/helm/template/lab/secretref/Chart.yaml new file mode 100644 index 00000000..5c60af06 --- /dev/null +++ b/helm/template/lab/secretref/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: secretref +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0-rc" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/lab/secretref/secretref.yaml b/helm/template/lab/secretref/secretref.yaml new file mode 100644 index 00000000..5ae675f2 --- /dev/null +++ b/helm/template/lab/secretref/secretref.yaml @@ -0,0 +1,13 @@ +secret: + enabled: true + name: secretref + mountPath: + subPath: {} + readOnly: true + data: {} + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" \ No newline at end of file diff --git a/helm/template/lab/secretref/templates/_helpers.tpl b/helm/template/lab/secretref/templates/_helpers.tpl new file mode 100644 index 00000000..4bd20cef --- /dev/null +++ b/helm/template/lab/secretref/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "secretref.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "secretref.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "secretref.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "secretref.labels" -}} +helm.sh/chart: {{ include "secretref.chart" . }} +{{ include "secretref.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "secretref.selectorLabels" -}} +app.kubernetes.io/name: {{ include "secretref.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "secretref.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "secretref.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/lab/secretref/templates/secret.yaml b/helm/template/lab/secretref/templates/secret.yaml new file mode 100644 index 00000000..0cfbcad9 --- /dev/null +++ b/helm/template/lab/secretref/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "secret.labels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/lab/secretref/values.yaml b/helm/template/lab/secretref/values.yaml new file mode 100644 index 00000000..3908af5b --- /dev/null +++ b/helm/template/lab/secretref/values.yaml @@ -0,0 +1,16 @@ +secret: + enabled: true + name: psql-cred + mountPath: /app/core/secret + subPath: {} + readOnly: true + data: + db-user: dXNlcm5hbWUK + db-pass: cGFzc3cwcmQK + db-host: MTI3LjAuMC4xCg== + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" \ No newline at end of file diff --git a/helm/template/lab/stateful/.helmignore b/helm/template/lab/stateful/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/lab/stateful/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/lab/stateful/Chart.yaml b/helm/template/lab/stateful/Chart.yaml new file mode 100644 index 00000000..e1998890 --- /dev/null +++ b/helm/template/lab/stateful/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: stateful +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0-rc" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/lab/stateful/stateful.yaml b/helm/template/lab/stateful/stateful.yaml new file mode 100644 index 00000000..f102581f --- /dev/null +++ b/helm/template/lab/stateful/stateful.yaml @@ -0,0 +1,163 @@ +# Default values for spinnaker. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +replicaCount: 1 + +secret: + enabled: false + name: "secret-stateful" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-stateful" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json: |- + { + "AppName": "Stateful Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +livenessProbe: {} +# initialDelaySeconds: 30 +# periodSeconds: 10 +# timeoutSeconds: 5 +# successThreshold: 1 +# failureThreshold: 3 + +readinessProbe: {} +# initialDelaySeconds: 5 +# periodSeconds: 10 +# timeoutSeconds: 1 +# successThreshold: 1 +# failureThreshold: 3 + +## Persist data to a persistent volume +persistence: + enabled: false + ## database data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "gp2" + # persistentVolumeReclaimPolicy: Recycle + # volumeMode: Filesystem + accessMode: ReadWriteOnce + ## Persistant Volume + capacity: 20Gi + ## Persistant Volume Claim + size: 8Gi + annotations: {} + selector: {} + # matchLabels: + # release: "stable" + # matchExpressions: + # - {key: environment, operator: In, values: [dev]} + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enable: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: stateful + +resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/lab/stateful/templates/_helpers.tpl b/helm/template/lab/stateful/templates/_helpers.tpl new file mode 100644 index 00000000..32610f3e --- /dev/null +++ b/helm/template/lab/stateful/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "stateful.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "stateful.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "stateful.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "stateful.labels" -}} +helm.sh/chart: {{ include "stateful.chart" . }} +{{ include "stateful.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "stateful.selectorLabels" -}} +app.kubernetes.io/name: {{ include "stateful.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "stateful.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "stateful.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/lab/stateful/templates/clusterrole.yaml b/helm/template/lab/stateful/templates/clusterrole.yaml new file mode 100644 index 00000000..1bef15a4 --- /dev/null +++ b/helm/template/lab/stateful/templates/clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "stateful.fullname" . }}-rbac +subjects: + - kind: ServiceAccount + name: {{ include "stateful.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/stateful/templates/configmap.yaml b/helm/template/lab/stateful/templates/configmap.yaml new file mode 100644 index 00000000..9175b366 --- /dev/null +++ b/helm/template/lab/stateful/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "stateful.labels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/stateful/templates/deployment.yaml b/helm/template/lab/stateful/templates/deployment.yaml new file mode 100644 index 00000000..a843988d --- /dev/null +++ b/helm/template/lab/stateful/templates/deployment.yaml @@ -0,0 +1,106 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "stateful.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "stateful.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "stateful.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "stateful.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.application.enabled }} + env: + {{- toYaml .Values.application.env | nindent 12 }} + {{- end }} + {{- if .Values.envFrom.enabled }} + envFrom: + {{- toYaml .Values.envFrom.envFrom | nindent 12 }} + {{- end }} + {{- if .Values.container }} + ports: + {{- with .Values.container.ports }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{ end }} + # livenessProbe: + # httpGet: + # path: / + # port: http + # readinessProbe: + # httpGet: + # path: / + # port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumeMounts: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + mountPath: {{ .Values.configMap.mountPath }} + readOnly: {{ .Values.configMap.readOnly }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + mountPath: {{ .Values.secret.mountPath }} + subPath: {{ .Values.secret.subPath }} + readOnly: {{ .Values.secret.readOnly }} + {{- end }} + {{- end }} + {{- if and .Values.volumes .Values.volumes.enabled }} + volumeMounts: + - name: {{ .Values.volumes.name }} + mountPath: {{ .Values.volumes.mountPath }} + {{- end }} + {{- if .Values.nodeSelector.enabled -}} + {{- with .Values.nodeSelector.select }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumes: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + configMap: + name: {{ .Values.configMap.name }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + secret: + secretName: {{ .Values.secret.name }} + {{- end }} + {{- end }} diff --git a/helm/template/lab/stateful/templates/hpa.yaml b/helm/template/lab/stateful/templates/hpa.yaml new file mode 100644 index 00000000..6d93c849 --- /dev/null +++ b/helm/template/lab/stateful/templates/hpa.yaml @@ -0,0 +1,29 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "stateful.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "stateful.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/template/lab/stateful/templates/ingress.yaml b/helm/template/lab/stateful/templates/ingress.yaml new file mode 100644 index 00000000..9808dadf --- /dev/null +++ b/helm/template/lab/stateful/templates/ingress.yaml @@ -0,0 +1,32 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "stateful.fullname" . -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else -}} +apiVersion: extensions/v1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "stateful.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + {{- with .Values.ingress.hosts }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/stateful/templates/pv.yaml b/helm/template/lab/stateful/templates/pv.yaml new file mode 100644 index 00000000..9671abf1 --- /dev/null +++ b/helm/template/lab/stateful/templates/pv.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} +kind: PersistentVolume +apiVersion: v1 +metadata: + name: {{ template "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} +{{- with .Values.persistence.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + labels: + app: {{ template "stateful.fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + {{- if .Values.persistence.capacity }} + capacity: + storage: {{ .Values.persistence.capacity | quote }} + {{- end }} + {{- if .Values.persistence.volumeMode }} + volumeMode: {{ .Values.persistence.volumeMode | quote }} + {{- end }} + accessModes: + - {{ .Values.persistence.accessMode | quote }} + {{- if .Values.persistence.persistentVolumeReclaimPolicy }} + persistentVolumeReclaimPolicy: {{ .Values.persistence.persistentVolumeReclaimPolicy | quote }} + {{- end }} +{{- if .Values.persistence.storageClass }} +{{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/stateful/templates/pvc.yaml b/helm/template/lab/stateful/templates/pvc.yaml new file mode 100644 index 00000000..2b7da086 --- /dev/null +++ b/helm/template/lab/stateful/templates/pvc.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} +{{- with .Values.persistence.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + labels: + app: {{ template "stateful.fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + accessModes: + - {{ .Values.persistence.accessMode | quote }} + {{- if .Values.persistence.volumeMode }} + volumeMode: {{ .Values.persistence.volumeMode | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} +{{- if .Values.persistence.storageClass }} +{{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" +{{- end }} +{{- end }} + {{- with .Values.persistence.annotations }} + selector: + {{ toYaml . | indent 4 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/lab/stateful/templates/secret.yaml b/helm/template/lab/stateful/templates/secret.yaml new file mode 100644 index 00000000..2b0a7d27 --- /dev/null +++ b/helm/template/lab/stateful/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "stateful.labels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/lab/stateful/templates/service.yaml b/helm/template/lab/stateful/templates/service.yaml new file mode 100644 index 00000000..8ed21b8e --- /dev/null +++ b/helm/template/lab/stateful/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "stateful.labels" . | nindent 4 }} +spec: + {{- if .Values.service }} + type: {{ .Values.service.type }} + {{- with .Values.service.ports }} + ports: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + selector: + {{- include "stateful.selectorLabels" . | nindent 4 }} diff --git a/helm/template/lab/stateful/templates/serviceaccount.yaml b/helm/template/lab/stateful/templates/serviceaccount.yaml new file mode 100644 index 00000000..dac4ad04 --- /dev/null +++ b/helm/template/lab/stateful/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "stateful.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "stateful.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/lab/stateful/values.yaml b/helm/template/lab/stateful/values.yaml new file mode 100644 index 00000000..f801efd8 --- /dev/null +++ b/helm/template/lab/stateful/values.yaml @@ -0,0 +1,140 @@ +--- +replicaCount: 1 + +secret: + enabled: false + name: "secret-stateful" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-stateful" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Stateful Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + create: false + annotations: {} + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +livenessProbe: {} +# initialDelaySeconds: 30 +# periodSeconds: 10 +# timeoutSeconds: 5 +# successThreshold: 1 +# failureThreshold: 3 + +readinessProbe: {} +# initialDelaySeconds: 5 +# periodSeconds: 10 +# timeoutSeconds: 1 +# successThreshold: 1 +# failureThreshold: 3 + +## Persist data to a persistent volume +persistence: + enabled: false + ## database data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "gp2" + # persistentVolumeReclaimPolicy: Recycle + # volumeMode: Filesystem + accessMode: ReadWriteOnce + ## Persistant Volume + capacity: 20Gi + ## Persistant Volume Claim + size: 8Gi + annotations: {} + selector: {} + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + - name: psql + port: 5432 + targetPort: 5432 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: stateful + +resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/lab/svcrole/.helmignore b/helm/template/lab/svcrole/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/lab/svcrole/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/lab/svcrole/Chart.yaml b/helm/template/lab/svcrole/Chart.yaml new file mode 100644 index 00000000..3f9e468e --- /dev/null +++ b/helm/template/lab/svcrole/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: svcrole +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0-rc" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/lab/svcrole/templates/_helpers.tpl b/helm/template/lab/svcrole/templates/_helpers.tpl new file mode 100644 index 00000000..5ff9d1f2 --- /dev/null +++ b/helm/template/lab/svcrole/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "svcrole.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "svcrole.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "svcrole.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "svcrole.labels" -}} +helm.sh/chart: {{ include "svcrole.chart" . }} +{{ include "svcrole.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "svcrole.selectorLabels" -}} +app.kubernetes.io/name: {{ include "svcrole.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "svcrole.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "svcrole.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/lab/svcrole/templates/clusterrole.yaml b/helm/template/lab/svcrole/templates/clusterrole.yaml new file mode 100644 index 00000000..6b9af355 --- /dev/null +++ b/helm/template/lab/svcrole/templates/clusterrole.yaml @@ -0,0 +1,16 @@ +{{- if .Values.clusterrole.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Values.serviceAccount.namespace }}-micro-registry + namespace: {{ .Values.serviceAccount.namespace }} +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - list + - patch + - watch +{{- end }} diff --git a/helm/template/lab/svcrole/templates/rolebinding.yaml b/helm/template/lab/svcrole/templates/rolebinding.yaml new file mode 100644 index 00000000..a8ba4aa1 --- /dev/null +++ b/helm/template/lab/svcrole/templates/rolebinding.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ .Values.serviceAccount.namespace }}-rolebinding-micro-registry + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole +{{- if .Values.clusterrole.create }} + name: {{ .Values.serviceAccount.namespace }}-micro-registry +{{- else }} + name: micro-registry +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ .Values.serviceAccount.name }} + namespace: {{ .Values.serviceAccount.namespace }} diff --git a/helm/template/lab/svcrole/templates/serviceaccount.yaml b/helm/template/lab/svcrole/templates/serviceaccount.yaml new file mode 100644 index 00000000..1a2b229f --- /dev/null +++ b/helm/template/lab/svcrole/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "svcrole.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + labels: + {{- include "svcrole.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/lab/svcrole/values.yaml b/helm/template/lab/svcrole/values.yaml new file mode 100644 index 00000000..3f74b54b --- /dev/null +++ b/helm/template/lab/svcrole/values.yaml @@ -0,0 +1,9 @@ +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" diff --git a/helm/template/prod/api/.helmignore b/helm/template/prod/api/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/prod/api/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/prod/api/Chart.yaml b/helm/template/prod/api/Chart.yaml new file mode 100644 index 00000000..1e083a6f --- /dev/null +++ b/helm/template/prod/api/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: api +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/prod/api/api.yaml b/helm/template/prod/api/api.yaml new file mode 100644 index 00000000..074d358d --- /dev/null +++ b/helm/template/prod/api/api.yaml @@ -0,0 +1,119 @@ +# Default values for api. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +secret: + enabled: false + name: "secret-api" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-api" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Api Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enabled: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: api + +resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/prod/api/templates/_helpers.tpl b/helm/template/prod/api/templates/_helpers.tpl new file mode 100644 index 00000000..a52ec969 --- /dev/null +++ b/helm/template/prod/api/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "api.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "api.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart prodel. +*/}} +{{- define "api.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common prodels +*/}} +{{- define "api.prodels" -}} +helm.sh/chart: {{ include "api.chart" . }} +{{ include "api.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector prodels +*/}} +{{- define "api.selectorLabels" -}} +app.kubernetes.io/name: {{ include "api.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "api.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "api.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/prod/api/templates/clusterrole.yaml b/helm/template/prod/api/templates/clusterrole.yaml new file mode 100644 index 00000000..9704958d --- /dev/null +++ b/helm/template/prod/api/templates/clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "api.fullname" . }}-rbac +subjects: + - kind: ServiceAccount + name: {{ include "api.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/api/templates/configmap.yaml b/helm/template/prod/api/templates/configmap.yaml new file mode 100644 index 00000000..e32b630a --- /dev/null +++ b/helm/template/prod/api/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "api.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "api.prodels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/api/templates/deployment.yaml b/helm/template/prod/api/templates/deployment.yaml new file mode 100644 index 00000000..29d1c275 --- /dev/null +++ b/helm/template/prod/api/templates/deployment.yaml @@ -0,0 +1,99 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "api.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "api.prodels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + revisionHistoryLimit: 10 + selector: + matchLabels: + {{- include "api.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + prodels: + {{- include "api.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "api.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.application.enabled }} + env: + {{- toYaml .Values.application.env | nindent 12 }} + {{- end }} + {{- if .Values.envFrom.enabled }} + envFrom: + {{- toYaml .Values.envFrom.envFrom | nindent 12 }} + {{- end }} + {{- if .Values.container }} + ports: + {{- with .Values.container.ports }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{ end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumeMounts: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + mountPath: {{ .Values.configMap.mountPath }} + readOnly: {{ .Values.configMap.readOnly }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + mountPath: {{ .Values.secret.mountPath }} + subPath: {{ .Values.secret.subPath }} + readOnly: {{ .Values.secret.readOnly }} + {{- end }} + {{- end }} + {{- if and .Values.volumes .Values.volumes.enabled }} + volumeMounts: + - name: {{ .Values.volumes.name }} + mountPath: {{ .Values.volumes.mountPath }} + {{- end }} + {{- if .Values.nodeSelector.enabled -}} + {{- with .Values.nodeSelector.select }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumes: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + configMap: + name: {{ .Values.configMap.name }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + secret: + secretName: {{ .Values.secret.name }} + {{- end }} + {{- end }} diff --git a/helm/template/prod/api/templates/hpa.yaml b/helm/template/prod/api/templates/hpa.yaml new file mode 100644 index 00000000..5c1eb46d --- /dev/null +++ b/helm/template/prod/api/templates/hpa.yaml @@ -0,0 +1,29 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "api.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "api.prodels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "api.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/template/prod/api/templates/ingress.yaml b/helm/template/prod/api/templates/ingress.yaml new file mode 100644 index 00000000..fa95232f --- /dev/null +++ b/helm/template/prod/api/templates/ingress.yaml @@ -0,0 +1,32 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "api.fullname" . -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else -}} +apiVersion: extensions/v1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + prodels: + {{- include "api.prodels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + {{- with .Values.ingress.hosts }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/api/templates/secret.yaml b/helm/template/prod/api/templates/secret.yaml new file mode 100644 index 00000000..4d0b9cc2 --- /dev/null +++ b/helm/template/prod/api/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "api.prodels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/prod/api/templates/service.yaml b/helm/template/prod/api/templates/service.yaml new file mode 100644 index 00000000..62cecc11 --- /dev/null +++ b/helm/template/prod/api/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "api.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "api.prodels" . | nindent 4 }} +spec: + {{- if .Values.service }} + type: {{ .Values.service.type }} + {{- with .Values.service.ports }} + ports: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + selector: + {{- include "api.selectorLabels" . | nindent 4 }} diff --git a/helm/template/prod/api/templates/serviceaccount.yaml b/helm/template/prod/api/templates/serviceaccount.yaml new file mode 100644 index 00000000..2b9a0155 --- /dev/null +++ b/helm/template/prod/api/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "api.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "api.prodels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/prod/api/values.yaml b/helm/template/prod/api/values.yaml new file mode 100644 index 00000000..450ed447 --- /dev/null +++ b/helm/template/prod/api/values.yaml @@ -0,0 +1,115 @@ +--- +replicaCount: 1 + +secret: + enabled: false + name: "secret-api" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-api" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Api Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enabled: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: api + - name: ALLOWED_ORIGINS + value: '*' + - name: PORT + value: "8080" + - name: REFRESH_TOKEN_EXPIRE_HOUR + value: "48" + - name: TOKEN_EXPIRE_HOUR + value: "1" + - name: PASSWORD + valueFrom: + secretKeyRef: + key: password + name: test-secret + +resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/prod/backend/.helmignore b/helm/template/prod/backend/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/prod/backend/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/prod/backend/Chart.yaml b/helm/template/prod/backend/Chart.yaml new file mode 100644 index 00000000..fa81f7aa --- /dev/null +++ b/helm/template/prod/backend/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: backend +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/prod/backend/backend.yaml b/helm/template/prod/backend/backend.yaml new file mode 100644 index 00000000..d5e20194 --- /dev/null +++ b/helm/template/prod/backend/backend.yaml @@ -0,0 +1,119 @@ +# Default values for backend. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +secret: + enabled: false + name: "secret-backend" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-backend" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Backend Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enabled: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: backend + +resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/prod/backend/templates/_helpers.tpl b/helm/template/prod/backend/templates/_helpers.tpl new file mode 100644 index 00000000..9a6a5fc1 --- /dev/null +++ b/helm/template/prod/backend/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "backend.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "backend.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart prodel. +*/}} +{{- define "backend.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common prodels +*/}} +{{- define "backend.prodels" -}} +helm.sh/chart: {{ include "backend.chart" . }} +{{ include "backend.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector prodels +*/}} +{{- define "backend.selectorLabels" -}} +app.kubernetes.io/name: {{ include "backend.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "backend.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "backend.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/prod/backend/templates/clusterrole.yaml b/helm/template/prod/backend/templates/clusterrole.yaml new file mode 100644 index 00000000..1f6ec50e --- /dev/null +++ b/helm/template/prod/backend/templates/clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "backend.fullname" . }}-rbac +subjects: + - kind: ServiceAccount + name: {{ include "backend.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/backend/templates/configmap.yaml b/helm/template/prod/backend/templates/configmap.yaml new file mode 100644 index 00000000..3bf418e7 --- /dev/null +++ b/helm/template/prod/backend/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "backend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "backend.prodels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/backend/templates/deployment.yaml b/helm/template/prod/backend/templates/deployment.yaml new file mode 100644 index 00000000..edcdbd97 --- /dev/null +++ b/helm/template/prod/backend/templates/deployment.yaml @@ -0,0 +1,99 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "backend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "backend.prodels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + revisionHistoryLimit: 10 + selector: + matchLabels: + {{- include "backend.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + prodels: + {{- include "backend.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "backend.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.application.enabled }} + env: + {{- toYaml .Values.application.env | nindent 12 }} + {{- end }} + {{- if .Values.envFrom.enabled }} + envFrom: + {{- toYaml .Values.envFrom.envFrom | nindent 12 }} + {{- end }} + {{- if .Values.container }} + ports: + {{- with .Values.container.ports }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{ end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumeMounts: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + mountPath: {{ .Values.configMap.mountPath }} + readOnly: {{ .Values.configMap.readOnly }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + mountPath: {{ .Values.secret.mountPath }} + subPath: {{ .Values.secret.subPath }} + readOnly: {{ .Values.secret.readOnly }} + {{- end }} + {{- end }} + {{- if and .Values.volumes .Values.volumes.enabled }} + volumeMounts: + - name: {{ .Values.volumes.name }} + mountPath: {{ .Values.volumes.mountPath }} + {{- end }} + {{- if .Values.nodeSelector.enabled -}} + {{- with .Values.nodeSelector.select }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumes: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + configMap: + name: {{ .Values.configMap.name }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + secret: + secretName: {{ .Values.secret.name }} + {{- end }} + {{- end }} diff --git a/helm/template/prod/backend/templates/hpa.yaml b/helm/template/prod/backend/templates/hpa.yaml new file mode 100644 index 00000000..2ff41f7a --- /dev/null +++ b/helm/template/prod/backend/templates/hpa.yaml @@ -0,0 +1,29 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "backend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "backend.prodels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "backend.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/template/prod/backend/templates/ingress.yaml b/helm/template/prod/backend/templates/ingress.yaml new file mode 100644 index 00000000..dee6d00c --- /dev/null +++ b/helm/template/prod/backend/templates/ingress.yaml @@ -0,0 +1,32 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "backend.fullname" . -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else -}} +apiVersion: extensions/v1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + prodels: + {{- include "backend.prodels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + {{- with .Values.ingress.hosts }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/backend/templates/secret.yaml b/helm/template/prod/backend/templates/secret.yaml new file mode 100644 index 00000000..48990451 --- /dev/null +++ b/helm/template/prod/backend/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "backend.prodels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/prod/backend/templates/service.yaml b/helm/template/prod/backend/templates/service.yaml new file mode 100644 index 00000000..d9b26d14 --- /dev/null +++ b/helm/template/prod/backend/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "backend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "backend.prodels" . | nindent 4 }} +spec: + {{- if .Values.service }} + type: {{ .Values.service.type }} + {{- with .Values.service.ports }} + ports: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + selector: + {{- include "backend.selectorLabels" . | nindent 4 }} diff --git a/helm/template/prod/backend/templates/serviceaccount.yaml b/helm/template/prod/backend/templates/serviceaccount.yaml new file mode 100644 index 00000000..17629d46 --- /dev/null +++ b/helm/template/prod/backend/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "backend.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "backend.prodels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/prod/backend/values.yaml b/helm/template/prod/backend/values.yaml new file mode 100644 index 00000000..2584c5c2 --- /dev/null +++ b/helm/template/prod/backend/values.yaml @@ -0,0 +1,126 @@ +--- +replicaCount: 1 + +secret: + enabled: false + name: "secret-backend" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-backend" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Backend Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: backend + - name: DB_HOST + value: db.internal.service + - name: DB_PORT + value: "5432" + - name: DB_USER + value: postgres + - name: DB_NAME + value: db_name + - name: DB_PASS + valueFrom: + secretKeyRef: + key: db-pass + name: db-secret + - name: DB_TIMEOUT + value: "10" + - name: DB_IDLE_CONN + value: "2" + - name: DB_OPEN_CONN + value: "5" + - name: DB_CONN_LIFETIME + value: "600" + +resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/prod/configmap/Chart.yaml b/helm/template/prod/configmap/Chart.yaml new file mode 100644 index 00000000..9518ad79 --- /dev/null +++ b/helm/template/prod/configmap/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: configmap +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/prod/configmap/configmap.yaml b/helm/template/prod/configmap/configmap.yaml new file mode 100644 index 00000000..c551f4fd --- /dev/null +++ b/helm/template/prod/configmap/configmap.yaml @@ -0,0 +1,12 @@ +configMap: + enabled: true + name: configmap + mountPath: {} + readOnly: true + data: {} + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" \ No newline at end of file diff --git a/helm/template/prod/configmap/templates/_helpers.tpl b/helm/template/prod/configmap/templates/_helpers.tpl new file mode 100644 index 00000000..6d0d102c --- /dev/null +++ b/helm/template/prod/configmap/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "configmap.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "configmap.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart prodel. +*/}} +{{- define "configmap.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common prodels +*/}} +{{- define "configmap.prodels" -}} +helm.sh/chart: {{ include "configmap.chart" . }} +{{ include "configmap.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector prodels +*/}} +{{- define "configmap.selectorLabels" -}} +app.kubernetes.io/name: {{ include "configmap.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "configmap.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "configmap.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/prod/configmap/templates/configmap.yaml b/helm/template/prod/configmap/templates/configmap.yaml new file mode 100644 index 00000000..f76f0ec4 --- /dev/null +++ b/helm/template/prod/configmap/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.configMap.name }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "configmap.prodels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/configmap/values.yaml b/helm/template/prod/configmap/values.yaml new file mode 100644 index 00000000..0ff4af1d --- /dev/null +++ b/helm/template/prod/configmap/values.yaml @@ -0,0 +1,21 @@ +configMap: + enabled: true + name: "configmap" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "configMap Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" \ No newline at end of file diff --git a/helm/template/prod/frontend/.helmignore b/helm/template/prod/frontend/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/prod/frontend/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/prod/frontend/Chart.yaml b/helm/template/prod/frontend/Chart.yaml new file mode 100644 index 00000000..3a4738ac --- /dev/null +++ b/helm/template/prod/frontend/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: frontend +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/prod/frontend/frontend.yaml b/helm/template/prod/frontend/frontend.yaml new file mode 100644 index 00000000..55c9b3c0 --- /dev/null +++ b/helm/template/prod/frontend/frontend.yaml @@ -0,0 +1,121 @@ +# Default values for frontend. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +secret: + enabled: false + name: "secret-frontend" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-frontend" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json: |- + { + "AppName": "Frontend Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: + {} + # fsGroup: 2000 + +securityContext: + {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enable: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 3000 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: frontend + +resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/prod/frontend/templates/_helpers.tpl b/helm/template/prod/frontend/templates/_helpers.tpl new file mode 100644 index 00000000..9021e1cd --- /dev/null +++ b/helm/template/prod/frontend/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "frontend.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "frontend.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart prodel. +*/}} +{{- define "frontend.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common prodels +*/}} +{{- define "frontend.prodels" -}} +helm.sh/chart: {{ include "frontend.chart" . }} +{{ include "frontend.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector prodels +*/}} +{{- define "frontend.selectorLabels" -}} +app.kubernetes.io/name: {{ include "frontend.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "frontend.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "frontend.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/prod/frontend/templates/clusterrole.yaml b/helm/template/prod/frontend/templates/clusterrole.yaml new file mode 100644 index 00000000..009f3ee6 --- /dev/null +++ b/helm/template/prod/frontend/templates/clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "frontend.fullname" . }}-rbac +subjects: + - kind: ServiceAccount + name: {{ include "frontend.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/frontend/templates/configmap.yaml b/helm/template/prod/frontend/templates/configmap.yaml new file mode 100644 index 00000000..7e256a9a --- /dev/null +++ b/helm/template/prod/frontend/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "frontend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "frontend.prodels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/frontend/templates/deployment.yaml b/helm/template/prod/frontend/templates/deployment.yaml new file mode 100644 index 00000000..938f41b9 --- /dev/null +++ b/helm/template/prod/frontend/templates/deployment.yaml @@ -0,0 +1,106 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "frontend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "frontend.prodels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "frontend.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + prodels: + {{- include "frontend.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "frontend.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.application.enabled }} + env: + {{- toYaml .Values.application.env | nindent 12 }} + {{- end }} + {{- if .Values.envFrom.enabled }} + envFrom: + {{- toYaml .Values.envFrom.envFrom | nindent 12 }} + {{- end }} + {{- if .Values.container }} + ports: + {{- with .Values.container.ports }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{ end }} + # livenessProbe: + # httpGet: + # path: / + # port: http + # readinessProbe: + # httpGet: + # path: / + # port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumeMounts: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + mountPath: {{ .Values.configMap.mountPath }} + readOnly: {{ .Values.configMap.readOnly }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + mountPath: {{ .Values.secret.mountPath }} + subPath: {{ .Values.secret.subPath }} + readOnly: {{ .Values.secret.readOnly }} + {{- end }} + {{- end }} + {{- if and .Values.volumes .Values.volumes.enabled }} + volumeMounts: + - name: {{ .Values.volumes.name }} + mountPath: {{ .Values.volumes.mountPath }} + {{- end }} + {{- if .Values.nodeSelector.enabled -}} + {{- with .Values.nodeSelector.select }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumes: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + configMap: + name: {{ .Values.configMap.name }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + secret: + secretName: {{ .Values.secret.name }} + {{- end }} + {{- end }} diff --git a/helm/template/prod/frontend/templates/hpa.yaml b/helm/template/prod/frontend/templates/hpa.yaml new file mode 100644 index 00000000..b84b12a7 --- /dev/null +++ b/helm/template/prod/frontend/templates/hpa.yaml @@ -0,0 +1,29 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "frontend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "frontend.prodels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "frontend.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/template/prod/frontend/templates/ingress.yaml b/helm/template/prod/frontend/templates/ingress.yaml new file mode 100644 index 00000000..f22d1112 --- /dev/null +++ b/helm/template/prod/frontend/templates/ingress.yaml @@ -0,0 +1,32 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "frontend.fullname" . -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else -}} +apiVersion: extensions/v1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + prodels: + {{- include "frontend.prodels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + {{- with .Values.ingress.hosts }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/frontend/templates/secret.yaml b/helm/template/prod/frontend/templates/secret.yaml new file mode 100644 index 00000000..0b4f18a9 --- /dev/null +++ b/helm/template/prod/frontend/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "frontend.prodels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/prod/frontend/templates/service.yaml b/helm/template/prod/frontend/templates/service.yaml new file mode 100644 index 00000000..bc5839b1 --- /dev/null +++ b/helm/template/prod/frontend/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "frontend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "frontend.prodels" . | nindent 4 }} +spec: + {{- if .Values.service }} + type: {{ .Values.service.type }} + {{- with .Values.service.ports }} + ports: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + selector: + {{- include "frontend.selectorLabels" . | nindent 4 }} diff --git a/helm/template/prod/frontend/templates/serviceaccount.yaml b/helm/template/prod/frontend/templates/serviceaccount.yaml new file mode 100644 index 00000000..f693d63e --- /dev/null +++ b/helm/template/prod/frontend/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "frontend.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "frontend.prodels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/prod/frontend/values.yaml b/helm/template/prod/frontend/values.yaml new file mode 100644 index 00000000..9dd06f60 --- /dev/null +++ b/helm/template/prod/frontend/values.yaml @@ -0,0 +1,108 @@ +--- +replicaCount: 1 + +secret: + enabled: false + name: "secret-frontend" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-frontend" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Frontend Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + create: false + annotations: {} + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 3000 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: frontend + - name: ALLOWED_ORIGINS + value: '*' + - name: PORT + value: "8080" + - name: REFRESH_TOKEN_EXPIRE_HOUR + value: "48" + - name: TOKEN_EXPIRE_HOUR + value: "1" + +resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/prod/helm-pack-prod.sh b/helm/template/prod/helm-pack-prod.sh new file mode 100755 index 00000000..3bfd5522 --- /dev/null +++ b/helm/template/prod/helm-pack-prod.sh @@ -0,0 +1,121 @@ +#!/bin/sh + +set -e + +TITLE="HELM PACKAGE SCRIPT" # script name +VER="2.2" # script version + +HELM_VERSION="1.4.0" +HELM_TEMPLATE="api \ + backend \ + configmap \ + frontend \ + secretref \ + stateful \ + svcrole +" +HELM_REPO_PATH="s3://devopscorner-adot-chart/prod" +HELM_REPO_NAME="devopscorner-adot" + +COL_RED="\033[22;31m" +COL_GREEN="\033[22;32m" +COL_BLUE="\033[22;34m" +COL_END="\033[0m" + +get_time() { + DATE=`date '+%Y-%m-%d %H:%M:%S'` +} + +print_line0() { + echo "$COL_GREEN=====================================================================================$COL_END" +} + +print_line1() { + echo "$COL_GREEN-------------------------------------------------------------------------------------$COL_END" +} + +print_line2() { + echo "-------------------------------------------------------------------------------------" +} + +logo() { + clear + print_line0 + echo "$COL_RED'########:'########:'########:::'#######:::'######::::'#####:::'########:::'#######:: $COL_END" + echo "$COL_RED..... ##:: ##.....:: ##.... ##:'##.... ##:'##... ##::'##.. ##:: ##.... ##:'##.... ##: $COL_END" + echo "$COL_RED:::: ##::: ##::::::: ##:::: ##: ##:::: ##: ##:::..::'##:::: ##: ##:::: ##:..::::: ##: $COL_END" + echo "$COL_RED::: ##:::: ######::: ########:: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::'#######:: $COL_END" + echo "$COL_RED:: ##::::: ##...:::: ##.. ##::: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::...... ##: $COL_END" + echo "$COL_RED: ##:::::: ##::::::: ##::. ##:: ##:::: ##: ##::: ##:. ##:: ##:: ##:::: ##:'##:::: ##: $COL_END" + echo "$COL_RED ########: ########: ##:::. ##:. #######::. ######:::. #####::: ########::. #######:: $COL_END" + echo "$COL_RED........::........::..:::::..:::.......::::......:::::.....::::........::::.......::: $COL_END" + print_line1 + echo "$COL_BLUE# $TITLE :: ver-$VER $COL_END" + echo "$COL_GREEN# HELM CHART :: ver-$HELM_VERSION $COL_END" + echo "$COL_GREEN# HELM REPO PATH :: $HELM_REPO_PATH $COL_END" + echo "$COL_GREEN# HELM REPO NAME :: $HELM_REPO_NAME $COL_END" +} + +header() { + logo + print_line0 + get_time + echo "$COL_RED# BEGIN PROCESS..... (Please Wait) $COL_END" + echo "$COL_RED# Start at: $DATE $COL_END" +} + +footer() { + echo "" + print_line0 + get_time + echo "$COL_RED# Finish at: $DATE $COL_END" + echo "$COL_RED# END PROCESS..... $COL_END\n" +} + +remove_old() { + for TEMPL in $HELM_TEMPLATE + do + msg_remove $TEMPL + rm -f $TEMPL-*.tgz + echo "- DONE -" + done +} + +packaging() { + for TEMPL in $HELM_TEMPLATE + do + msg_package $TEMPL + helm package $TEMPL + echo "- DONE -" + done +} + +msg_remove() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Remove Old Package : $1 " + echo "$COL_GREEN[ $DATE ] rm -f $1-*.tgz $COL_END" + get_time + print_line2 +} + +msg_package() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Packaging Helm : $1 " + echo "$COL_GREEN[ $DATE ] helm package $1 $COL_END" + get_time + print_line2 +} + +main() { + header + remove_old + packaging + footer +} + +### START HERE ### +main $@ diff --git a/helm/template/prod/helm-push-prod.sh b/helm/template/prod/helm-push-prod.sh new file mode 100755 index 00000000..5f4a2eb6 --- /dev/null +++ b/helm/template/prod/helm-push-prod.sh @@ -0,0 +1,111 @@ +#!/bin/sh + +set -e + +TITLE="HELM PACKAGE SCRIPT" # script name +VER="2.2" # script version + +HELM_VERSION="1.4.0" +HELM_TEMPLATE="api \ + backend \ + configmap \ + frontend \ + secretref \ + stateful \ + svcrole +" +HELM_REPO_PATH="s3://devopscorner-adot-chart/prod" +HELM_REPO_NAME="devopscorner-adot" + +COL_RED="\033[22;31m" +COL_GREEN="\033[22;32m" +COL_BLUE="\033[22;34m" +COL_END="\033[0m" + +get_time() { + DATE=`date '+%Y-%m-%d %H:%M:%S'` +} + +print_line0() { + echo "$COL_GREEN=====================================================================================$COL_END" +} + +print_line1() { + echo "$COL_GREEN-------------------------------------------------------------------------------------$COL_END" +} + +print_line2() { + echo "-------------------------------------------------------------------------------------" +} + +logo() { + clear + print_line0 + echo "$COL_RED'########:'########:'########:::'#######:::'######::::'#####:::'########:::'#######:: $COL_END" + echo "$COL_RED..... ##:: ##.....:: ##.... ##:'##.... ##:'##... ##::'##.. ##:: ##.... ##:'##.... ##: $COL_END" + echo "$COL_RED:::: ##::: ##::::::: ##:::: ##: ##:::: ##: ##:::..::'##:::: ##: ##:::: ##:..::::: ##: $COL_END" + echo "$COL_RED::: ##:::: ######::: ########:: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::'#######:: $COL_END" + echo "$COL_RED:: ##::::: ##...:::: ##.. ##::: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::...... ##: $COL_END" + echo "$COL_RED: ##:::::: ##::::::: ##::. ##:: ##:::: ##: ##::: ##:. ##:: ##:: ##:::: ##:'##:::: ##: $COL_END" + echo "$COL_RED ########: ########: ##:::. ##:. #######::. ######:::. #####::: ########::. #######:: $COL_END" + echo "$COL_RED........::........::..:::::..:::.......::::......:::::.....::::........::::.......::: $COL_END" + print_line1 + echo "$COL_BLUE# $TITLE :: ver-$VER $COL_END" + echo "$COL_GREEN# HELM CHART :: ver-$HELM_VERSION $COL_END" + echo "$COL_GREEN# HELM REPO PATH :: $HELM_REPO_PATH $COL_END" + echo "$COL_GREEN# HELM REPO NAME :: $HELM_REPO_NAME $COL_END" +} + +header() { + logo + print_line0 + get_time + echo "$COL_RED# BEGIN PROCESS..... (Please Wait) $COL_END" + echo "$COL_RED# Start at: $DATE $COL_END" +} + +footer() { + echo "" + print_line0 + get_time + echo "$COL_RED# Finish at: $DATE $COL_END" + echo "$COL_RED# END PROCESS..... $COL_END\n" +} + +push_package() { + for TEMPL in $HELM_TEMPLATE + do + msg_push $TEMPL + helm s3 push $TEMPL*.tgz $HELM_REPO_NAME --force + echo "- DONE -" + done +} + +msg_push() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Push Package Helm : $1 " + echo "$COL_GREEN[ $DATE ] helm s3 push $1 $HELM_REPO_NAME --force $COL_END" + print_line2 +} + +helm_update() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Update Helm Repository : " + echo "$COL_GREEN[ $DATE ] helm repo update" + helm repo update + echo "- DONE -" +} + +main() { + header + push_package + helm_update + footer +} + +### START HERE ### +main $@ diff --git a/helm/template/prod/secretref/Chart.yaml b/helm/template/prod/secretref/Chart.yaml new file mode 100644 index 00000000..db8e911d --- /dev/null +++ b/helm/template/prod/secretref/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: secretref +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/prod/secretref/secretref.yaml b/helm/template/prod/secretref/secretref.yaml new file mode 100644 index 00000000..5ae675f2 --- /dev/null +++ b/helm/template/prod/secretref/secretref.yaml @@ -0,0 +1,13 @@ +secret: + enabled: true + name: secretref + mountPath: + subPath: {} + readOnly: true + data: {} + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" \ No newline at end of file diff --git a/helm/template/prod/secretref/templates/_helpers.tpl b/helm/template/prod/secretref/templates/_helpers.tpl new file mode 100644 index 00000000..1d8fa8fb --- /dev/null +++ b/helm/template/prod/secretref/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "secretref.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "secretref.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart prodel. +*/}} +{{- define "secretref.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common prodels +*/}} +{{- define "secretref.prodels" -}} +helm.sh/chart: {{ include "secretref.chart" . }} +{{ include "secretref.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector prodels +*/}} +{{- define "secretref.selectorLabels" -}} +app.kubernetes.io/name: {{ include "secretref.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "secretref.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "secretref.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/prod/secretref/templates/secret.yaml b/helm/template/prod/secretref/templates/secret.yaml new file mode 100644 index 00000000..968ea28c --- /dev/null +++ b/helm/template/prod/secretref/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "secret.prodels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/prod/secretref/values.yaml b/helm/template/prod/secretref/values.yaml new file mode 100644 index 00000000..3908af5b --- /dev/null +++ b/helm/template/prod/secretref/values.yaml @@ -0,0 +1,16 @@ +secret: + enabled: true + name: psql-cred + mountPath: /app/core/secret + subPath: {} + readOnly: true + data: + db-user: dXNlcm5hbWUK + db-pass: cGFzc3cwcmQK + db-host: MTI3LjAuMC4xCg== + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" \ No newline at end of file diff --git a/helm/template/prod/stateful/.helmignore b/helm/template/prod/stateful/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/prod/stateful/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/prod/stateful/Chart.yaml b/helm/template/prod/stateful/Chart.yaml new file mode 100644 index 00000000..e09ef1b5 --- /dev/null +++ b/helm/template/prod/stateful/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: stateful +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/prod/stateful/stateful.yaml b/helm/template/prod/stateful/stateful.yaml new file mode 100644 index 00000000..f102581f --- /dev/null +++ b/helm/template/prod/stateful/stateful.yaml @@ -0,0 +1,163 @@ +# Default values for spinnaker. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +replicaCount: 1 + +secret: + enabled: false + name: "secret-stateful" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-stateful" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json: |- + { + "AppName": "Stateful Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +livenessProbe: {} +# initialDelaySeconds: 30 +# periodSeconds: 10 +# timeoutSeconds: 5 +# successThreshold: 1 +# failureThreshold: 3 + +readinessProbe: {} +# initialDelaySeconds: 5 +# periodSeconds: 10 +# timeoutSeconds: 1 +# successThreshold: 1 +# failureThreshold: 3 + +## Persist data to a persistent volume +persistence: + enabled: false + ## database data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "gp2" + # persistentVolumeReclaimPolicy: Recycle + # volumeMode: Filesystem + accessMode: ReadWriteOnce + ## Persistant Volume + capacity: 20Gi + ## Persistant Volume Claim + size: 8Gi + annotations: {} + selector: {} + # matchLabels: + # release: "stable" + # matchExpressions: + # - {key: environment, operator: In, values: [dev]} + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enable: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: stateful + +resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/prod/stateful/templates/_helpers.tpl b/helm/template/prod/stateful/templates/_helpers.tpl new file mode 100644 index 00000000..af384cc8 --- /dev/null +++ b/helm/template/prod/stateful/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "stateful.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "stateful.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart prodel. +*/}} +{{- define "stateful.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common prodels +*/}} +{{- define "stateful.prodels" -}} +helm.sh/chart: {{ include "stateful.chart" . }} +{{ include "stateful.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector prodels +*/}} +{{- define "stateful.selectorLabels" -}} +app.kubernetes.io/name: {{ include "stateful.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "stateful.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "stateful.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/prod/stateful/templates/clusterrole.yaml b/helm/template/prod/stateful/templates/clusterrole.yaml new file mode 100644 index 00000000..1bef15a4 --- /dev/null +++ b/helm/template/prod/stateful/templates/clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "stateful.fullname" . }}-rbac +subjects: + - kind: ServiceAccount + name: {{ include "stateful.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/stateful/templates/configmap.yaml b/helm/template/prod/stateful/templates/configmap.yaml new file mode 100644 index 00000000..a6ba2475 --- /dev/null +++ b/helm/template/prod/stateful/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "stateful.prodels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/stateful/templates/deployment.yaml b/helm/template/prod/stateful/templates/deployment.yaml new file mode 100644 index 00000000..7fa298d0 --- /dev/null +++ b/helm/template/prod/stateful/templates/deployment.yaml @@ -0,0 +1,106 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "stateful.prodels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "stateful.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + prodels: + {{- include "stateful.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "stateful.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.application.enabled }} + env: + {{- toYaml .Values.application.env | nindent 12 }} + {{- end }} + {{- if .Values.envFrom.enabled }} + envFrom: + {{- toYaml .Values.envFrom.envFrom | nindent 12 }} + {{- end }} + {{- if .Values.container }} + ports: + {{- with .Values.container.ports }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{ end }} + # livenessProbe: + # httpGet: + # path: / + # port: http + # readinessProbe: + # httpGet: + # path: / + # port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumeMounts: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + mountPath: {{ .Values.configMap.mountPath }} + readOnly: {{ .Values.configMap.readOnly }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + mountPath: {{ .Values.secret.mountPath }} + subPath: {{ .Values.secret.subPath }} + readOnly: {{ .Values.secret.readOnly }} + {{- end }} + {{- end }} + {{- if and .Values.volumes .Values.volumes.enabled }} + volumeMounts: + - name: {{ .Values.volumes.name }} + mountPath: {{ .Values.volumes.mountPath }} + {{- end }} + {{- if .Values.nodeSelector.enabled -}} + {{- with .Values.nodeSelector.select }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumes: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + configMap: + name: {{ .Values.configMap.name }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + secret: + secretName: {{ .Values.secret.name }} + {{- end }} + {{- end }} diff --git a/helm/template/prod/stateful/templates/hpa.yaml b/helm/template/prod/stateful/templates/hpa.yaml new file mode 100644 index 00000000..c8827ff5 --- /dev/null +++ b/helm/template/prod/stateful/templates/hpa.yaml @@ -0,0 +1,29 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "stateful.prodels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "stateful.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/template/prod/stateful/templates/ingress.yaml b/helm/template/prod/stateful/templates/ingress.yaml new file mode 100644 index 00000000..1ec965d3 --- /dev/null +++ b/helm/template/prod/stateful/templates/ingress.yaml @@ -0,0 +1,32 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "stateful.fullname" . -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else -}} +apiVersion: extensions/v1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + prodels: + {{- include "stateful.prodels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + {{- with .Values.ingress.hosts }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/stateful/templates/pv.yaml b/helm/template/prod/stateful/templates/pv.yaml new file mode 100644 index 00000000..2e285cd4 --- /dev/null +++ b/helm/template/prod/stateful/templates/pv.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} +kind: PersistentVolume +apiVersion: v1 +metadata: + name: {{ template "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} +{{- with .Values.persistence.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + prodels: + app: {{ template "stateful.fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + {{- if .Values.persistence.capacity }} + capacity: + storage: {{ .Values.persistence.capacity | quote }} + {{- end }} + {{- if .Values.persistence.volumeMode }} + volumeMode: {{ .Values.persistence.volumeMode | quote }} + {{- end }} + accessModes: + - {{ .Values.persistence.accessMode | quote }} + {{- if .Values.persistence.persistentVolumeReclaimPolicy }} + persistentVolumeReclaimPolicy: {{ .Values.persistence.persistentVolumeReclaimPolicy | quote }} + {{- end }} +{{- if .Values.persistence.storageClass }} +{{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/stateful/templates/pvc.yaml b/helm/template/prod/stateful/templates/pvc.yaml new file mode 100644 index 00000000..d8199cc0 --- /dev/null +++ b/helm/template/prod/stateful/templates/pvc.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} +{{- with .Values.persistence.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + prodels: + app: {{ template "stateful.fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + accessModes: + - {{ .Values.persistence.accessMode | quote }} + {{- if .Values.persistence.volumeMode }} + volumeMode: {{ .Values.persistence.volumeMode | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} +{{- if .Values.persistence.storageClass }} +{{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" +{{- end }} +{{- end }} + {{- with .Values.persistence.annotations }} + selector: + {{ toYaml . | indent 4 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/prod/stateful/templates/secret.yaml b/helm/template/prod/stateful/templates/secret.yaml new file mode 100644 index 00000000..27dee5ad --- /dev/null +++ b/helm/template/prod/stateful/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "stateful.prodels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/prod/stateful/templates/service.yaml b/helm/template/prod/stateful/templates/service.yaml new file mode 100644 index 00000000..8d669fdc --- /dev/null +++ b/helm/template/prod/stateful/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "stateful.prodels" . | nindent 4 }} +spec: + {{- if .Values.service }} + type: {{ .Values.service.type }} + {{- with .Values.service.ports }} + ports: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + selector: + {{- include "stateful.selectorLabels" . | nindent 4 }} diff --git a/helm/template/prod/stateful/templates/serviceaccount.yaml b/helm/template/prod/stateful/templates/serviceaccount.yaml new file mode 100644 index 00000000..88b30281 --- /dev/null +++ b/helm/template/prod/stateful/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "stateful.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "stateful.prodels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/prod/stateful/values.yaml b/helm/template/prod/stateful/values.yaml new file mode 100644 index 00000000..f801efd8 --- /dev/null +++ b/helm/template/prod/stateful/values.yaml @@ -0,0 +1,140 @@ +--- +replicaCount: 1 + +secret: + enabled: false + name: "secret-stateful" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-stateful" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Stateful Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + create: false + annotations: {} + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +livenessProbe: {} +# initialDelaySeconds: 30 +# periodSeconds: 10 +# timeoutSeconds: 5 +# successThreshold: 1 +# failureThreshold: 3 + +readinessProbe: {} +# initialDelaySeconds: 5 +# periodSeconds: 10 +# timeoutSeconds: 1 +# successThreshold: 1 +# failureThreshold: 3 + +## Persist data to a persistent volume +persistence: + enabled: false + ## database data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "gp2" + # persistentVolumeReclaimPolicy: Recycle + # volumeMode: Filesystem + accessMode: ReadWriteOnce + ## Persistant Volume + capacity: 20Gi + ## Persistant Volume Claim + size: 8Gi + annotations: {} + selector: {} + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + - name: psql + port: 5432 + targetPort: 5432 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: stateful + +resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/prod/svcrole/.helmignore b/helm/template/prod/svcrole/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/prod/svcrole/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/prod/svcrole/Chart.yaml b/helm/template/prod/svcrole/Chart.yaml new file mode 100644 index 00000000..78df3c9f --- /dev/null +++ b/helm/template/prod/svcrole/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: svcrole +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/prod/svcrole/templates/_helpers.tpl b/helm/template/prod/svcrole/templates/_helpers.tpl new file mode 100644 index 00000000..111e971e --- /dev/null +++ b/helm/template/prod/svcrole/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "svcrole.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "svcrole.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart prodel. +*/}} +{{- define "svcrole.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common prodels +*/}} +{{- define "svcrole.prodels" -}} +helm.sh/chart: {{ include "svcrole.chart" . }} +{{ include "svcrole.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector prodels +*/}} +{{- define "svcrole.selectorLabels" -}} +app.kubernetes.io/name: {{ include "svcrole.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "svcrole.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "svcrole.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/prod/svcrole/templates/clusterrole.yaml b/helm/template/prod/svcrole/templates/clusterrole.yaml new file mode 100644 index 00000000..6b9af355 --- /dev/null +++ b/helm/template/prod/svcrole/templates/clusterrole.yaml @@ -0,0 +1,16 @@ +{{- if .Values.clusterrole.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Values.serviceAccount.namespace }}-micro-registry + namespace: {{ .Values.serviceAccount.namespace }} +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - list + - patch + - watch +{{- end }} diff --git a/helm/template/prod/svcrole/templates/rolebinding.yaml b/helm/template/prod/svcrole/templates/rolebinding.yaml new file mode 100644 index 00000000..a8ba4aa1 --- /dev/null +++ b/helm/template/prod/svcrole/templates/rolebinding.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ .Values.serviceAccount.namespace }}-rolebinding-micro-registry + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole +{{- if .Values.clusterrole.create }} + name: {{ .Values.serviceAccount.namespace }}-micro-registry +{{- else }} + name: micro-registry +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ .Values.serviceAccount.name }} + namespace: {{ .Values.serviceAccount.namespace }} diff --git a/helm/template/prod/svcrole/templates/serviceaccount.yaml b/helm/template/prod/svcrole/templates/serviceaccount.yaml new file mode 100644 index 00000000..1b369534 --- /dev/null +++ b/helm/template/prod/svcrole/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "svcrole.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + prodels: + {{- include "svcrole.prodels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/prod/svcrole/values.yaml b/helm/template/prod/svcrole/values.yaml new file mode 100644 index 00000000..3f74b54b --- /dev/null +++ b/helm/template/prod/svcrole/values.yaml @@ -0,0 +1,9 @@ +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" diff --git a/helm/template/staging/api/.helmignore b/helm/template/staging/api/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/staging/api/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/staging/api/Chart.yaml b/helm/template/staging/api/Chart.yaml new file mode 100644 index 00000000..1e083a6f --- /dev/null +++ b/helm/template/staging/api/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: api +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/staging/api/api.yaml b/helm/template/staging/api/api.yaml new file mode 100644 index 00000000..074d358d --- /dev/null +++ b/helm/template/staging/api/api.yaml @@ -0,0 +1,119 @@ +# Default values for api. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +secret: + enabled: false + name: "secret-api" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-api" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Api Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enabled: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: api + +resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/staging/api/templates/_helpers.tpl b/helm/template/staging/api/templates/_helpers.tpl new file mode 100644 index 00000000..2aa240dd --- /dev/null +++ b/helm/template/staging/api/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "api.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "api.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart stagingel. +*/}} +{{- define "api.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common stagingels +*/}} +{{- define "api.stagingels" -}} +helm.sh/chart: {{ include "api.chart" . }} +{{ include "api.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector stagingels +*/}} +{{- define "api.selectorLabels" -}} +app.kubernetes.io/name: {{ include "api.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "api.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "api.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/staging/api/templates/clusterrole.yaml b/helm/template/staging/api/templates/clusterrole.yaml new file mode 100644 index 00000000..9704958d --- /dev/null +++ b/helm/template/staging/api/templates/clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "api.fullname" . }}-rbac +subjects: + - kind: ServiceAccount + name: {{ include "api.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/api/templates/configmap.yaml b/helm/template/staging/api/templates/configmap.yaml new file mode 100644 index 00000000..3ba0580c --- /dev/null +++ b/helm/template/staging/api/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "api.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "api.stagingels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/api/templates/deployment.yaml b/helm/template/staging/api/templates/deployment.yaml new file mode 100644 index 00000000..2f9a2792 --- /dev/null +++ b/helm/template/staging/api/templates/deployment.yaml @@ -0,0 +1,99 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "api.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "api.stagingels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + revisionHistoryLimit: 10 + selector: + matchLabels: + {{- include "api.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + stagingels: + {{- include "api.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "api.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.application.enabled }} + env: + {{- toYaml .Values.application.env | nindent 12 }} + {{- end }} + {{- if .Values.envFrom.enabled }} + envFrom: + {{- toYaml .Values.envFrom.envFrom | nindent 12 }} + {{- end }} + {{- if .Values.container }} + ports: + {{- with .Values.container.ports }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{ end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumeMounts: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + mountPath: {{ .Values.configMap.mountPath }} + readOnly: {{ .Values.configMap.readOnly }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + mountPath: {{ .Values.secret.mountPath }} + subPath: {{ .Values.secret.subPath }} + readOnly: {{ .Values.secret.readOnly }} + {{- end }} + {{- end }} + {{- if and .Values.volumes .Values.volumes.enabled }} + volumeMounts: + - name: {{ .Values.volumes.name }} + mountPath: {{ .Values.volumes.mountPath }} + {{- end }} + {{- if .Values.nodeSelector.enabled -}} + {{- with .Values.nodeSelector.select }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumes: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + configMap: + name: {{ .Values.configMap.name }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + secret: + secretName: {{ .Values.secret.name }} + {{- end }} + {{- end }} diff --git a/helm/template/staging/api/templates/hpa.yaml b/helm/template/staging/api/templates/hpa.yaml new file mode 100644 index 00000000..1479f1ca --- /dev/null +++ b/helm/template/staging/api/templates/hpa.yaml @@ -0,0 +1,29 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "api.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "api.stagingels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "api.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/template/staging/api/templates/ingress.yaml b/helm/template/staging/api/templates/ingress.yaml new file mode 100644 index 00000000..4731742a --- /dev/null +++ b/helm/template/staging/api/templates/ingress.yaml @@ -0,0 +1,32 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "api.fullname" . -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else -}} +apiVersion: extensions/v1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + stagingels: + {{- include "api.stagingels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + {{- with .Values.ingress.hosts }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/api/templates/secret.yaml b/helm/template/staging/api/templates/secret.yaml new file mode 100644 index 00000000..262da467 --- /dev/null +++ b/helm/template/staging/api/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "api.stagingels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/staging/api/templates/service.yaml b/helm/template/staging/api/templates/service.yaml new file mode 100644 index 00000000..73e6a4ec --- /dev/null +++ b/helm/template/staging/api/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "api.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "api.stagingels" . | nindent 4 }} +spec: + {{- if .Values.service }} + type: {{ .Values.service.type }} + {{- with .Values.service.ports }} + ports: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + selector: + {{- include "api.selectorLabels" . | nindent 4 }} diff --git a/helm/template/staging/api/templates/serviceaccount.yaml b/helm/template/staging/api/templates/serviceaccount.yaml new file mode 100644 index 00000000..9320390f --- /dev/null +++ b/helm/template/staging/api/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "api.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "api.stagingels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/staging/api/values.yaml b/helm/template/staging/api/values.yaml new file mode 100644 index 00000000..450ed447 --- /dev/null +++ b/helm/template/staging/api/values.yaml @@ -0,0 +1,115 @@ +--- +replicaCount: 1 + +secret: + enabled: false + name: "secret-api" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-api" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Api Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enabled: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: api + - name: ALLOWED_ORIGINS + value: '*' + - name: PORT + value: "8080" + - name: REFRESH_TOKEN_EXPIRE_HOUR + value: "48" + - name: TOKEN_EXPIRE_HOUR + value: "1" + - name: PASSWORD + valueFrom: + secretKeyRef: + key: password + name: test-secret + +resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/staging/backend/.helmignore b/helm/template/staging/backend/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/staging/backend/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/staging/backend/Chart.yaml b/helm/template/staging/backend/Chart.yaml new file mode 100644 index 00000000..fa81f7aa --- /dev/null +++ b/helm/template/staging/backend/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: backend +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/staging/backend/backend.yaml b/helm/template/staging/backend/backend.yaml new file mode 100644 index 00000000..d5e20194 --- /dev/null +++ b/helm/template/staging/backend/backend.yaml @@ -0,0 +1,119 @@ +# Default values for backend. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +secret: + enabled: false + name: "secret-backend" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-backend" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Backend Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enabled: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: backend + +resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/staging/backend/templates/_helpers.tpl b/helm/template/staging/backend/templates/_helpers.tpl new file mode 100644 index 00000000..97b082d1 --- /dev/null +++ b/helm/template/staging/backend/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "backend.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "backend.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart stagingel. +*/}} +{{- define "backend.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common stagingels +*/}} +{{- define "backend.stagingels" -}} +helm.sh/chart: {{ include "backend.chart" . }} +{{ include "backend.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector stagingels +*/}} +{{- define "backend.selectorLabels" -}} +app.kubernetes.io/name: {{ include "backend.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "backend.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "backend.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/staging/backend/templates/clusterrole.yaml b/helm/template/staging/backend/templates/clusterrole.yaml new file mode 100644 index 00000000..1f6ec50e --- /dev/null +++ b/helm/template/staging/backend/templates/clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "backend.fullname" . }}-rbac +subjects: + - kind: ServiceAccount + name: {{ include "backend.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/backend/templates/configmap.yaml b/helm/template/staging/backend/templates/configmap.yaml new file mode 100644 index 00000000..f493d7a0 --- /dev/null +++ b/helm/template/staging/backend/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "backend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "backend.stagingels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/backend/templates/deployment.yaml b/helm/template/staging/backend/templates/deployment.yaml new file mode 100644 index 00000000..5bfca057 --- /dev/null +++ b/helm/template/staging/backend/templates/deployment.yaml @@ -0,0 +1,99 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "backend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "backend.stagingels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + revisionHistoryLimit: 10 + selector: + matchLabels: + {{- include "backend.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + stagingels: + {{- include "backend.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "backend.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.application.enabled }} + env: + {{- toYaml .Values.application.env | nindent 12 }} + {{- end }} + {{- if .Values.envFrom.enabled }} + envFrom: + {{- toYaml .Values.envFrom.envFrom | nindent 12 }} + {{- end }} + {{- if .Values.container }} + ports: + {{- with .Values.container.ports }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{ end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumeMounts: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + mountPath: {{ .Values.configMap.mountPath }} + readOnly: {{ .Values.configMap.readOnly }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + mountPath: {{ .Values.secret.mountPath }} + subPath: {{ .Values.secret.subPath }} + readOnly: {{ .Values.secret.readOnly }} + {{- end }} + {{- end }} + {{- if and .Values.volumes .Values.volumes.enabled }} + volumeMounts: + - name: {{ .Values.volumes.name }} + mountPath: {{ .Values.volumes.mountPath }} + {{- end }} + {{- if .Values.nodeSelector.enabled -}} + {{- with .Values.nodeSelector.select }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumes: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + configMap: + name: {{ .Values.configMap.name }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + secret: + secretName: {{ .Values.secret.name }} + {{- end }} + {{- end }} diff --git a/helm/template/staging/backend/templates/hpa.yaml b/helm/template/staging/backend/templates/hpa.yaml new file mode 100644 index 00000000..ae94127b --- /dev/null +++ b/helm/template/staging/backend/templates/hpa.yaml @@ -0,0 +1,29 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "backend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "backend.stagingels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "backend.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/template/staging/backend/templates/ingress.yaml b/helm/template/staging/backend/templates/ingress.yaml new file mode 100644 index 00000000..ec557aa2 --- /dev/null +++ b/helm/template/staging/backend/templates/ingress.yaml @@ -0,0 +1,32 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "backend.fullname" . -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else -}} +apiVersion: extensions/v1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + stagingels: + {{- include "backend.stagingels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + {{- with .Values.ingress.hosts }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/backend/templates/secret.yaml b/helm/template/staging/backend/templates/secret.yaml new file mode 100644 index 00000000..19a27f7c --- /dev/null +++ b/helm/template/staging/backend/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "backend.stagingels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/staging/backend/templates/service.yaml b/helm/template/staging/backend/templates/service.yaml new file mode 100644 index 00000000..8e9d71c2 --- /dev/null +++ b/helm/template/staging/backend/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "backend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "backend.stagingels" . | nindent 4 }} +spec: + {{- if .Values.service }} + type: {{ .Values.service.type }} + {{- with .Values.service.ports }} + ports: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + selector: + {{- include "backend.selectorLabels" . | nindent 4 }} diff --git a/helm/template/staging/backend/templates/serviceaccount.yaml b/helm/template/staging/backend/templates/serviceaccount.yaml new file mode 100644 index 00000000..b333335a --- /dev/null +++ b/helm/template/staging/backend/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "backend.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "backend.stagingels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/staging/backend/values.yaml b/helm/template/staging/backend/values.yaml new file mode 100644 index 00000000..2584c5c2 --- /dev/null +++ b/helm/template/staging/backend/values.yaml @@ -0,0 +1,126 @@ +--- +replicaCount: 1 + +secret: + enabled: false + name: "secret-backend" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-backend" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Backend Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: backend + - name: DB_HOST + value: db.internal.service + - name: DB_PORT + value: "5432" + - name: DB_USER + value: postgres + - name: DB_NAME + value: db_name + - name: DB_PASS + valueFrom: + secretKeyRef: + key: db-pass + name: db-secret + - name: DB_TIMEOUT + value: "10" + - name: DB_IDLE_CONN + value: "2" + - name: DB_OPEN_CONN + value: "5" + - name: DB_CONN_LIFETIME + value: "600" + +resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/staging/configmap/Chart.yaml b/helm/template/staging/configmap/Chart.yaml new file mode 100644 index 00000000..9518ad79 --- /dev/null +++ b/helm/template/staging/configmap/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: configmap +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/staging/configmap/configmap.yaml b/helm/template/staging/configmap/configmap.yaml new file mode 100644 index 00000000..c551f4fd --- /dev/null +++ b/helm/template/staging/configmap/configmap.yaml @@ -0,0 +1,12 @@ +configMap: + enabled: true + name: configmap + mountPath: {} + readOnly: true + data: {} + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" \ No newline at end of file diff --git a/helm/template/staging/configmap/templates/_helpers.tpl b/helm/template/staging/configmap/templates/_helpers.tpl new file mode 100644 index 00000000..b7c6d10f --- /dev/null +++ b/helm/template/staging/configmap/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "configmap.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "configmap.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart stagingel. +*/}} +{{- define "configmap.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common stagingels +*/}} +{{- define "configmap.stagingels" -}} +helm.sh/chart: {{ include "configmap.chart" . }} +{{ include "configmap.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector stagingels +*/}} +{{- define "configmap.selectorLabels" -}} +app.kubernetes.io/name: {{ include "configmap.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "configmap.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "configmap.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/staging/configmap/templates/configmap.yaml b/helm/template/staging/configmap/templates/configmap.yaml new file mode 100644 index 00000000..4ef02a89 --- /dev/null +++ b/helm/template/staging/configmap/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.configMap.name }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "configmap.stagingels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/configmap/values.yaml b/helm/template/staging/configmap/values.yaml new file mode 100644 index 00000000..0ff4af1d --- /dev/null +++ b/helm/template/staging/configmap/values.yaml @@ -0,0 +1,21 @@ +configMap: + enabled: true + name: "configmap" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "configMap Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" \ No newline at end of file diff --git a/helm/template/staging/frontend/.helmignore b/helm/template/staging/frontend/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/staging/frontend/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/staging/frontend/Chart.yaml b/helm/template/staging/frontend/Chart.yaml new file mode 100644 index 00000000..3a4738ac --- /dev/null +++ b/helm/template/staging/frontend/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: frontend +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/staging/frontend/frontend.yaml b/helm/template/staging/frontend/frontend.yaml new file mode 100644 index 00000000..55c9b3c0 --- /dev/null +++ b/helm/template/staging/frontend/frontend.yaml @@ -0,0 +1,121 @@ +# Default values for frontend. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +secret: + enabled: false + name: "secret-frontend" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-frontend" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json: |- + { + "AppName": "Frontend Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: + {} + # fsGroup: 2000 + +securityContext: + {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enable: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 3000 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: frontend + +resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/staging/frontend/templates/_helpers.tpl b/helm/template/staging/frontend/templates/_helpers.tpl new file mode 100644 index 00000000..130986c1 --- /dev/null +++ b/helm/template/staging/frontend/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "frontend.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "frontend.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart stagingel. +*/}} +{{- define "frontend.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common stagingels +*/}} +{{- define "frontend.stagingels" -}} +helm.sh/chart: {{ include "frontend.chart" . }} +{{ include "frontend.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector stagingels +*/}} +{{- define "frontend.selectorLabels" -}} +app.kubernetes.io/name: {{ include "frontend.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "frontend.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "frontend.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/staging/frontend/templates/clusterrole.yaml b/helm/template/staging/frontend/templates/clusterrole.yaml new file mode 100644 index 00000000..009f3ee6 --- /dev/null +++ b/helm/template/staging/frontend/templates/clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "frontend.fullname" . }}-rbac +subjects: + - kind: ServiceAccount + name: {{ include "frontend.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/frontend/templates/configmap.yaml b/helm/template/staging/frontend/templates/configmap.yaml new file mode 100644 index 00000000..873f9702 --- /dev/null +++ b/helm/template/staging/frontend/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "frontend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "frontend.stagingels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/frontend/templates/deployment.yaml b/helm/template/staging/frontend/templates/deployment.yaml new file mode 100644 index 00000000..8663d1a0 --- /dev/null +++ b/helm/template/staging/frontend/templates/deployment.yaml @@ -0,0 +1,106 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "frontend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "frontend.stagingels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "frontend.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + stagingels: + {{- include "frontend.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "frontend.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.application.enabled }} + env: + {{- toYaml .Values.application.env | nindent 12 }} + {{- end }} + {{- if .Values.envFrom.enabled }} + envFrom: + {{- toYaml .Values.envFrom.envFrom | nindent 12 }} + {{- end }} + {{- if .Values.container }} + ports: + {{- with .Values.container.ports }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{ end }} + # livenessProbe: + # httpGet: + # path: / + # port: http + # readinessProbe: + # httpGet: + # path: / + # port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumeMounts: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + mountPath: {{ .Values.configMap.mountPath }} + readOnly: {{ .Values.configMap.readOnly }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + mountPath: {{ .Values.secret.mountPath }} + subPath: {{ .Values.secret.subPath }} + readOnly: {{ .Values.secret.readOnly }} + {{- end }} + {{- end }} + {{- if and .Values.volumes .Values.volumes.enabled }} + volumeMounts: + - name: {{ .Values.volumes.name }} + mountPath: {{ .Values.volumes.mountPath }} + {{- end }} + {{- if .Values.nodeSelector.enabled -}} + {{- with .Values.nodeSelector.select }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumes: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + configMap: + name: {{ .Values.configMap.name }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + secret: + secretName: {{ .Values.secret.name }} + {{- end }} + {{- end }} diff --git a/helm/template/staging/frontend/templates/hpa.yaml b/helm/template/staging/frontend/templates/hpa.yaml new file mode 100644 index 00000000..11941852 --- /dev/null +++ b/helm/template/staging/frontend/templates/hpa.yaml @@ -0,0 +1,29 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "frontend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "frontend.stagingels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "frontend.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/template/staging/frontend/templates/ingress.yaml b/helm/template/staging/frontend/templates/ingress.yaml new file mode 100644 index 00000000..dc5bcccc --- /dev/null +++ b/helm/template/staging/frontend/templates/ingress.yaml @@ -0,0 +1,32 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "frontend.fullname" . -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else -}} +apiVersion: extensions/v1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + stagingels: + {{- include "frontend.stagingels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + {{- with .Values.ingress.hosts }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/frontend/templates/secret.yaml b/helm/template/staging/frontend/templates/secret.yaml new file mode 100644 index 00000000..ea2f0810 --- /dev/null +++ b/helm/template/staging/frontend/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "frontend.stagingels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/staging/frontend/templates/service.yaml b/helm/template/staging/frontend/templates/service.yaml new file mode 100644 index 00000000..a9a1948c --- /dev/null +++ b/helm/template/staging/frontend/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "frontend.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "frontend.stagingels" . | nindent 4 }} +spec: + {{- if .Values.service }} + type: {{ .Values.service.type }} + {{- with .Values.service.ports }} + ports: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + selector: + {{- include "frontend.selectorLabels" . | nindent 4 }} diff --git a/helm/template/staging/frontend/templates/serviceaccount.yaml b/helm/template/staging/frontend/templates/serviceaccount.yaml new file mode 100644 index 00000000..70ed69ab --- /dev/null +++ b/helm/template/staging/frontend/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "frontend.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "frontend.stagingels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/staging/frontend/values.yaml b/helm/template/staging/frontend/values.yaml new file mode 100644 index 00000000..9dd06f60 --- /dev/null +++ b/helm/template/staging/frontend/values.yaml @@ -0,0 +1,108 @@ +--- +replicaCount: 1 + +secret: + enabled: false + name: "secret-frontend" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-frontend" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Frontend Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + create: false + annotations: {} + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 3000 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: frontend + - name: ALLOWED_ORIGINS + value: '*' + - name: PORT + value: "8080" + - name: REFRESH_TOKEN_EXPIRE_HOUR + value: "48" + - name: TOKEN_EXPIRE_HOUR + value: "1" + +resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/staging/helm-pack-staging.sh b/helm/template/staging/helm-pack-staging.sh new file mode 100755 index 00000000..425e3317 --- /dev/null +++ b/helm/template/staging/helm-pack-staging.sh @@ -0,0 +1,121 @@ +#!/bin/sh + +set -e + +TITLE="HELM PACKAGE SCRIPT" # script name +VER="2.2" # script version + +HELM_VERSION="1.4.0" +HELM_TEMPLATE="api \ + backend \ + configmap \ + frontend \ + secretref \ + stateful \ + svcrole +" +HELM_REPO_PATH="s3://devopscorner-adot-chart/staging" +HELM_REPO_NAME="devopscorner-adot-staging" + +COL_RED="\033[22;31m" +COL_GREEN="\033[22;32m" +COL_BLUE="\033[22;34m" +COL_END="\033[0m" + +get_time() { + DATE=`date '+%Y-%m-%d %H:%M:%S'` +} + +print_line0() { + echo "$COL_GREEN=====================================================================================$COL_END" +} + +print_line1() { + echo "$COL_GREEN-------------------------------------------------------------------------------------$COL_END" +} + +print_line2() { + echo "-------------------------------------------------------------------------------------" +} + +logo() { + clear + print_line0 + echo "$COL_RED'########:'########:'########:::'#######:::'######::::'#####:::'########:::'#######:: $COL_END" + echo "$COL_RED..... ##:: ##.....:: ##.... ##:'##.... ##:'##... ##::'##.. ##:: ##.... ##:'##.... ##: $COL_END" + echo "$COL_RED:::: ##::: ##::::::: ##:::: ##: ##:::: ##: ##:::..::'##:::: ##: ##:::: ##:..::::: ##: $COL_END" + echo "$COL_RED::: ##:::: ######::: ########:: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::'#######:: $COL_END" + echo "$COL_RED:: ##::::: ##...:::: ##.. ##::: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::...... ##: $COL_END" + echo "$COL_RED: ##:::::: ##::::::: ##::. ##:: ##:::: ##: ##::: ##:. ##:: ##:: ##:::: ##:'##:::: ##: $COL_END" + echo "$COL_RED ########: ########: ##:::. ##:. #######::. ######:::. #####::: ########::. #######:: $COL_END" + echo "$COL_RED........::........::..:::::..:::.......::::......:::::.....::::........::::.......::: $COL_END" + print_line1 + echo "$COL_BLUE# $TITLE :: ver-$VER $COL_END" + echo "$COL_GREEN# HELM CHART :: ver-$HELM_VERSION $COL_END" + echo "$COL_GREEN# HELM REPO PATH :: $HELM_REPO_PATH $COL_END" + echo "$COL_GREEN# HELM REPO NAME :: $HELM_REPO_NAME $COL_END" +} + +header() { + logo + print_line0 + get_time + echo "$COL_RED# BEGIN PROCESS..... (Please Wait) $COL_END" + echo "$COL_RED# Start at: $DATE $COL_END" +} + +footer() { + echo "" + print_line0 + get_time + echo "$COL_RED# Finish at: $DATE $COL_END" + echo "$COL_RED# END PROCESS..... $COL_END\n" +} + +remove_old() { + for TEMPL in $HELM_TEMPLATE + do + msg_remove $TEMPL + rm -f $TEMPL-*.tgz + echo "- DONE -" + done +} + +packaging() { + for TEMPL in $HELM_TEMPLATE + do + msg_package $TEMPL + helm package $TEMPL + echo "- DONE -" + done +} + +msg_remove() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Remove Old Package : $1 " + echo "$COL_GREEN[ $DATE ] rm -f $1-*.tgz $COL_END" + get_time + print_line2 +} + +msg_package() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Packaging Helm : $1 " + echo "$COL_GREEN[ $DATE ] helm package $1 $COL_END" + get_time + print_line2 +} + +main() { + header + remove_old + packaging + footer +} + +### START HERE ### +main $@ diff --git a/helm/template/staging/helm-push-staging.sh b/helm/template/staging/helm-push-staging.sh new file mode 100755 index 00000000..707f031c --- /dev/null +++ b/helm/template/staging/helm-push-staging.sh @@ -0,0 +1,111 @@ +#!/bin/sh + +set -e + +TITLE="HELM PACKAGE SCRIPT" # script name +VER="2.2" # script version + +HELM_VERSION="1.4.0" +HELM_TEMPLATE="api \ + backend \ + configmap \ + frontend \ + secretref \ + stateful \ + svcrole +" +HELM_REPO_PATH="s3://devopscorner-adot-chart/staging" +HELM_REPO_NAME="devopscorner-adot-staging" + +COL_RED="\033[22;31m" +COL_GREEN="\033[22;32m" +COL_BLUE="\033[22;34m" +COL_END="\033[0m" + +get_time() { + DATE=`date '+%Y-%m-%d %H:%M:%S'` +} + +print_line0() { + echo "$COL_GREEN=====================================================================================$COL_END" +} + +print_line1() { + echo "$COL_GREEN-------------------------------------------------------------------------------------$COL_END" +} + +print_line2() { + echo "-------------------------------------------------------------------------------------" +} + +logo() { + clear + print_line0 + echo "$COL_RED'########:'########:'########:::'#######:::'######::::'#####:::'########:::'#######:: $COL_END" + echo "$COL_RED..... ##:: ##.....:: ##.... ##:'##.... ##:'##... ##::'##.. ##:: ##.... ##:'##.... ##: $COL_END" + echo "$COL_RED:::: ##::: ##::::::: ##:::: ##: ##:::: ##: ##:::..::'##:::: ##: ##:::: ##:..::::: ##: $COL_END" + echo "$COL_RED::: ##:::: ######::: ########:: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::'#######:: $COL_END" + echo "$COL_RED:: ##::::: ##...:::: ##.. ##::: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::...... ##: $COL_END" + echo "$COL_RED: ##:::::: ##::::::: ##::. ##:: ##:::: ##: ##::: ##:. ##:: ##:: ##:::: ##:'##:::: ##: $COL_END" + echo "$COL_RED ########: ########: ##:::. ##:. #######::. ######:::. #####::: ########::. #######:: $COL_END" + echo "$COL_RED........::........::..:::::..:::.......::::......:::::.....::::........::::.......::: $COL_END" + print_line1 + echo "$COL_BLUE# $TITLE :: ver-$VER $COL_END" + echo "$COL_GREEN# HELM CHART :: ver-$HELM_VERSION $COL_END" + echo "$COL_GREEN# HELM REPO PATH :: $HELM_REPO_PATH $COL_END" + echo "$COL_GREEN# HELM REPO NAME :: $HELM_REPO_NAME $COL_END" +} + +header() { + logo + print_line0 + get_time + echo "$COL_RED# BEGIN PROCESS..... (Please Wait) $COL_END" + echo "$COL_RED# Start at: $DATE $COL_END" +} + +footer() { + echo "" + print_line0 + get_time + echo "$COL_RED# Finish at: $DATE $COL_END" + echo "$COL_RED# END PROCESS..... $COL_END\n" +} + +push_package() { + for TEMPL in $HELM_TEMPLATE + do + msg_push $TEMPL + helm s3 push $TEMPL*.tgz $HELM_REPO_NAME --force + echo "- DONE -" + done +} + +msg_push() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Push Package Helm : $1 " + echo "$COL_GREEN[ $DATE ] helm s3 push $1 $HELM_REPO_NAME --force $COL_END" + print_line2 +} + +helm_update() { + echo "" + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Update Helm Repository : " + echo "$COL_GREEN[ $DATE ] helm repo update" + helm repo update + echo "- DONE -" +} + +main() { + header + push_package + helm_update + footer +} + +### START HERE ### +main $@ diff --git a/helm/template/staging/secretref/Chart.yaml b/helm/template/staging/secretref/Chart.yaml new file mode 100644 index 00000000..db8e911d --- /dev/null +++ b/helm/template/staging/secretref/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: secretref +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/staging/secretref/secretref.yaml b/helm/template/staging/secretref/secretref.yaml new file mode 100644 index 00000000..5ae675f2 --- /dev/null +++ b/helm/template/staging/secretref/secretref.yaml @@ -0,0 +1,13 @@ +secret: + enabled: true + name: secretref + mountPath: + subPath: {} + readOnly: true + data: {} + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" \ No newline at end of file diff --git a/helm/template/staging/secretref/templates/_helpers.tpl b/helm/template/staging/secretref/templates/_helpers.tpl new file mode 100644 index 00000000..0e04fafc --- /dev/null +++ b/helm/template/staging/secretref/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "secretref.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "secretref.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart stagingel. +*/}} +{{- define "secretref.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common stagingels +*/}} +{{- define "secretref.stagingels" -}} +helm.sh/chart: {{ include "secretref.chart" . }} +{{ include "secretref.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector stagingels +*/}} +{{- define "secretref.selectorLabels" -}} +app.kubernetes.io/name: {{ include "secretref.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "secretref.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "secretref.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/staging/secretref/templates/secret.yaml b/helm/template/staging/secretref/templates/secret.yaml new file mode 100644 index 00000000..c2056b11 --- /dev/null +++ b/helm/template/staging/secretref/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "secret.stagingels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/staging/secretref/values.yaml b/helm/template/staging/secretref/values.yaml new file mode 100644 index 00000000..3908af5b --- /dev/null +++ b/helm/template/staging/secretref/values.yaml @@ -0,0 +1,16 @@ +secret: + enabled: true + name: psql-cred + mountPath: /app/core/secret + subPath: {} + readOnly: true + data: + db-user: dXNlcm5hbWUK + db-pass: cGFzc3cwcmQK + db-host: MTI3LjAuMC4xCg== + +serviceAccount: + create: false + annotations: {} + name: "devopscorner" + namespace: "devopscorner-dev" \ No newline at end of file diff --git a/helm/template/staging/stateful/.helmignore b/helm/template/staging/stateful/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/staging/stateful/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/staging/stateful/Chart.yaml b/helm/template/staging/stateful/Chart.yaml new file mode 100644 index 00000000..e09ef1b5 --- /dev/null +++ b/helm/template/staging/stateful/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: stateful +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/staging/stateful/stateful.yaml b/helm/template/staging/stateful/stateful.yaml new file mode 100644 index 00000000..f102581f --- /dev/null +++ b/helm/template/staging/stateful/stateful.yaml @@ -0,0 +1,163 @@ +# Default values for spinnaker. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +replicaCount: 1 + +secret: + enabled: false + name: "secret-stateful" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-stateful" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json: |- + { + "AppName": "Stateful Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +livenessProbe: {} +# initialDelaySeconds: 30 +# periodSeconds: 10 +# timeoutSeconds: 5 +# successThreshold: 1 +# failureThreshold: 3 + +readinessProbe: {} +# initialDelaySeconds: 5 +# periodSeconds: 10 +# timeoutSeconds: 1 +# successThreshold: 1 +# failureThreshold: 3 + +## Persist data to a persistent volume +persistence: + enabled: false + ## database data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "gp2" + # persistentVolumeReclaimPolicy: Recycle + # volumeMode: Filesystem + accessMode: ReadWriteOnce + ## Persistant Volume + capacity: 20Gi + ## Persistant Volume Claim + size: 8Gi + annotations: {} + selector: {} + # matchLabels: + # release: "stable" + # matchExpressions: + # - {key: environment, operator: In, values: [dev]} + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + enable: false + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: stateful + +resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/staging/stateful/templates/_helpers.tpl b/helm/template/staging/stateful/templates/_helpers.tpl new file mode 100644 index 00000000..e5dccc30 --- /dev/null +++ b/helm/template/staging/stateful/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "stateful.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "stateful.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart stagingel. +*/}} +{{- define "stateful.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common stagingels +*/}} +{{- define "stateful.stagingels" -}} +helm.sh/chart: {{ include "stateful.chart" . }} +{{ include "stateful.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector stagingels +*/}} +{{- define "stateful.selectorLabels" -}} +app.kubernetes.io/name: {{ include "stateful.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "stateful.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "stateful.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/staging/stateful/templates/clusterrole.yaml b/helm/template/staging/stateful/templates/clusterrole.yaml new file mode 100644 index 00000000..1bef15a4 --- /dev/null +++ b/helm/template/staging/stateful/templates/clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "stateful.fullname" . }}-rbac +subjects: + - kind: ServiceAccount + name: {{ include "stateful.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/stateful/templates/configmap.yaml b/helm/template/staging/stateful/templates/configmap.yaml new file mode 100644 index 00000000..85562f57 --- /dev/null +++ b/helm/template/staging/stateful/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.configMap .Values.configMap.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "stateful.stagingels" . | nindent 4 }} +{{- with .Values.configMap.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/stateful/templates/deployment.yaml b/helm/template/staging/stateful/templates/deployment.yaml new file mode 100644 index 00000000..8c273d46 --- /dev/null +++ b/helm/template/staging/stateful/templates/deployment.yaml @@ -0,0 +1,106 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "stateful.stagingels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "stateful.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + stagingels: + {{- include "stateful.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "stateful.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.application.enabled }} + env: + {{- toYaml .Values.application.env | nindent 12 }} + {{- end }} + {{- if .Values.envFrom.enabled }} + envFrom: + {{- toYaml .Values.envFrom.envFrom | nindent 12 }} + {{- end }} + {{- if .Values.container }} + ports: + {{- with .Values.container.ports }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{ end }} + # livenessProbe: + # httpGet: + # path: / + # port: http + # readinessProbe: + # httpGet: + # path: / + # port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumeMounts: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + mountPath: {{ .Values.configMap.mountPath }} + readOnly: {{ .Values.configMap.readOnly }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + mountPath: {{ .Values.secret.mountPath }} + subPath: {{ .Values.secret.subPath }} + readOnly: {{ .Values.secret.readOnly }} + {{- end }} + {{- end }} + {{- if and .Values.volumes .Values.volumes.enabled }} + volumeMounts: + - name: {{ .Values.volumes.name }} + mountPath: {{ .Values.volumes.mountPath }} + {{- end }} + {{- if .Values.nodeSelector.enabled -}} + {{- with .Values.nodeSelector.select }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.configMap.enabled .Values.secret.enabled }} + volumes: + {{- if and .Values.configMap .Values.configMap.enabled }} + - name: {{ .Values.configMap.name }} + configMap: + name: {{ .Values.configMap.name }} + {{- end }} + {{- if and .Values.secret .Values.secret.enabled }} + - name: {{ .Values.secret.name }} + secret: + secretName: {{ .Values.secret.name }} + {{- end }} + {{- end }} diff --git a/helm/template/staging/stateful/templates/hpa.yaml b/helm/template/staging/stateful/templates/hpa.yaml new file mode 100644 index 00000000..ee006a32 --- /dev/null +++ b/helm/template/staging/stateful/templates/hpa.yaml @@ -0,0 +1,29 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "stateful.stagingels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "stateful.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/template/staging/stateful/templates/ingress.yaml b/helm/template/staging/stateful/templates/ingress.yaml new file mode 100644 index 00000000..2e72fdf9 --- /dev/null +++ b/helm/template/staging/stateful/templates/ingress.yaml @@ -0,0 +1,32 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "stateful.fullname" . -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else -}} +apiVersion: extensions/v1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + stagingels: + {{- include "stateful.stagingels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + {{- with .Values.ingress.hosts }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/stateful/templates/pv.yaml b/helm/template/staging/stateful/templates/pv.yaml new file mode 100644 index 00000000..07fc25b9 --- /dev/null +++ b/helm/template/staging/stateful/templates/pv.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} +kind: PersistentVolume +apiVersion: v1 +metadata: + name: {{ template "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} +{{- with .Values.persistence.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + stagingels: + app: {{ template "stateful.fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + {{- if .Values.persistence.capacity }} + capacity: + storage: {{ .Values.persistence.capacity | quote }} + {{- end }} + {{- if .Values.persistence.volumeMode }} + volumeMode: {{ .Values.persistence.volumeMode | quote }} + {{- end }} + accessModes: + - {{ .Values.persistence.accessMode | quote }} + {{- if .Values.persistence.persistentVolumeReclaimPolicy }} + persistentVolumeReclaimPolicy: {{ .Values.persistence.persistentVolumeReclaimPolicy | quote }} + {{- end }} +{{- if .Values.persistence.storageClass }} +{{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/stateful/templates/pvc.yaml b/helm/template/staging/stateful/templates/pvc.yaml new file mode 100644 index 00000000..3495919f --- /dev/null +++ b/helm/template/staging/stateful/templates/pvc.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} +{{- with .Values.persistence.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + stagingels: + app: {{ template "stateful.fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + accessModes: + - {{ .Values.persistence.accessMode | quote }} + {{- if .Values.persistence.volumeMode }} + volumeMode: {{ .Values.persistence.volumeMode | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} +{{- if .Values.persistence.storageClass }} +{{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" +{{- end }} +{{- end }} + {{- with .Values.persistence.annotations }} + selector: + {{ toYaml . | indent 4 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/template/staging/stateful/templates/secret.yaml b/helm/template/staging/stateful/templates/secret.yaml new file mode 100644 index 00000000..0b24bb9c --- /dev/null +++ b/helm/template/staging/stateful/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "stateful.stagingels" . | nindent 4 }} +{{- with .Values.secret.data }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/template/staging/stateful/templates/service.yaml b/helm/template/staging/stateful/templates/service.yaml new file mode 100644 index 00000000..0a9bd7ef --- /dev/null +++ b/helm/template/staging/stateful/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "stateful.fullname" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "stateful.stagingels" . | nindent 4 }} +spec: + {{- if .Values.service }} + type: {{ .Values.service.type }} + {{- with .Values.service.ports }} + ports: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + selector: + {{- include "stateful.selectorLabels" . | nindent 4 }} diff --git a/helm/template/staging/stateful/templates/serviceaccount.yaml b/helm/template/staging/stateful/templates/serviceaccount.yaml new file mode 100644 index 00000000..06831b1f --- /dev/null +++ b/helm/template/staging/stateful/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "stateful.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "stateful.stagingels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/staging/stateful/values.yaml b/helm/template/staging/stateful/values.yaml new file mode 100644 index 00000000..f801efd8 --- /dev/null +++ b/helm/template/staging/stateful/values.yaml @@ -0,0 +1,140 @@ +--- +replicaCount: 1 + +secret: + enabled: false + name: "secret-stateful" + mountPath: {} + subPath: {} + readOnly: true + data: {} + +configMap: + enabled: true + name: "config-stateful" + mountPath: /app/core/config + readOnly: true + data: + .app.config.json : |- + { + "AppName": "Stateful Helm Template", + "GRPCTimeout": 10, + "CacheExpiry": 300, + "CacheCleanup": 600, + "DefaultPageLimit": 3, + "ClientTimeout": 10 + } + +image: + repository: devopscorner/cicd:alpine + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + create: false + annotations: {} + name: "" + namespace: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +livenessProbe: {} +# initialDelaySeconds: 30 +# periodSeconds: 10 +# timeoutSeconds: 5 +# successThreshold: 1 +# failureThreshold: 3 + +readinessProbe: {} +# initialDelaySeconds: 5 +# periodSeconds: 10 +# timeoutSeconds: 1 +# successThreshold: 1 +# failureThreshold: 3 + +## Persist data to a persistent volume +persistence: + enabled: false + ## database data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "gp2" + # persistentVolumeReclaimPolicy: Recycle + # volumeMode: Filesystem + accessMode: ReadWriteOnce + ## Persistant Volume + capacity: 20Gi + ## Persistant Volume Claim + size: 8Gi + annotations: {} + selector: {} + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP + - name: psql + port: 5432 + targetPort: 5432 + protocol: TCP + +ingress: + enabled: false + annotations: {} + hosts: + - host: "" + paths: [] + tls: [] + +application: + enabled: true + env: + - name: HELM_TEMPLATE_NAME + value: stateful + +resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 100m + memory: 32Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: + enabled: true + select: + node: "default" + +tolerations: [] + +affinity: {} diff --git a/helm/template/staging/svcrole/.helmignore b/helm/template/staging/svcrole/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm/template/staging/svcrole/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/template/staging/svcrole/Chart.yaml b/helm/template/staging/svcrole/Chart.yaml new file mode 100644 index 00000000..78df3c9f --- /dev/null +++ b/helm/template/staging/svcrole/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +name: svcrole +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "1.4.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/helm/template/staging/svcrole/templates/_helpers.tpl b/helm/template/staging/svcrole/templates/_helpers.tpl new file mode 100644 index 00000000..f45f5199 --- /dev/null +++ b/helm/template/staging/svcrole/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "svcrole.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "svcrole.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart stagingel. +*/}} +{{- define "svcrole.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common stagingels +*/}} +{{- define "svcrole.stagingels" -}} +helm.sh/chart: {{ include "svcrole.chart" . }} +{{ include "svcrole.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector stagingels +*/}} +{{- define "svcrole.selectorLabels" -}} +app.kubernetes.io/name: {{ include "svcrole.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "svcrole.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "svcrole.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/template/staging/svcrole/templates/clusterrole.yaml b/helm/template/staging/svcrole/templates/clusterrole.yaml new file mode 100644 index 00000000..6b9af355 --- /dev/null +++ b/helm/template/staging/svcrole/templates/clusterrole.yaml @@ -0,0 +1,16 @@ +{{- if .Values.clusterrole.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Values.serviceAccount.namespace }}-micro-registry + namespace: {{ .Values.serviceAccount.namespace }} +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - list + - patch + - watch +{{- end }} diff --git a/helm/template/staging/svcrole/templates/rolebinding.yaml b/helm/template/staging/svcrole/templates/rolebinding.yaml new file mode 100644 index 00000000..a8ba4aa1 --- /dev/null +++ b/helm/template/staging/svcrole/templates/rolebinding.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ .Values.serviceAccount.namespace }}-rolebinding-micro-registry + namespace: {{ .Values.serviceAccount.namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole +{{- if .Values.clusterrole.create }} + name: {{ .Values.serviceAccount.namespace }}-micro-registry +{{- else }} + name: micro-registry +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ .Values.serviceAccount.name }} + namespace: {{ .Values.serviceAccount.namespace }} diff --git a/helm/template/staging/svcrole/templates/serviceaccount.yaml b/helm/template/staging/svcrole/templates/serviceaccount.yaml new file mode 100644 index 00000000..7ba202c9 --- /dev/null +++ b/helm/template/staging/svcrole/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "svcrole.serviceAccountName" . }} + namespace: {{ .Values.serviceAccount.namespace }} + stagingels: + {{- include "svcrole.stagingels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/template/staging/svcrole/values.yaml b/helm/template/staging/svcrole/values.yaml new file mode 100644 index 00000000..3f74b54b --- /dev/null +++ b/helm/template/staging/svcrole/values.yaml @@ -0,0 +1,9 @@ +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + namespace: "" diff --git a/module_community.lst b/module_community.lst new file mode 100644 index 00000000..e64648ea --- /dev/null +++ b/module_community.lst @@ -0,0 +1,10 @@ +-b 0.25.0 https://github.com/cloudposse/terraform-null-label.git +-b v0.1.0 https://github.com/cloudposse/terraform-aws-budgets.git +-b 0.3.0 https://github.com/cloudposse/terraform-aws-rds-cloudwatch-sns-alarms.git +-b 0.13.0 https://github.com/cloudposse/terraform-aws-route53-alias.git +-b 0.47.1 https://github.com/cloudposse/terraform-aws-s3-bucket.git +-b 0.26.0 https://github.com/cloudposse/terraform-aws-s3-log-storage.git +-b 1.0.0 https://github.com/cloudposse/terraform-aws-codebuild.git +-b 0.19.5 https://github.com/cloudposse/terraform-aws-cicd.git +-b 0.29.0 https://github.com/cloudposse/terraform-aws-ecs-codepipeline.git +-b 0.2.3 https://github.com/cloudposse/terraform-aws-code-deploy.git diff --git a/module_officials.lst b/module_officials.lst new file mode 100644 index 00000000..e1f8ba21 --- /dev/null +++ b/module_officials.lst @@ -0,0 +1,19 @@ +-b v6.7.0 https://github.com/terraform-aws-modules/terraform-aws-alb.git +-b v5.1.1 https://github.com/terraform-aws-modules/terraform-aws-autoscaling.git +-b v2.9.2 https://github.com/terraform-aws-modules/terraform-aws-cloudfront.git +-b v2.4.1 https://github.com/terraform-aws-modules/terraform-aws-cloudwatch.git +-b v1.2.2 https://github.com/terraform-aws-modules/terraform-aws-dynamodb-table.git +-b v3.4.0 https://github.com/terraform-aws-modules/terraform-aws-ec2-instance.git +-b v3.4.1 https://github.com/terraform-aws-modules/terraform-aws-ecs.git +-b v18.7.2 https://github.com/terraform-aws-modules/terraform-aws-eks.git +-b v3.0.1 https://github.com/terraform-aws-modules/terraform-aws-elb.git +-b v4.13.1 https://github.com/terraform-aws-modules/terraform-aws-iam.git +-b v2.34.0 https://github.com/terraform-aws-modules/terraform-aws-lambda.git +-b v1.0.1 https://github.com/terraform-aws-modules/terraform-aws-key-pair.git +https://github.com/terraform-aws-modules/terraform-aws-s3-object +-b v4.1.2 https://github.com/terraform-aws-modules/terraform-aws-rds.git +-b v2.5.0 https://github.com/terraform-aws-modules/terraform-aws-route53.git +-b v2.14.1 https://github.com/terraform-aws-modules/terraform-aws-s3-bucket.git +-b v4.8.0 https://github.com/terraform-aws-modules/terraform-aws-security-group.git +-b v3.12.0 https://github.com/terraform-aws-modules/terraform-aws-vpc.git +-b v2.11.1 https://github.com/terraform-aws-modules/terraform-aws-vpn-gateway.git diff --git a/run-docker.sh b/run-docker.sh new file mode 100755 index 00000000..b924318e --- /dev/null +++ b/run-docker.sh @@ -0,0 +1,198 @@ +#!/usr/bin/env sh +# ----------------------------------------------------------------------------- +# Docker Build Container +# ----------------------------------------------------------------------------- +# Author : Dwi Fahni Denni (@zeroc0d3) +# License : Apache v2 +# ----------------------------------------------------------------------------- +set -e + +TITLE="DOCKER BUILD CONTAINER SCRIPT" # script name +VER="3.1" # script version +ENV="0" # container environment (0 = development, 1 = staging, 2 = production) +SKIP_BUILD="0" # (0 = with build process, 1 = bypass build process) +REMOVE_CACHE="0" # (0 = using cache, 1 = no-cache) +RECREATE_CONTAINER="0" # (0 = disable recreate container, 1 = force recreate container) +DAEMON_MODE="1" # (0 = disable daemon mode, 1 = running daemon mode / background) +CHMOD_DATA="0" # (0 = disable chmod 777 folder data, 1 = skip chmod 777 folder data) + +USERNAME=$(echo $USER) +PATH_HOME=$(echo $HOME) + +PATH_APP=$(pwd) +PATH_CONTAINER_DATA="$PATH_APP/data" +COMPOSE_PATH="$PATH_APP" +COMPOSE_APP="$COMPOSE_PATH/docker-compose.yml" + +COL_RED="\033[22;31m" +COL_GREEN="\033[22;32m" +COL_BLUE="\033[22;34m" +COL_END="\033[0m" + +export RUBY_VERSION="2.7.1" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +print_line0() { + echo "$COL_GREEN=====================================================================================$COL_END" +} + +print_line1() { + echo "$COL_GREEN-------------------------------------------------------------------------------------$COL_END" +} + +print_line2() { + echo "-------------------------------------------------------------------------------------" +} + +logo() { + clear + print_line0 + echo "$COL_RED'########:'########:'########:::'#######:::'######::::'#####:::'########:::'#######:: $COL_END" + echo "$COL_RED..... ##:: ##.....:: ##.... ##:'##.... ##:'##... ##::'##.. ##:: ##.... ##:'##.... ##: $COL_END" + echo "$COL_RED:::: ##::: ##::::::: ##:::: ##: ##:::: ##: ##:::..::'##:::: ##: ##:::: ##:..::::: ##: $COL_END" + echo "$COL_RED::: ##:::: ######::: ########:: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::'#######:: $COL_END" + echo "$COL_RED:: ##::::: ##...:::: ##.. ##::: ##:::: ##: ##::::::: ##:::: ##: ##:::: ##::...... ##: $COL_END" + echo "$COL_RED: ##:::::: ##::::::: ##::. ##:: ##:::: ##: ##::: ##:. ##:: ##:: ##:::: ##:'##:::: ##: $COL_END" + echo "$COL_RED ########: ########: ##:::. ##:. #######::. ######:::. #####::: ########::. #######:: $COL_END" + echo "$COL_RED........::........::..:::::..:::.......::::......:::::.....::::........::::.......::: $COL_END" + print_line1 + echo "$COL_GREEN# $TITLE :: ver-$VER $COL_END" +} + +header() { + logo + print_line0 + get_time + echo "$COL_RED# BEGIN PROCESS..... (Please Wait) $COL_END" + echo "$COL_RED# Start at: $DATE $COL_END\n" +} + +footer() { + print_line0 + get_time + echo "$COL_RED# Finish at: $DATE $COL_END" + echo "$COL_RED# END PROCESS..... $COL_END\n" +} + +chmod_data() { + if [ "$CHMOD_DATA" = "1" ]; then + sudo chmod 777 -R $PATH_CONTAINER_DATA + fi +} + +build_env() { + if [ "$ENV" = "0" ]; then + BUILD_ENV="$CONTAINER_DEVELOPMENT" + elif [ "$ENV" = "1" ]; then + BUILD_ENV="$CONTAINER_STAGING" + else + BUILD_ENV="$CONTAINER_PRODUCTION" + fi +} + +cache() { + if [ "$REMOVE_CACHE" = "0" ]; then + CACHE="" + else + CACHE="--no-cache " + fi +} + +recreate() { + if [ "$RECREATE_CONTAINER" = "0" ]; then + RECREATE="" + else + RECREATE="--force-recreate " + fi +} + +daemon_mode() { + if [ "$DAEMON_MODE" = "0" ]; then + DAEMON="" + else + DAEMON="-d " + fi +} + +prepare_volume() { + print_line2 + + VOL_PATH="/opt/data/docker" + + # VOL_CONTAINER="$VOL_PATH/airflow/dags \ + # $VOL_PATH/airflow/logs \ + # $VOL_PATH/airflow/plugins \ + # $VOL_PATH/postgresql14/pgdata \ + # $VOL_PATH/portainer" + + get_time + echo "$COL_BLUE[ $DATE ] ##### Prepare Volume Container: $COL_END" + echo "$COL_GREEN[ $DATE ] sudo mkdir -p [vol_docker]\n" + + # for VOL in $VOL_CONTAINER; do + # get_time + # print_line2 + # echo "$COL_GREEN[ $DATE ] sudo mkdir -p $VOL $COL_END" + # print_line2 + # sudo mkdir -p $VOL + # echo '- DONE -' + # done + + sudo chmod -R 777 $VOL_PATH + echo "-- VOLUME DONE --" + echo '' +} + +docker_build() { + if [ "$SKIP_BUILD" = "0" ]; then + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Docker Compose Build: $COL_END" + echo "$COL_GREEN[ $DATE ] docker-compose -f $COMPOSE_APP build $CACHE$BUILD_ENV $COL_END\n" + + for CONTAINER in $BUILD_ENV; do + get_time + print_line2 + echo "$COL_GREEN[ $DATE ] docker-compose -f $COMPOSE_APP build $CONTAINER $COL_END" + print_line2 + docker-compose -f $COMPOSE_APP build $CONTAINER + echo '- DONE -' + echo '' + done + fi + echo "-- BUILD DONE --" + echo '' +} + +docker_up() { + daemon_mode + print_line2 + get_time + echo "$COL_BLUE[ $DATE ] ##### Docker Compose Up: $COL_END" + echo "$COL_GREEN[ $DATE ] docker-compose -f $COMPOSE_APP up $DAEMON $RECREATE$BUILD_ENV $COL_END\n" + get_time + print_line2 + echo "$COL_GREEN[ $DATE ] docker-compose -f $COMPOSE_APP up $DAEMON $RECREATE$BUILD_ENV $COL_END" + print_line2 + docker-compose -f $COMPOSE_APP up $DAEMON $RECREATE$BUILD_ENV + echo "-- UP DONE --" + echo '' +} + +main() { + header + cache + recreate + build_env + #prepare_volume + docker_build + docker_up + footer + # chmod_data +} + +### START HERE ### +main $@ diff --git a/scripts/01-install-terraform-modules.sh b/scripts/01-install-terraform-modules.sh new file mode 100755 index 00000000..cbff876c --- /dev/null +++ b/scripts/01-install-terraform-modules.sh @@ -0,0 +1,85 @@ +# Install Terraform Modules + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +module_cleanup() { + echo $line2 + echo " Cleanup All Previous Modules..." + echo " \$ rm -rf $TF_MODULE_PATH" + echo $line2 + sleep 2 + rm -rf $TF_MODULE_PATH + echo ' - DONE - ' + echo '' + sleep 1 +} + +install_module_officials() { + echo $line2 + echo " Download Officials Modules..." + echo " \$ make sub-officials" + echo $line2 + sleep 2 + cd $REPO_PATH + make sub-officials + echo ' - DONE - ' + echo '' + sleep 1 +} + +install_module_community() { + echo $line2 + echo " Download Community Modules..." + echo " \$ make sub-community" + echo $line2 + sleep 2 + cd $REPO_PATH + make sub-community + echo ' - DONE - ' + echo '' + sleep 1 +} + +show_modules() { + echo $line2 + echo " Check Module List..." + echo " \$ ls -alR $ALL_MODULES_PATH" + echo $line2 + sleep 2 + ls -alR $ALL_MODULES_PATH + echo ' - DONE - ' +} + +main() { + module_cleanup + install_module_officials + install_module_community + show_modules + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main + diff --git a/scripts/02-provisioning-helm-template.sh b/scripts/02-provisioning-helm-template.sh new file mode 100755 index 00000000..5de84340 --- /dev/null +++ b/scripts/02-provisioning-helm-template.sh @@ -0,0 +1,300 @@ +# Provisioning Helm Template + +#!/usr/bin/env sh + +# set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export HELM_PATH="helm" +export HELM_SRC="$REPO_PATH/$HELM_PATH/template" +export BUCKET_NAME="devopscorner-adot-chart" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +s3_empty_bucket() { + echo $line2 + echo " Empty All Bucket Objects..." + echo " \$ aws s3 rm s3://$BUCKET_NAME --recursive" + echo $line2 + sleep 2 + aws s3 rm s3://$BUCKET_NAME --recursive + echo ' - DONE - ' + echo '' + sleep 1 +} + +s3_delete_bucket() { + echo $line2 + echo " Delete Bucket..." + echo " \$ aws s3 rb s3://$BUCKET_NAME --region us-west-2" + echo $line2 + sleep 2 + aws s3 rb s3://$BUCKET_NAME --region us-west-2 + echo ' - DONE - ' + echo '' + sleep 1 +} + +s3_create_bucket() { + echo $line2 + echo " Create Bucket..." + echo " \$ aws s3 mb s3://$BUCKET_NAME --region us-west-2" + echo $line2 + sleep 2 + aws s3 mb s3://$BUCKET_NAME --region us-west-2 + echo ' - DONE - ' + echo '' + sleep 1 +} + +s3_check_bucket() { + echo $line2 + echo " Check Bucket Created..." + echo " \$ aws s3 ls s3://$BUCKET_NAME --recursive --human-readable --summarize" + echo $line2 + sleep 2 + aws s3 ls s3://$BUCKET_NAME --recursive --human-readable --summarize + echo ' - DONE - ' + echo '' + sleep 1 +} + +cleanup_helm_repo() { + echo $line2 + echo " Cleanup Helm Repository..." + echo $line2 + helm repo rm stable + helm repo rm devopscorner-adot + helm repo rm devopscorner-adot-staging + helm repo rm devopscorner-adot-lab + echo ' - DONE - ' + echo '' + sleep 1 +} + +check_helm_repo() { + echo $line2 + echo " Check Existing Helm Repository..." + echo " \$ helm repo list" + echo $line2 + helm repo list + echo ' - DONE - ' + echo '' + sleep 1 +} + +init_helm_repo_prod() { + echo $line1 + echo " Initialize Helm Repo Production..." + echo " \$ helm s3 init s3://$BUCKET_NAME/prod" + echo $line1 + helm s3 init s3://$BUCKET_NAME/prod + echo ' - DONE - ' + echo '' + sleep 1 +} + +init_helm_repo_staging() { + echo $line1 + echo " Initialize Helm Repo Staging..." + echo " \$ helm s3 init s3://$BUCKET_NAME/staging" + echo $line1 + helm s3 init s3://$BUCKET_NAME/staging + echo ' - DONE -' + echo '' + sleep 1 +} + +init_helm_repo_lab() { + echo $line1 + echo " Initialize Helm Repo Lab..." + echo " \$ helm s3 init s3://$BUCKET_NAME/lab" + echo $line1 + helm s3 init s3://$BUCKET_NAME/lab + echo ' - DONE - ' + echo '' + sleep 1 +} + +init_helm() { + echo $line2 + echo " Initialize Helm Repository..." + echo $line2 + sleep 1 + echo '' + init_helm_repo_prod + init_helm_repo_staging + init_helm_repo_lab + echo '' +} + + +added_helm_repo_stable() { + echo $line2 + echo " Initialize Helm Repo Stable..." + echo " \$ helm repo add stable https://charts.helm.sh/stable" + echo $line2 + helm repo add stable https://charts.helm.sh/stable + helm repo update + echo ' - DONE -' + echo '' + sleep 1 +} + + +register_helm_repo_prod() { + echo $line1 + echo " Register Helm Repo Production..." + echo " \$ AWS_REGION=us-west-2 helm repo add devopscorner-adot s3://$BUCKET_NAME/prod" + echo $line1 + sleep 1 + AWS_REGION=us-west-2 helm repo add devopscorner-adot s3://$BUCKET_NAME/prod + echo ' - DONE -' + echo '' +} + +register_helm_repo_staging() { + echo $line1 + echo " Register Helm Repo Staging..." + echo " \$ AWS_REGION=us-west-2 helm repo add devopscorner-adot-staging s3://$BUCKET_NAME/staging" + echo $line1 + sleep 1 + AWS_REGION=us-west-2 helm repo add devopscorner-adot-staging s3://$BUCKET_NAME/staging + echo ' - DONE -' + echo '' +} + +register_helm_repo_lab() { + echo $line1 + echo " Register Helm Repo Lab..." + echo " \$ AWS_REGION=us-west-2 helm repo add devopscorner-adot-lab s3://$BUCKET_NAME/lab" + echo $line1 + sleep 1 + AWS_REGION=us-west-2 helm repo add devopscorner-adot-lab s3://$BUCKET_NAME/lab + echo ' - DONE -' + echo '' +} + +register_helm() { + echo $line2 + echo " Register Helm Repository..." + echo $line2 + sleep 1 + echo '' + register_helm_repo_prod + register_helm_repo_staging + register_helm_repo_lab + check_helm_repo +} + +packing_push_helm_prod() { + echo $line1 + echo " Packaging Helm Template Production..." + echo " \$ cd $HELM_SRC/prod && ./helm-pack-prod.sh" + echo $line1 + cd $HELM_SRC/prod + sh ./helm-pack-prod.sh + echo ' - DONE -' + echo '' + sleep 1 + + echo $line1 + echo " Push Helm Template Production..." + echo " \$ cd $HELM_SRC/prod && ./helm-push-prod.sh" + echo $line1 + cd $HELM_SRC/prod + sh ./helm-push-prod.sh + echo ' - DONE -' + echo '' + sleep 1 +} + +packing_push_helm_staging() { + echo $line1 + echo " Packaging Helm Template Staging..." + echo " \$ cd $HELM_SRC/staging && ./helm-pack-staging.sh" + echo $line1 + cd $HELM_SRC/staging + sh ./helm-pack-staging.sh + echo ' - DONE -' + echo '' + sleep 1 + + echo $line1 + echo " Push Helm Template Staging..." + echo " \$ cd $HELM_SRC/staging && ./helm-push-staging.sh" + echo $line1 + cd $HELM_SRC/staging + sh ./helm-push-staging.sh + echo ' - DONE -' + echo '' + sleep 1 +} + +packing_push_helm_lab() { + echo $line1 + echo " Packaging Helm Template Lab..." + echo " \$ cd $HELM_SRC/lab && ./helm-pack-lab.sh" + echo $line1 + cd $HELM_SRC/lab + sh ./helm-pack-lab.sh + echo ' - DONE -' + echo '' + sleep 1 + + echo $line1 + echo " Push Helm Template Lab..." + echo " \$ cd $HELM_SRC/lab && ./helm-push-lab.sh" + echo $line1 + cd $HELM_SRC/lab + sh ./helm-push-lab.sh + echo ' - DONE -' + echo '' + sleep 1 +} + +packing_push_helm() { + echo $line2 + echo " Packing & Push Helm Template..." + echo $line2 + echo '' + sleep 2 + packing_push_helm_prod + packing_push_helm_staging + packing_push_helm_lab +} + +cleanup_existing() { + s3_empty_bucket + s3_delete_bucket + cleanup_helm_repo +} + + +main() { + cleanup_existing + s3_create_bucket + s3_check_bucket + added_helm_repo_stable + check_helm_repo + init_helm + register_helm + packing_push_helm + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main diff --git a/scripts/03.1-provisioning-tfstate-plan.sh b/scripts/03.1-provisioning-tfstate-plan.sh new file mode 100755 index 00000000..b4a70f92 --- /dev/null +++ b/scripts/03.1-provisioning-tfstate-plan.sh @@ -0,0 +1,200 @@ +# Provisioning TFState + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +cleanup_terraform() { + echo $line2 + echo " Cleanup Terraform TFState..." + echo " \$ rm -rf .terraform .terraform.lock.hcl terraform.tfstate.d" + echo $line2 + cd $TF_STATE_PATH + rm -rf .terraform .terraform.lock.hcl terraform.tfstate.d + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_init() { + echo $line2 + echo " Initialize Terraform..." + echo " \$ terraform init" + echo $line2 + cd $TF_STATE_PATH + terraform init + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_STATE_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_plan() { + echo $line2 + echo " Terraform Plan & Save Binary Plan..." + echo " \$ terraform plan --out tfplan.binary" + echo $line2 + cd $TF_STATE_PATH + terraform plan --out tfplan.binary + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_save_plan() { + echo $line2 + echo " Export JSON Terraform Plan..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_STATE_PATH + terraform show -json tfplan.binary > tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_security() { + echo $line2 + echo " Running Security Inspect Terraform..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_STATE_PATH + # ================== # + # Terraform Addons # + # ================== # + # ~ Terrascan ~ + echo $line1 + echo " Using: terrascan ..." + echo " \$ terrascan init" + echo " \$ terrascan scan -o human" + echo $line1 + terrascan init + terrascan scan -o human + echo '' + sleep 1 + + # ~ Tfsec ~ + echo $line1 + echo " Using: tfsec ..." + echo " \$ tfsec ." + echo $line1 + tfsec . + echo '' + sleep 1 + + # ~ Checkov + echo $line1 + echo " Using: checkov ..." + echo " \$ checkov -f tfplan.json" + echo $line1 + tfsec . + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_cost_review() { + echo $line2 + echo " Cost Review Terraform..." + echo " \$ infracost breakdown --path tfplan.json" + echo $line2 + cd $TF_STATE_PATH + # ~ Infracost + infracost breakdown --path tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_STATE_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_STATE_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + cleanup_terraform + terraform_init + terraform_workspace + terraform_plan + terraform_save_plan + # terraform_security + terraform_cost_review + # terraform_apply + # terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/03.2-provisioning-tfstate-apply.sh b/scripts/03.2-provisioning-tfstate-apply.sh new file mode 100755 index 00000000..1fbee906 --- /dev/null +++ b/scripts/03.2-provisioning-tfstate-apply.sh @@ -0,0 +1,70 @@ +# Provisioning TFState + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_STATE_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_STATE_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_apply + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/04.1-provisioning-infra-core-plan.sh b/scripts/04.1-provisioning-infra-core-plan.sh new file mode 100755 index 00000000..d298a060 --- /dev/null +++ b/scripts/04.1-provisioning-infra-core-plan.sh @@ -0,0 +1,200 @@ +# Provisioning Infra Core + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +cleanup_terraform() { + echo $line2 + echo " Cleanup Terraform Core..." + echo " \$ rm -rf .terraform .terraform.lock.hcl terraform.core.d" + echo $line2 + cd $TF_CORE_PATH + rm -rf .terraform .terraform.lock.hcl terraform.core.d + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_init() { + echo $line2 + echo " Initialize Terraform..." + echo " \$ terraform init" + echo $line2 + cd $TF_CORE_PATH + terraform init + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_CORE_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_plan() { + echo $line2 + echo " Terraform Plan & Save Binary Plan..." + echo " \$ terraform plan --out tfplan.binary" + echo $line2 + cd $TF_CORE_PATH + terraform plan --out tfplan.binary + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_save_plan() { + echo $line2 + echo " Export JSON Terraform Plan..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_CORE_PATH + terraform show -json tfplan.binary > tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_security() { + echo $line2 + echo " Running Security Inspect Terraform..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_CORE_PATH + # ================== # + # Terraform Addons # + # ================== # + # ~ Terrascan ~ + echo $line1 + echo " Using: terrascan ..." + echo " \$ terrascan init" + echo " \$ terrascan scan -o human" + echo $line1 + terrascan init + terrascan scan -o human + echo '' + sleep 1 + + # ~ Tfsec ~ + echo $line1 + echo " Using: tfsec ..." + echo " \$ tfsec ." + echo $line1 + tfsec . + echo '' + sleep 1 + + # ~ Checkov + echo $line1 + echo " Using: checkov ..." + echo " \$ checkov -f tfplan.json" + echo $line1 + tfsec . + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_cost_review() { + echo $line2 + echo " Cost Review Terraform..." + echo " \$ infracost breakdown --path tfplan.json" + echo $line2 + cd $TF_CORE_PATH + # ~ Infracost + infracost breakdown --path tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_CORE_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_CORE_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + cleanup_terraform + terraform_init + terraform_workspace + terraform_plan + terraform_save_plan + # terraform_security + terraform_cost_review + # terraform_apply + # terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/04.2-provisioning-infra-core-apply.sh b/scripts/04.2-provisioning-infra-core-apply.sh new file mode 100755 index 00000000..00f52c9b --- /dev/null +++ b/scripts/04.2-provisioning-infra-core-apply.sh @@ -0,0 +1,70 @@ +# Provisioning Infra Core + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_CORE_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_CORE_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_apply + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/05.1-provisioning-infra-cicd-plan.sh b/scripts/05.1-provisioning-infra-cicd-plan.sh new file mode 100755 index 00000000..c80529d8 --- /dev/null +++ b/scripts/05.1-provisioning-infra-cicd-plan.sh @@ -0,0 +1,201 @@ +# Provisioning Infra CI/CD + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_CICD_PATH="$TF_RESOURCES_PATH/cicd" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +cleanup_terraform() { + echo $line2 + echo " Cleanup Terraform Core..." + echo " \$ rm -rf .terraform .terraform.lock.hcl terraform.cicd.d" + echo $line2 + cd $TF_CICD_PATH + rm -rf .terraform .terraform.lock.hcl terraform.cicd.d + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_init() { + echo $line2 + echo " Initialize Terraform..." + echo " \$ terraform init" + echo $line2 + cd $TF_CICD_PATH + terraform init + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_CICD_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_plan() { + echo $line2 + echo " Terraform Plan & Save Binary Plan..." + echo " \$ terraform plan --out tfplan.binary" + echo $line2 + cd $TF_CICD_PATH + terraform plan --out tfplan.binary + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_save_plan() { + echo $line2 + echo " Export JSON Terraform Plan..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_CICD_PATH + terraform show -json tfplan.binary > tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_security() { + echo $line2 + echo " Running Security Inspect Terraform..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_CICD_PATH + # ================== # + # Terraform Addons # + # ================== # + # ~ Terrascan ~ + echo $line1 + echo " Using: terrascan ..." + echo " \$ terrascan init" + echo " \$ terrascan scan -o human" + echo $line1 + terrascan init + terrascan scan -o human + echo '' + sleep 1 + + # ~ Tfsec ~ + echo $line1 + echo " Using: tfsec ..." + echo " \$ tfsec ." + echo $line1 + tfsec . + echo '' + sleep 1 + + # ~ Checkov + echo $line1 + echo " Using: checkov ..." + echo " \$ checkov -f tfplan.json" + echo $line1 + tfsec . + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_cost_review() { + echo $line2 + echo " Cost Review Terraform..." + echo " \$ infracost breakdown --path tfplan.json" + echo $line2 + cd $TF_CICD_PATH + # ~ Infracost + infracost breakdown --path tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_CICD_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_CICD_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + cleanup_terraform + terraform_init + terraform_workspace + terraform_plan + terraform_save_plan + # terraform_security + terraform_cost_review + # terraform_apply + # terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/05.2-provisioning-infra-cicd-apply.sh b/scripts/05.2-provisioning-infra-cicd-apply.sh new file mode 100755 index 00000000..8b4c7e05 --- /dev/null +++ b/scripts/05.2-provisioning-infra-cicd-apply.sh @@ -0,0 +1,71 @@ +# Provisioning Infra CI/CD + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_CICD_PATH="$TF_RESOURCES_PATH/cicd" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_CICD_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_CICD_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_apply + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/06.1-provisioning-resources-eks-plan.sh b/scripts/06.1-provisioning-resources-eks-plan.sh new file mode 100755 index 00000000..45b0b650 --- /dev/null +++ b/scripts/06.1-provisioning-resources-eks-plan.sh @@ -0,0 +1,201 @@ +# Provisioning Amazon EKS + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_EKS_PATH="$TF_RESOURCES_PATH/eks" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +cleanup_terraform() { + echo $line2 + echo " Cleanup Terraform Core..." + echo " \$ rm -rf .terraform .terraform.lock.hcl terraform.eks.d" + echo $line2 + cd $TF_EKS_PATH + rm -rf .terraform .terraform.lock.hcl terraform.eks.d + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_init() { + echo $line2 + echo " Initialize Terraform..." + echo " \$ terraform init" + echo $line2 + cd $TF_EKS_PATH + terraform init + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_EKS_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_plan() { + echo $line2 + echo " Terraform Plan & Save Binary Plan..." + echo " \$ terraform plan --out tfplan.binary" + echo $line2 + cd $TF_EKS_PATH + terraform plan --out tfplan.binary + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_save_plan() { + echo $line2 + echo " Export JSON Terraform Plan..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_EKS_PATH + terraform show -json tfplan.binary > tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_security() { + echo $line2 + echo " Running Security Inspect Terraform..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_EKS_PATH + # ================== # + # Terraform Addons # + # ================== # + # ~ Terrascan ~ + echo $line1 + echo " Using: terrascan ..." + echo " \$ terrascan init" + echo " \$ terrascan scan -o human" + echo $line1 + terrascan init + terrascan scan -o human + echo '' + sleep 1 + + # ~ Tfsec ~ + echo $line1 + echo " Using: tfsec ..." + echo " \$ tfsec ." + echo $line1 + tfsec . + echo '' + sleep 1 + + # ~ Checkov + echo $line1 + echo " Using: checkov ..." + echo " \$ checkov -f tfplan.json" + echo $line1 + tfsec . + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_cost_review() { + echo $line2 + echo " Cost Review Terraform..." + echo " \$ infracost breakdown --path tfplan.json" + echo $line2 + cd $TF_EKS_PATH + # ~ Infracost + infracost breakdown --path tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_EKS_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_EKS_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + cleanup_terraform + terraform_init + terraform_workspace + terraform_plan + terraform_save_plan + # terraform_security + terraform_cost_review + # terraform_apply + # terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/06.2-provisioning-resources-eks-apply.sh b/scripts/06.2-provisioning-resources-eks-apply.sh new file mode 100755 index 00000000..2101573f --- /dev/null +++ b/scripts/06.2-provisioning-resources-eks-apply.sh @@ -0,0 +1,71 @@ +# Provisioning Amazon EKS + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_EKS_PATH="$TF_RESOURCES_PATH/eks" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_EKS_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_EKS_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_apply + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/07.1-provisioning-resources-amp-plan.sh b/scripts/07.1-provisioning-resources-amp-plan.sh new file mode 100755 index 00000000..474ad869 --- /dev/null +++ b/scripts/07.1-provisioning-resources-amp-plan.sh @@ -0,0 +1,201 @@ +# Provisioning Managed Services Prometheus (AMP) + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_AMP_PATH="$TF_RESOURCES_PATH/amp" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +cleanup_terraform() { + echo $line2 + echo " Cleanup Terraform Core..." + echo " \$ rm -rf .terraform .terraform.lock.hcl terraform.amp.d" + echo $line2 + cd $TF_AMP_PATH + rm -rf .terraform .terraform.lock.hcl terraform.amp.d + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_init() { + echo $line2 + echo " Initialize Terraform..." + echo " \$ terraform init" + echo $line2 + cd $TF_AMP_PATH + terraform init + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_AMP_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_plan() { + echo $line2 + echo " Terraform Plan & Save Binary Plan..." + echo " \$ terraform plan --out tfplan.binary" + echo $line2 + cd $TF_AMP_PATH + terraform plan --out tfplan.binary + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_save_plan() { + echo $line2 + echo " Export JSON Terraform Plan..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_AMP_PATH + terraform show -json tfplan.binary > tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_security() { + echo $line2 + echo " Running Security Inspect Terraform..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_AMP_PATH + # ================== # + # Terraform Addons # + # ================== # + # ~ Terrascan ~ + echo $line1 + echo " Using: terrascan ..." + echo " \$ terrascan init" + echo " \$ terrascan scan -o human" + echo $line1 + terrascan init + terrascan scan -o human + echo '' + sleep 1 + + # ~ Tfsec ~ + echo $line1 + echo " Using: tfsec ..." + echo " \$ tfsec ." + echo $line1 + tfsec . + echo '' + sleep 1 + + # ~ Checkov + echo $line1 + echo " Using: checkov ..." + echo " \$ checkov -f tfplan.json" + echo $line1 + tfsec . + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_cost_review() { + echo $line2 + echo " Cost Review Terraform..." + echo " \$ infracost breakdown --path tfplan.json" + echo $line2 + cd $TF_AMP_PATH + # ~ Infracost + infracost breakdown --path tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_AMP_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_AMP_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + cleanup_terraform + terraform_init + terraform_workspace + terraform_plan + terraform_save_plan + # terraform_security + terraform_cost_review + # terraform_apply + # terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/07.2-provisioning-resources-amp-apply.sh b/scripts/07.2-provisioning-resources-amp-apply.sh new file mode 100755 index 00000000..8e6b2ca1 --- /dev/null +++ b/scripts/07.2-provisioning-resources-amp-apply.sh @@ -0,0 +1,71 @@ +# Provisioning Managed Services Prometheus (AMP) + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_AMP_PATH="$TF_RESOURCES_PATH/amp" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_AMP_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_AMP_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_apply + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/08.1-provisioning-resources-amg-plan.sh b/scripts/08.1-provisioning-resources-amg-plan.sh new file mode 100755 index 00000000..0f6fe021 --- /dev/null +++ b/scripts/08.1-provisioning-resources-amg-plan.sh @@ -0,0 +1,201 @@ +# Provisioning Managed Services Grafana (AMG) + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_OPENSEARCH_PATH="$TF_RESOURCES_PATH/opensearch" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +cleanup_terraform() { + echo $line2 + echo " Cleanup Terraform Core..." + echo " \$ rm -rf .terraform .terraform.lock.hcl terraform.opensearch.d" + echo $line2 + cd $TF_OPENSEARCH_PATH + rm -rf .terraform .terraform.lock.hcl terraform.opensearch.d + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_init() { + echo $line2 + echo " Initialize Terraform..." + echo " \$ terraform init" + echo $line2 + cd $TF_OPENSEARCH_PATH + terraform init + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_OPENSEARCH_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_plan() { + echo $line2 + echo " Terraform Plan & Save Binary Plan..." + echo " \$ terraform plan --out tfplan.binary" + echo $line2 + cd $TF_OPENSEARCH_PATH + terraform plan --out tfplan.binary + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_save_plan() { + echo $line2 + echo " Export JSON Terraform Plan..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_OPENSEARCH_PATH + terraform show -json tfplan.binary > tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_security() { + echo $line2 + echo " Running Security Inspect Terraform..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_OPENSEARCH_PATH + # ================== # + # Terraform Addons # + # ================== # + # ~ Terrascan ~ + echo $line1 + echo " Using: terrascan ..." + echo " \$ terrascan init" + echo " \$ terrascan scan -o human" + echo $line1 + terrascan init + terrascan scan -o human + echo '' + sleep 1 + + # ~ Tfsec ~ + echo $line1 + echo " Using: tfsec ..." + echo " \$ tfsec ." + echo $line1 + tfsec . + echo '' + sleep 1 + + # ~ Checkov + echo $line1 + echo " Using: checkov ..." + echo " \$ checkov -f tfplan.json" + echo $line1 + tfsec . + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_cost_review() { + echo $line2 + echo " Cost Review Terraform..." + echo " \$ infracost breakdown --path tfplan.json" + echo $line2 + cd $TF_OPENSEARCH_PATH + # ~ Infracost + infracost breakdown --path tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_OPENSEARCH_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_OPENSEARCH_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + cleanup_terraform + terraform_init + terraform_workspace + terraform_plan + terraform_save_plan + # terraform_security + terraform_cost_review + # terraform_apply + # terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/08.2-provisioning-resources-amg-apply.sh b/scripts/08.2-provisioning-resources-amg-apply.sh new file mode 100755 index 00000000..34a7472f --- /dev/null +++ b/scripts/08.2-provisioning-resources-amg-apply.sh @@ -0,0 +1,71 @@ +# Provisioning Managed Services Grafana (AMG) + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_AMG_PATH="$TF_RESOURCES_PATH/amg" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_AMG_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_AMG_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_apply + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/09.1-provisioning-resources-opensearch-plan.sh b/scripts/09.1-provisioning-resources-opensearch-plan.sh new file mode 100755 index 00000000..9998440a --- /dev/null +++ b/scripts/09.1-provisioning-resources-opensearch-plan.sh @@ -0,0 +1,201 @@ +# Provisioning Managed Services Grafana (AMG) + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_AMG_PATH="$TF_RESOURCES_PATH/amg" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +cleanup_terraform() { + echo $line2 + echo " Cleanup Terraform Core..." + echo " \$ rm -rf .terraform .terraform.lock.hcl terraform.amg.d" + echo $line2 + cd $TF_AMG_PATH + rm -rf .terraform .terraform.lock.hcl terraform.amg.d + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_init() { + echo $line2 + echo " Initialize Terraform..." + echo " \$ terraform init" + echo $line2 + cd $TF_AMG_PATH + terraform init + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_AMG_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_plan() { + echo $line2 + echo " Terraform Plan & Save Binary Plan..." + echo " \$ terraform plan --out tfplan.binary" + echo $line2 + cd $TF_AMG_PATH + terraform plan --out tfplan.binary + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_save_plan() { + echo $line2 + echo " Export JSON Terraform Plan..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_AMG_PATH + terraform show -json tfplan.binary > tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_security() { + echo $line2 + echo " Running Security Inspect Terraform..." + echo " \$ terraform show -json tfplan.binary > tfplan.json" + echo $line2 + cd $TF_AMG_PATH + # ================== # + # Terraform Addons # + # ================== # + # ~ Terrascan ~ + echo $line1 + echo " Using: terrascan ..." + echo " \$ terrascan init" + echo " \$ terrascan scan -o human" + echo $line1 + terrascan init + terrascan scan -o human + echo '' + sleep 1 + + # ~ Tfsec ~ + echo $line1 + echo " Using: tfsec ..." + echo " \$ tfsec ." + echo $line1 + tfsec . + echo '' + sleep 1 + + # ~ Checkov + echo $line1 + echo " Using: checkov ..." + echo " \$ checkov -f tfplan.json" + echo $line1 + tfsec . + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_cost_review() { + echo $line2 + echo " Cost Review Terraform..." + echo " \$ infracost breakdown --path tfplan.json" + echo $line2 + cd $TF_AMG_PATH + # ~ Infracost + infracost breakdown --path tfplan.json + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_AMG_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_AMG_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + cleanup_terraform + terraform_init + terraform_workspace + terraform_plan + terraform_save_plan + # terraform_security + terraform_cost_review + # terraform_apply + # terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/09.2-provisioning-resources-opensearch-apply.sh b/scripts/09.2-provisioning-resources-opensearch-apply.sh new file mode 100755 index 00000000..b80d5eda --- /dev/null +++ b/scripts/09.2-provisioning-resources-opensearch-apply.sh @@ -0,0 +1,71 @@ +# Provisioning Managed Services Grafana (AMG) + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_OPENSEARCH_PATH="$TF_RESOURCES_PATH/opensearch" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_OPENSEARCH_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_apply() { + echo $line2 + echo " Apply Terraform..." + echo " \$ terraform apply -auto-approve" + echo $line2 + cd $TF_OPENSEARCH_PATH + # ======================== # + # Terraform Provisioning # + # ======================== # + terraform apply -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_apply + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/93-destroy-resources-opensearch.sh b/scripts/93-destroy-resources-opensearch.sh new file mode 100755 index 00000000..d3a210fc --- /dev/null +++ b/scripts/93-destroy-resources-opensearch.sh @@ -0,0 +1,71 @@ +# Destroy OpenSearch + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_OPENSEARCH_PATH="$TF_RESOURCES_PATH/opensearch" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_OPENSEARCH_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_OPENSEARCH_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/94-destroy-resources-amg.sh b/scripts/94-destroy-resources-amg.sh new file mode 100755 index 00000000..071fe275 --- /dev/null +++ b/scripts/94-destroy-resources-amg.sh @@ -0,0 +1,71 @@ +# Destroy Managed Services Grafana (AMG) + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_AMG_PATH="$TF_RESOURCES_PATH/amg" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_AMG_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_AMG_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/95-destroy-resources-amp.sh b/scripts/95-destroy-resources-amp.sh new file mode 100755 index 00000000..8bace42a --- /dev/null +++ b/scripts/95-destroy-resources-amp.sh @@ -0,0 +1,71 @@ +# Destroy Managed Services Prometheus (AMP) + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_AMP_PATH="$TF_RESOURCES_PATH/amp" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_AMP_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_AMP_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/96-destroy-resources-eks.sh b/scripts/96-destroy-resources-eks.sh new file mode 100755 index 00000000..f134f101 --- /dev/null +++ b/scripts/96-destroy-resources-eks.sh @@ -0,0 +1,71 @@ +# Destroy Amazon EKS + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_EKS_PATH="$TF_RESOURCES_PATH/eks" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_EKS_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_EKS_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/97-destroy-infra-cicd.sh b/scripts/97-destroy-infra-cicd.sh new file mode 100755 index 00000000..66904f65 --- /dev/null +++ b/scripts/97-destroy-infra-cicd.sh @@ -0,0 +1,71 @@ +# Destroy Infra CI/CD + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" +export TF_CICD_PATH="$TF_RESOURCES_PATH/cicd" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_CICD_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_CICD_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/98-destroy-infra-core.sh b/scripts/98-destroy-infra-core.sh new file mode 100755 index 00000000..2eb17302 --- /dev/null +++ b/scripts/98-destroy-infra-core.sh @@ -0,0 +1,70 @@ +# Destroy Infra Core + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_CORE_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_CORE_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/99-destroy-tfstate.sh b/scripts/99-destroy-tfstate.sh new file mode 100755 index 00000000..41bbb5c1 --- /dev/null +++ b/scripts/99-destroy-tfstate.sh @@ -0,0 +1,70 @@ +# Destroy TFState + +#!/usr/bin/env sh + +set -e + +# Path xterm-256-color +export TERM="xterm-256color" + +# Partition Data +# export REPO_PATH="/data/repo/golang-adot" + +# Cloud9 +export REPO_PATH="$HOME/environment/golang-adot" +export TF_PATH="terraform" +export TF_MODULE_PATH="$REPO_PATH/$TF_PATH/modules" +export ALL_MODULES_PATH="$TF_MODULE_PATH/providers/aws" + +export TF_INFRA_PATH="$REPO_PATH/$TF_PATH/environment/providers/aws/infra" +export TF_CORE_PATH="$TF_INFRA_PATH/core" +export TF_RESOURCES_PATH="$TF_INFRA_PATH/resources" +export TF_STATE_PATH="$TF_INFRA_PATH/tfstate" + +export WORKSPACE_ENV="prod" + +line1="----------------------------------------------------------------------------------------------------" +line2="====================================================================================================" + +get_time() { + DATE=$(date '+%Y-%m-%d %H:%M:%S') +} + +terraform_workspace() { + echo $line2 + echo " Create / Select Terraform Workspace..." + echo " \$ terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV" + echo $line2 + cd $TF_STATE_PATH + terraform workspace select $WORKSPACE_ENV || terraform workspace new $WORKSPACE_ENV + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +terraform_destroy() { + echo $line2 + echo " Cleanup TFState..." + echo " \$ terraform destroy -auto-approve" + echo $line2 + cd $TF_STATE_PATH + # =================== # + # Terraform Destroy # + # =================== # + terraform destroy -auto-approve + echo '' + echo ' - DONE - ' + echo '' + sleep 1 +} + +main() { + terraform_workspace + terraform_destroy + echo '' + echo '-- ALL DONE --' +} + +### START HERE ### +main \ No newline at end of file diff --git a/scripts/config/.p10k.zsh b/scripts/config/.p10k.zsh new file mode 100644 index 00000000..f9ad8f51 --- /dev/null +++ b/scripts/config/.p10k.zsh @@ -0,0 +1,1761 @@ +# Generated by Powerlevel10k configuration wizard on 2023-03-07 at 23:23 WIB. +# Based on romkatv/powerlevel10k/config/p10k-rainbow.zsh, checksum 53641. +# Wizard options: nerdfont-complete + powerline, small icons, rainbow, unicode, +# 12h time, angled separators, sharp heads, flat tails, 2 lines, disconnected, +# full frame, lightest-ornaments, sparse, many icons, concise, instant_prompt=verbose. +# Type `p10k configure` to generate another config. +# +# Config for Powerlevel10k with powerline prompt style with colorful background. +# Type `p10k configure` to generate your own config based on it. +# +# Tip: Looking for a nice color? Here's a one-liner to print colormap. +# +# for i in {0..255}; do print -Pn "%K{$i} %k%F{$i}${(l:3::0:)i}%f " ${${(M)$((i%6)):#3}:+$'\n'}; done + +# Temporarily change options. +'builtin' 'local' '-a' 'p10k_config_opts' +[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' + +() { + emulate -L zsh -o extended_glob + + # Unset all configuration options. This allows you to apply configuration changes without + # restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`. + unset -m '(POWERLEVEL9K_*|DEFAULT_USER)~POWERLEVEL9K_GITSTATUS_DIR' + + # Zsh >= 5.1 is required. + [[ $ZSH_VERSION == (5.<1->*|<6->.*) ]] || return + + # The list of segments shown on the left. Fill it with the most important segments. + typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + os_icon # os identifier + dir # current directory + vcs # git status + # =========================[ Line #2 ]========================= + newline # \n + # prompt_char # prompt symbol + ) + + # The list of segments shown on the right. Fill it with less important segments. + # Right prompt on the last prompt line (where you are typing your commands) gets + # automatically hidden when the input line reaches it. Right prompt above the + # last prompt line gets hidden if it would overlap with left prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + status # exit code of the last command + command_execution_time # duration of the last command + background_jobs # presence of background jobs + direnv # direnv status (https://direnv.net/) + asdf # asdf version manager (https://github.com/asdf-vm/asdf) + virtualenv # python virtual environment (https://docs.python.org/3/library/venv.html) + anaconda # conda environment (https://conda.io/) + pyenv # python environment (https://github.com/pyenv/pyenv) + goenv # go environment (https://github.com/syndbg/goenv) + nodenv # node.js version from nodenv (https://github.com/nodenv/nodenv) + nvm # node.js version from nvm (https://github.com/nvm-sh/nvm) + nodeenv # node.js environment (https://github.com/ekalinin/nodeenv) + # node_version # node.js version + # go_version # go version (https://golang.org) + # rust_version # rustc version (https://www.rust-lang.org) + # dotnet_version # .NET version (https://dotnet.microsoft.com) + # php_version # php version (https://www.php.net/) + # laravel_version # laravel php framework version (https://laravel.com/) + # java_version # java version (https://www.java.com/) + # package # name@version from package.json (https://docs.npmjs.com/files/package.json) + rbenv # ruby version from rbenv (https://github.com/rbenv/rbenv) + rvm # ruby version from rvm (https://rvm.io) + fvm # flutter version management (https://github.com/leoafarias/fvm) + luaenv # lua version from luaenv (https://github.com/cehoffman/luaenv) + jenv # java version from jenv (https://github.com/jenv/jenv) + plenv # perl version from plenv (https://github.com/tokuhirom/plenv) + perlbrew # perl version from perlbrew (https://github.com/gugod/App-perlbrew) + phpenv # php version from phpenv (https://github.com/phpenv/phpenv) + scalaenv # scala version from scalaenv (https://github.com/scalaenv/scalaenv) + haskell_stack # haskell version from stack (https://haskellstack.org/) + kubecontext # current kubernetes context (https://kubernetes.io/) + terraform # terraform workspace (https://www.terraform.io) + # terraform_version # terraform version (https://www.terraform.io) + aws # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) + aws_eb_env # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) + azure # azure account name (https://docs.microsoft.com/en-us/cli/azure) + gcloud # google cloud cli account and project (https://cloud.google.com/) + google_app_cred # google application credentials (https://cloud.google.com/docs/authentication/production) + toolbox # toolbox name (https://github.com/containers/toolbox) + context # user@hostname + nordvpn # nordvpn connection status, linux only (https://nordvpn.com/) + ranger # ranger shell (https://github.com/ranger/ranger) + nnn # nnn shell (https://github.com/jarun/nnn) + lf # lf shell (https://github.com/gokcehan/lf) + xplr # xplr shell (https://github.com/sayanarijit/xplr) + vim_shell # vim shell indicator (:sh) + midnight_commander # midnight commander shell (https://midnight-commander.org/) + nix_shell # nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) + vi_mode # vi mode (you don't need this if you've enabled prompt_char) + # vpn_ip # virtual private network indicator + # load # CPU load + # disk_usage # disk usage + # ram # free RAM + # swap # used swap + todo # todo items (https://github.com/todotxt/todo.txt-cli) + timewarrior # timewarrior tracking status (https://timewarrior.net/) + taskwarrior # taskwarrior task count (https://taskwarrior.org/) + # cpu_arch # CPU architecture + time # current time + # =========================[ Line #2 ]========================= + newline + # ip # ip address and bandwidth usage for a specified network interface + # public_ip # public IP address + # proxy # system-wide http/https/ftp proxy + # battery # internal battery + # wifi # wifi speed + # example # example user-defined segment (see prompt_example function below) + ) + + # Defines character set used by powerlevel10k. It's best to let `p10k configure` set it for you. + typeset -g POWERLEVEL9K_MODE=nerdfont-complete + # When set to `moderate`, some icons will have an extra space after them. This is meant to avoid + # icon overlap when using non-monospace fonts. When set to `none`, spaces are not added. + typeset -g POWERLEVEL9K_ICON_PADDING=none + + # When set to true, icons appear before content on both sides of the prompt. When set + # to false, icons go after content. If empty or not set, icons go before content in the left + # prompt and after content in the right prompt. + # + # You can also override it for a specific segment: + # + # POWERLEVEL9K_STATUS_ICON_BEFORE_CONTENT=false + # + # Or for a specific segment in specific state: + # + # POWERLEVEL9K_DIR_NOT_WRITABLE_ICON_BEFORE_CONTENT=false + typeset -g POWERLEVEL9K_ICON_BEFORE_CONTENT= + + # Add an empty line before each prompt. + typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true + + # Connect left prompt lines with these symbols. You'll probably want to use the same color + # as POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND below. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX='%244F╭─' + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX='%244F├─' + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX='%244F╰─' + # Connect right prompt lines with these symbols. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX='%244F─╮' + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX='%244F─┤' + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX='%244F─╯' + + # Filler between left and right prompt on the first prompt line. You can set it to ' ', '·' or + # '─'. The last two make it easier to see the alignment between left and right prompt and to + # separate prompt from command output. You might want to set POWERLEVEL9K_PROMPT_ADD_NEWLINE=false + # for more compact prompt if using this option. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' ' + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_BACKGROUND= + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_GAP_BACKGROUND= + if [[ $POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR != ' ' ]]; then + # The color of the filler. You'll probably want to match the color of POWERLEVEL9K_MULTILINE + # ornaments defined above. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND=244 + # Start filler from the edge of the screen if there are no left segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_FIRST_SEGMENT_END_SYMBOL='%{%}' + # End filler on the edge of the screen if there are no right segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='%{%}' + fi + + # Separator between same-color segments on the left. + typeset -g POWERLEVEL9K_LEFT_SUBSEGMENT_SEPARATOR='\uE0B1' + # Separator between same-color segments on the right. + typeset -g POWERLEVEL9K_RIGHT_SUBSEGMENT_SEPARATOR='\uE0B3' + # Separator between different-color segments on the left. + typeset -g POWERLEVEL9K_LEFT_SEGMENT_SEPARATOR='\uE0B0' + # Separator between different-color segments on the right. + typeset -g POWERLEVEL9K_RIGHT_SEGMENT_SEPARATOR='\uE0B2' + # The right end of left prompt. + typeset -g POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL='\uE0B0' + # The left end of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='\uE0B2' + # The left end of left prompt. + typeset -g POWERLEVEL9K_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL='' + # The right end of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL='' + # Left prompt terminator for lines without any segments. + typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL= + + #################################[ os_icon: os identifier ]################################## + # OS identifier color. + typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND=232 + typeset -g POWERLEVEL9K_OS_ICON_BACKGROUND=7 + # Custom icon. + # typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='⭐' + + ################################[ prompt_char: prompt symbol ]################################ + # Transparent background. + typeset -g POWERLEVEL9K_PROMPT_CHAR_BACKGROUND= + # Green prompt symbol if the last command succeeded. + typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=76 + # Red prompt symbol if the last command failed. + typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=196 + # Default prompt symbol. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION='❯' + # Prompt symbol in command vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='❮' + # Prompt symbol in visual vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='V' + # Prompt symbol in overwrite vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION='▶' + typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true + # No line terminator if prompt_char is the last segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL= + # No line introducer if prompt_char is the first segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL= + # No surrounding whitespace. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_{LEFT,RIGHT}_WHITESPACE= + + ##################################[ dir: current directory ]################################## + # Current directory background color. + typeset -g POWERLEVEL9K_DIR_BACKGROUND=4 + # Default current directory foreground color. + typeset -g POWERLEVEL9K_DIR_FOREGROUND=254 + # If directory is too long, shorten some of its segments to the shortest possible unique + # prefix. The shortened directory can be tab-completed to the original. + typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique + # Replace removed segment suffixes with this symbol. + typeset -g POWERLEVEL9K_SHORTEN_DELIMITER= + # Color of the shortened directory segments. + typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND=250 + # Color of the anchor directory segments. Anchor segments are never shortened. The first + # segment is always an anchor. + typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=255 + # Display anchor directory segments in bold. + typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true + # Don't shorten directories that contain any of these files. They are anchors. + local anchor_files=( + .bzr + .citc + .git + .hg + .node-version + .python-version + .go-version + .ruby-version + .lua-version + .java-version + .perl-version + .php-version + .tool-version + .shorten_folder_marker + .svn + .terraform + CVS + Cargo.toml + composer.json + go.mod + package.json + stack.yaml + ) + typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})" + # If set to "first" ("last"), remove everything before the first (last) subdirectory that contains + # files matching $POWERLEVEL9K_SHORTEN_FOLDER_MARKER. For example, when the current directory is + # /foo/bar/git_repo/nested_git_repo/baz, prompt will display git_repo/nested_git_repo/baz (first) + # or nested_git_repo/baz (last). This assumes that git_repo and nested_git_repo contain markers + # and other directories don't. + # + # Optionally, "first" and "last" can be followed by ":" where is an integer. + # This moves the truncation point to the right (positive offset) or to the left (negative offset) + # relative to the marker. Plain "first" and "last" are equivalent to "first:0" and "last:0" + # respectively. + typeset -g POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER=false + # Don't shorten this many last directory segments. They are anchors. + typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1 + # Shorten directory if it's longer than this even if there is space for it. The value can + # be either absolute (e.g., '80') or a percentage of terminal width (e.g, '50%'). If empty, + # directory will be shortened only when prompt doesn't fit or when other parameters demand it + # (see POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS and POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT below). + # If set to `0`, directory will always be shortened to its minimum length. + typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least this + # many columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least + # COLUMNS * POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT * 0.01 columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50 + # If set to true, embed a hyperlink into the directory. Useful for quickly + # opening a directory in the file manager simply by clicking the link. + # Can also be handy when the directory is shortened, as it allows you to see + # the full directory that was used in previous commands. + typeset -g POWERLEVEL9K_DIR_HYPERLINK=false + + # Enable special styling for non-writable and non-existent directories. See POWERLEVEL9K_LOCK_ICON + # and POWERLEVEL9K_DIR_CLASSES below. + typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=v3 + + # The default icon shown next to non-writable and non-existent directories when + # POWERLEVEL9K_DIR_SHOW_WRITABLE is set to v3. + # typeset -g POWERLEVEL9K_LOCK_ICON='⭐' + + # POWERLEVEL9K_DIR_CLASSES allows you to specify custom icons and colors for different + # directories. It must be an array with 3 * N elements. Each triplet consists of: + # + # 1. A pattern against which the current directory ($PWD) is matched. Matching is done with + # extended_glob option enabled. + # 2. Directory class for the purpose of styling. + # 3. An empty string. + # + # Triplets are tried in order. The first triplet whose pattern matches $PWD wins. + # + # If POWERLEVEL9K_DIR_SHOW_WRITABLE is set to v3, non-writable and non-existent directories + # acquire class suffix _NOT_WRITABLE and NON_EXISTENT respectively. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_DIR_CLASSES=( + # '~/work(|/*)' WORK '' + # '~(|/*)' HOME '' + # '*' DEFAULT '') + # + # Whenever the current directory is ~/work or a subdirectory of ~/work, it gets styled with one + # of the following classes depending on its writability and existence: WORK, WORK_NOT_WRITABLE or + # WORK_NON_EXISTENT. + # + # Simply assigning classes to directories doesn't have any visible effects. It merely gives you an + # option to define custom colors and icons for different directory classes. + # + # # Styling for WORK. + # typeset -g POWERLEVEL9K_DIR_WORK_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_BACKGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=254 + # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=250 + # typeset -g POWERLEVEL9K_DIR_WORK_ANCHOR_FOREGROUND=255 + # + # # Styling for WORK_NOT_WRITABLE. + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_BACKGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND=254 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_SHORTENED_FOREGROUND=250 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_ANCHOR_FOREGROUND=255 + # + # # Styling for WORK_NON_EXISTENT. + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_BACKGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_FOREGROUND=254 + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_SHORTENED_FOREGROUND=250 + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_ANCHOR_FOREGROUND=255 + # + # If a styling parameter isn't explicitly defined for some class, it falls back to the classless + # parameter. For example, if POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND is not set, it falls + # back to POWERLEVEL9K_DIR_FOREGROUND. + # + # typeset -g POWERLEVEL9K_DIR_CLASSES=() + + # Custom prefix. + # typeset -g POWERLEVEL9K_DIR_PREFIX='in ' + + #####################################[ vcs: git status ]###################################### + # Version control background colors. + typeset -g POWERLEVEL9K_VCS_CLEAN_BACKGROUND=2 + typeset -g POWERLEVEL9K_VCS_MODIFIED_BACKGROUND=3 + typeset -g POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND=2 + typeset -g POWERLEVEL9K_VCS_CONFLICTED_BACKGROUND=3 + typeset -g POWERLEVEL9K_VCS_LOADING_BACKGROUND=8 + + # Branch icon. Set this parameter to '\UE0A0 ' for the popular Powerline branch icon. + typeset -g POWERLEVEL9K_VCS_BRANCH_ICON='\uF126 ' + + # Untracked files icon. It's really a question mark, your font isn't broken. + # Change the value of this parameter to show a different icon. + typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?' + + # Formatter for Git status. + # + # Example output: master wip ⇣42⇡42 *42 merge ~42 +42 !42 ?42. + # + # You can edit the function to customize how Git status looks. + # + # VCS_STATUS_* parameters are set by gitstatus plugin. See reference: + # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh. + function my_git_formatter() { + emulate -L zsh + + if [[ -n $P9K_CONTENT ]]; then + # If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from + # gitstatus plugin). VCS_STATUS_* parameters are not available in this case. + typeset -g my_git_format=$P9K_CONTENT + return + fi + + # Styling for different parts of Git status. + local meta='%7F' # white foreground + local clean='%0F' # black foreground + local modified='%0F' # black foreground + local untracked='%0F' # black foreground + local conflicted='%1F' # red foreground + + local res + + if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then + local branch=${(V)VCS_STATUS_LOCAL_BRANCH} + # If local branch name is at most 32 characters long, show it in full. + # Otherwise show the first 12 … the last 12. + # Tip: To always show local branch name in full without truncation, delete the next line. + (( $#branch > 32 )) && branch[13,-13]="…" # <-- this line + res+="${clean}${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}${branch//\%/%%}" + fi + + if [[ -n $VCS_STATUS_TAG + # Show tag only if not on a branch. + # Tip: To always show tag, delete the next line. + && -z $VCS_STATUS_LOCAL_BRANCH # <-- this line + ]]; then + local tag=${(V)VCS_STATUS_TAG} + # If tag name is at most 32 characters long, show it in full. + # Otherwise show the first 12 … the last 12. + # Tip: To always show tag name in full without truncation, delete the next line. + (( $#tag > 32 )) && tag[13,-13]="…" # <-- this line + res+="${meta}#${clean}${tag//\%/%%}" + fi + + # Display the current Git commit if there is no branch and no tag. + # Tip: To always display the current Git commit, delete the next line. + [[ -z $VCS_STATUS_LOCAL_BRANCH && -z $VCS_STATUS_TAG ]] && # <-- this line + res+="${meta}@${clean}${VCS_STATUS_COMMIT[1,8]}" + + # Show tracking branch name if it differs from local branch. + if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then + res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}" + fi + + # Display "wip" if the latest commit's summary contains "wip" or "WIP". + if [[ $VCS_STATUS_COMMIT_SUMMARY == (|*[^[:alnum:]])(wip|WIP)(|[^[:alnum:]]*) ]]; then + res+=" ${modified}wip" + fi + + # ⇣42 if behind the remote. + (( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}" + # ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42. + (( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" " + (( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}" + # ⇠42 if behind the push remote. + (( VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" ${clean}⇠${VCS_STATUS_PUSH_COMMITS_BEHIND}" + (( VCS_STATUS_PUSH_COMMITS_AHEAD && !VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" " + # ⇢42 if ahead of the push remote; no leading space if also behind: ⇠42⇢42. + (( VCS_STATUS_PUSH_COMMITS_AHEAD )) && res+="${clean}⇢${VCS_STATUS_PUSH_COMMITS_AHEAD}" + # *42 if have stashes. + (( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}" + # 'merge' if the repo is in an unusual state. + [[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}" + # ~42 if have merge conflicts. + (( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}" + # +42 if have staged changes. + (( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}" + # !42 if have unstaged changes. + (( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}" + # ?42 if have untracked files. It's really a question mark, your font isn't broken. + # See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon. + # Remove the next line if you don't want to see untracked files at all. + (( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}" + # "─" if the number of unstaged files is unknown. This can happen due to + # POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY (see below) being set to a non-negative number lower + # than the number of files in the Git index, or due to bash.showDirtyState being set to false + # in the repository config. The number of staged and untracked files may also be unknown + # in this case. + (( VCS_STATUS_HAS_UNSTAGED == -1 )) && res+=" ${modified}─" + + typeset -g my_git_format=$res + } + functions -M my_git_formatter 2>/dev/null + + # Don't count the number of unstaged, untracked and conflicted files in Git repositories with + # more than this many files in the index. Negative value means infinity. + # + # If you are working in Git repositories with tens of millions of files and seeing performance + # sagging, try setting POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY to a number lower than the output + # of `git ls-files | wc -l`. Alternatively, add `bash.showDirtyState = false` to the repository's + # config: `git config bash.showDirtyState false`. + typeset -g POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY=-1 + + # Don't show Git status in prompt for repositories whose workdir matches this pattern. + # For example, if set to '~', the Git repository at $HOME/.git will be ignored. + # Multiple patterns can be combined with '|': '~(|/foo)|/bar/baz/*'. + typeset -g POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN='~' + + # Disable the default Git status formatting. + typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true + # Install our own Git status formatter. + typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter()))+${my_git_format}}' + # Enable counters for staged, unstaged, etc. + typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1 + + # Custom icon. + # typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_VCS_PREFIX='on ' + + # Show status of repositories of these types. You can add svn and/or hg if you are + # using them. If you do, your prompt may become slow even when your current directory + # isn't in an svn or hg repository. + typeset -g POWERLEVEL9K_VCS_BACKENDS=(git) + + ##########################[ status: exit code of the last command ]########################### + # Enable OK_PIPE, ERROR_PIPE and ERROR_SIGNAL status states to allow us to enable, disable and + # style them independently from the regular OK and ERROR state. + typeset -g POWERLEVEL9K_STATUS_EXTENDED_STATES=true + + # Status on success. No content, just an icon. No need to show it if prompt_char is enabled as + # it will signify success by turning green. + typeset -g POWERLEVEL9K_STATUS_OK=true + typeset -g POWERLEVEL9K_STATUS_OK_VISUAL_IDENTIFIER_EXPANSION='✔' + typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND=2 + typeset -g POWERLEVEL9K_STATUS_OK_BACKGROUND=0 + + # Status when some part of a pipe command fails but the overall exit status is zero. It may look + # like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_OK_PIPE=true + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_VISUAL_IDENTIFIER_EXPANSION='✔' + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND=2 + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_BACKGROUND=0 + + # Status when it's just an error code (e.g., '1'). No need to show it if prompt_char is enabled as + # it will signify error by turning red. + typeset -g POWERLEVEL9K_STATUS_ERROR=true + typeset -g POWERLEVEL9K_STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION='✘' + typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND=3 + typeset -g POWERLEVEL9K_STATUS_ERROR_BACKGROUND=1 + + # Status when the last command was terminated by a signal. + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL=true + # Use terse signal names: "INT" instead of "SIGINT(2)". + typeset -g POWERLEVEL9K_STATUS_VERBOSE_SIGNAME=false + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION='✘' + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND=3 + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_BACKGROUND=1 + + # Status when some part of a pipe command fails and the overall exit status is also non-zero. + # It may look like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE=true + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION='✘' + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND=3 + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_BACKGROUND=1 + + ###################[ command_execution_time: duration of the last command ]################### + # Execution time color. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=0 + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_BACKGROUND=3 + # Show duration of the last command if takes at least this many seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=3 + # Show this many fractional digits. Zero means round to seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=0 + # Duration format: 1d 2h 3m 4s. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s' + # Custom icon. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PREFIX='took ' + + #######################[ background_jobs: presence of background jobs ]####################### + # Background jobs color. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND=6 + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_BACKGROUND=0 + # Don't show the number of background jobs. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE=false + # Custom icon. + # typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ direnv: direnv status (https://direnv.net/) ]######################## + # Direnv color. + typeset -g POWERLEVEL9K_DIRENV_FOREGROUND=3 + typeset -g POWERLEVEL9K_DIRENV_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_DIRENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ asdf: asdf version manager (https://github.com/asdf-vm/asdf) ]############### + # Default asdf color. Only used to display tools for which there is no color override (see below). + # Tip: Override these parameters for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_FOREGROUND and + # POWERLEVEL9K_ASDF_${TOOL}_BACKGROUND. + typeset -g POWERLEVEL9K_ASDF_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_BACKGROUND=7 + + # There are four parameters that can be used to hide asdf tools. Each parameter describes + # conditions under which a tool gets hidden. Parameters can hide tools but not unhide them. If at + # least one parameter decides to hide a tool, that tool gets hidden. If no parameter decides to + # hide a tool, it gets shown. + # + # Special note on the difference between POWERLEVEL9K_ASDF_SOURCES and + # POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW. Consider the effect of the following commands: + # + # asdf local python 3.8.1 + # asdf global python 3.8.1 + # + # After running both commands the current python version is 3.8.1 and its source is "local" as + # it takes precedence over "global". If POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW is set to false, + # it'll hide python version in this case because 3.8.1 is the same as the global version. + # POWERLEVEL9K_ASDF_SOURCES will hide python version only if the value of this parameter doesn't + # contain "local". + + # Hide tool versions that don't come from one of these sources. + # + # Available sources: + # + # - shell `asdf current` says "set by ASDF_${TOOL}_VERSION environment variable" + # - local `asdf current` says "set by /some/not/home/directory/file" + # - global `asdf current` says "set by /home/username/file" + # + # Note: If this parameter is set to (shell local global), it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SOURCES. + typeset -g POWERLEVEL9K_ASDF_SOURCES=(shell local global) + + # If set to false, hide tool versions that are the same as global. + # + # Note: The name of this parameter doesn't reflect its meaning at all. + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_PROMPT_ALWAYS_SHOW. + typeset -g POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW=false + + # If set to false, hide tool versions that are equal to "system". + # + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_SYSTEM. + typeset -g POWERLEVEL9K_ASDF_SHOW_SYSTEM=true + + # If set to non-empty value, hide tools unless there is a file matching the specified file pattern + # in the current directory, or its parent directory, or its grandparent directory, and so on. + # + # Note: If this parameter is set to empty value, it won't hide tools. + # Note: SHOW_ON_UPGLOB isn't specific to asdf. It works with all prompt segments. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_ON_UPGLOB. + # + # Example: Hide nodejs version when there is no package.json and no *.js files in the current + # directory, in `..`, in `../..` and so on. + # + # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.js|package.json' + typeset -g POWERLEVEL9K_ASDF_SHOW_ON_UPGLOB= + + # Ruby version from asdf. + typeset -g POWERLEVEL9K_ASDF_RUBY_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_RUBY_BACKGROUND=1 + # typeset -g POWERLEVEL9K_ASDF_RUBY_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUBY_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Python version from asdf. + typeset -g POWERLEVEL9K_ASDF_PYTHON_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_PYTHON_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_PYTHON_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PYTHON_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Go version from asdf. + typeset -g POWERLEVEL9K_ASDF_GOLANG_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_GOLANG_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_GOLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_GOLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Node.js version from asdf. + typeset -g POWERLEVEL9K_ASDF_NODEJS_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_NODEJS_BACKGROUND=2 + # typeset -g POWERLEVEL9K_ASDF_NODEJS_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Rust version from asdf. + typeset -g POWERLEVEL9K_ASDF_RUST_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_RUST_BACKGROUND=208 + # typeset -g POWERLEVEL9K_ASDF_RUST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUST_SHOW_ON_UPGLOB='*.foo|*.bar' + + # .NET Core version from asdf. + typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_BACKGROUND=5 + # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Flutter version from asdf. + typeset -g POWERLEVEL9K_ASDF_FLUTTER_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_FLUTTER_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Lua version from asdf. + typeset -g POWERLEVEL9K_ASDF_LUA_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_LUA_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_LUA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_LUA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Java version from asdf. + typeset -g POWERLEVEL9K_ASDF_JAVA_FOREGROUND=1 + typeset -g POWERLEVEL9K_ASDF_JAVA_BACKGROUND=7 + # typeset -g POWERLEVEL9K_ASDF_JAVA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_JAVA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Perl version from asdf. + typeset -g POWERLEVEL9K_ASDF_PERL_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_PERL_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_PERL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PERL_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Erlang version from asdf. + typeset -g POWERLEVEL9K_ASDF_ERLANG_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_ERLANG_BACKGROUND=1 + # typeset -g POWERLEVEL9K_ASDF_ERLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ERLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Elixir version from asdf. + typeset -g POWERLEVEL9K_ASDF_ELIXIR_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_ELIXIR_BACKGROUND=5 + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Postgres version from asdf. + typeset -g POWERLEVEL9K_ASDF_POSTGRES_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_POSTGRES_BACKGROUND=6 + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_SHOW_ON_UPGLOB='*.foo|*.bar' + + # PHP version from asdf. + typeset -g POWERLEVEL9K_ASDF_PHP_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_PHP_BACKGROUND=5 + # typeset -g POWERLEVEL9K_ASDF_PHP_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PHP_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Haskell version from asdf. + typeset -g POWERLEVEL9K_ASDF_HASKELL_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_HASKELL_BACKGROUND=3 + # typeset -g POWERLEVEL9K_ASDF_HASKELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_HASKELL_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Julia version from asdf. + typeset -g POWERLEVEL9K_ASDF_JULIA_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_JULIA_BACKGROUND=2 + # typeset -g POWERLEVEL9K_ASDF_JULIA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_JULIA_SHOW_ON_UPGLOB='*.foo|*.bar' + + ##########[ nordvpn: nordvpn connection status, linux only (https://nordvpn.com/) ]########### + # NordVPN connection indicator color. + typeset -g POWERLEVEL9K_NORDVPN_FOREGROUND=7 + typeset -g POWERLEVEL9K_NORDVPN_BACKGROUND=4 + # Hide NordVPN connection indicator when not connected. + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_CONTENT_EXPANSION= + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_VISUAL_IDENTIFIER_EXPANSION= + # Custom icon. + # typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ ranger: ranger shell (https://github.com/ranger/ranger) ]################## + # Ranger shell color. + typeset -g POWERLEVEL9K_RANGER_FOREGROUND=3 + typeset -g POWERLEVEL9K_RANGER_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################[ nnn: nnn shell (https://github.com/jarun/nnn) ]####################### + # Nnn shell color. + typeset -g POWERLEVEL9K_NNN_FOREGROUND=0 + typeset -g POWERLEVEL9K_NNN_BACKGROUND=6 + # Custom icon. + # typeset -g POWERLEVEL9K_NNN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################[ lf: lf shell (https://github.com/gokcehan/lf) ]####################### + # lf shell color. + typeset -g POWERLEVEL9K_LF_FOREGROUND=0 + typeset -g POWERLEVEL9K_LF_BACKGROUND=6 + # Custom icon. + # typeset -g POWERLEVEL9K_LF_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################[ xplr: xplr shell (https://github.com/sayanarijit/xplr) ]################## + # xplr shell color. + typeset -g POWERLEVEL9K_XPLR_FOREGROUND=0 + typeset -g POWERLEVEL9K_XPLR_BACKGROUND=6 + # Custom icon. + # typeset -g POWERLEVEL9K_XPLR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########################[ vim_shell: vim shell indicator (:sh) ]########################### + # Vim shell indicator color. + typeset -g POWERLEVEL9K_VIM_SHELL_FOREGROUND=0 + typeset -g POWERLEVEL9K_VIM_SHELL_BACKGROUND=2 + # Custom icon. + # typeset -g POWERLEVEL9K_VIM_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######[ midnight_commander: midnight commander shell (https://midnight-commander.org/) ]###### + # Midnight Commander shell color. + typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_FOREGROUND=3 + typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ nix_shell: nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) ]## + # Nix shell color. + typeset -g POWERLEVEL9K_NIX_SHELL_FOREGROUND=0 + typeset -g POWERLEVEL9K_NIX_SHELL_BACKGROUND=4 + + # Tip: If you want to see just the icon without "pure" and "impure", uncomment the next line. + # typeset -g POWERLEVEL9K_NIX_SHELL_CONTENT_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_NIX_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ disk_usage: disk usage ]################################## + # Colors for different levels of disk usage. + typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_FOREGROUND=3 + typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_BACKGROUND=0 + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_FOREGROUND=0 + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_BACKGROUND=3 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_FOREGROUND=7 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_BACKGROUND=1 + # Thresholds for different levels of disk usage (percentage points). + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL=90 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL=95 + # If set to true, hide disk usage when below $POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL percent. + typeset -g POWERLEVEL9K_DISK_USAGE_ONLY_WARNING=false + # Custom icon. + # typeset -g POWERLEVEL9K_DISK_USAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ vi_mode: vi mode (you don't need this if you've enabled prompt_char) ]########### + # Foreground color. + typeset -g POWERLEVEL9K_VI_MODE_FOREGROUND=0 + # Text and color for normal (a.k.a. command) vi mode. + typeset -g POWERLEVEL9K_VI_COMMAND_MODE_STRING=NORMAL + typeset -g POWERLEVEL9K_VI_MODE_NORMAL_BACKGROUND=2 + # Text and color for visual vi mode. + typeset -g POWERLEVEL9K_VI_VISUAL_MODE_STRING=VISUAL + typeset -g POWERLEVEL9K_VI_MODE_VISUAL_BACKGROUND=4 + # Text and color for overtype (a.k.a. overwrite and replace) vi mode. + typeset -g POWERLEVEL9K_VI_OVERWRITE_MODE_STRING=OVERTYPE + typeset -g POWERLEVEL9K_VI_MODE_OVERWRITE_BACKGROUND=3 + # Text and color for insert vi mode. + typeset -g POWERLEVEL9K_VI_INSERT_MODE_STRING= + typeset -g POWERLEVEL9K_VI_MODE_INSERT_FOREGROUND=8 + + ######################################[ ram: free RAM ]####################################### + # RAM color. + typeset -g POWERLEVEL9K_RAM_FOREGROUND=0 + typeset -g POWERLEVEL9K_RAM_BACKGROUND=3 + # Custom icon. + # typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################################[ swap: used swap ]###################################### + # Swap color. + typeset -g POWERLEVEL9K_SWAP_FOREGROUND=0 + typeset -g POWERLEVEL9K_SWAP_BACKGROUND=3 + # Custom icon. + # typeset -g POWERLEVEL9K_SWAP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ load: CPU load ]###################################### + # Show average CPU load over this many last minutes. Valid values are 1, 5 and 15. + typeset -g POWERLEVEL9K_LOAD_WHICH=5 + # Load color when load is under 50%. + typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND=0 + typeset -g POWERLEVEL9K_LOAD_NORMAL_BACKGROUND=2 + # Load color when load is between 50% and 70%. + typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND=0 + typeset -g POWERLEVEL9K_LOAD_WARNING_BACKGROUND=3 + # Load color when load is over 70%. + typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND=0 + typeset -g POWERLEVEL9K_LOAD_CRITICAL_BACKGROUND=1 + # Custom icon. + # typeset -g POWERLEVEL9K_LOAD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ todo: todo items (https://github.com/todotxt/todo.txt-cli) ]################ + # Todo color. + typeset -g POWERLEVEL9K_TODO_FOREGROUND=0 + typeset -g POWERLEVEL9K_TODO_BACKGROUND=8 + # Hide todo when the total number of tasks is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_TOTAL=true + # Hide todo when the number of tasks after filtering is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_FILTERED=false + + # Todo format. The following parameters are available within the expansion. + # + # - P9K_TODO_TOTAL_TASK_COUNT The total number of tasks. + # - P9K_TODO_FILTERED_TASK_COUNT The number of tasks after filtering. + # + # These variables correspond to the last line of the output of `todo.sh -p ls`: + # + # TODO: 24 of 42 tasks shown + # + # Here 24 is P9K_TODO_FILTERED_TASK_COUNT and 42 is P9K_TODO_TOTAL_TASK_COUNT. + # + # typeset -g POWERLEVEL9K_TODO_CONTENT_EXPANSION='$P9K_TODO_FILTERED_TASK_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TODO_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ timewarrior: timewarrior tracking status (https://timewarrior.net/) ]############ + # Timewarrior color. + typeset -g POWERLEVEL9K_TIMEWARRIOR_FOREGROUND=255 + typeset -g POWERLEVEL9K_TIMEWARRIOR_BACKGROUND=8 + + # If the tracked task is longer than 24 characters, truncate and append "…". + # Tip: To always display tasks without truncation, delete the following parameter. + # Tip: To hide task names and display just the icon when time tracking is enabled, set the + # value of the following parameter to "". + typeset -g POWERLEVEL9K_TIMEWARRIOR_CONTENT_EXPANSION='${P9K_CONTENT:0:24}${${P9K_CONTENT:24}:+…}' + + # Custom icon. + # typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]############## + # Taskwarrior color. + typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=0 + typeset -g POWERLEVEL9K_TASKWARRIOR_BACKGROUND=6 + + # Taskwarrior segment format. The following parameters are available within the expansion. + # + # - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`. + # - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`. + # + # Zero values are represented as empty parameters. + # + # The default format: + # + # '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT' + # + # typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################################[ cpu_arch: CPU architecture ]################################ + # CPU architecture color. + typeset -g POWERLEVEL9K_CPU_ARCH_FOREGROUND=0 + typeset -g POWERLEVEL9K_CPU_ARCH_BACKGROUND=3 + + # Hide the segment when on a specific CPU architecture. + # typeset -g POWERLEVEL9K_CPU_ARCH_X86_64_CONTENT_EXPANSION= + # typeset -g POWERLEVEL9K_CPU_ARCH_X86_64_VISUAL_IDENTIFIER_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_CPU_ARCH_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ context: user@hostname ]################################## + # Context color when running with privileges. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=1 + typeset -g POWERLEVEL9K_CONTEXT_ROOT_BACKGROUND=0 + # Context color in SSH without privileges. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_FOREGROUND=3 + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_BACKGROUND=0 + # Default context color (no privileges, no SSH). + typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=3 + typeset -g POWERLEVEL9K_CONTEXT_BACKGROUND=0 + + # Context format when running with privileges: user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%n@%m' + # Context format when in SSH without privileges: user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_TEMPLATE='%n@%m' + # Default context format (no privileges, no SSH): user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m' + + # Don't show context unless running with privileges or in SSH. + # Tip: Remove the next line to always show context. + typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_CONTEXT_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_CONTEXT_PREFIX='with ' + + ###[ virtualenv: python virtual environment (https://docs.python.org/3/library/venv.html) ]### + # Python virtual environment color. + typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_VIRTUALENV_BACKGROUND=4 + # Don't show Python version next to the virtual environment name. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false + # If set to "false", won't show virtualenv if pyenv is already shown. + # If set to "if-different", won't show virtualenv if it's the same as pyenv. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV=false + # Separate environment name from Python version only with a space. + typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ anaconda: conda environment (https://conda.io/) ]###################### + # Anaconda environment color. + typeset -g POWERLEVEL9K_ANACONDA_FOREGROUND=0 + typeset -g POWERLEVEL9K_ANACONDA_BACKGROUND=4 + + # Anaconda segment format. The following parameters are available within the expansion. + # + # - CONDA_PREFIX Absolute path to the active Anaconda/Miniconda environment. + # - CONDA_DEFAULT_ENV Name of the active Anaconda/Miniconda environment. + # - CONDA_PROMPT_MODIFIER Configurable prompt modifier (see below). + # - P9K_ANACONDA_PYTHON_VERSION Current python version (python --version). + # + # CONDA_PROMPT_MODIFIER can be configured with the following command: + # + # conda config --set env_prompt '({default_env}) ' + # + # The last argument is a Python format string that can use the following variables: + # + # - prefix The same as CONDA_PREFIX. + # - default_env The same as CONDA_DEFAULT_ENV. + # - name The last segment of CONDA_PREFIX. + # - stacked_env Comma-separated list of names in the environment stack. The first element is + # always the same as default_env. + # + # Note: '({default_env}) ' is the default value of env_prompt. + # + # The default value of POWERLEVEL9K_ANACONDA_CONTENT_EXPANSION expands to $CONDA_PROMPT_MODIFIER + # without the surrounding parentheses, or to the last path component of CONDA_PREFIX if the former + # is empty. + typeset -g POWERLEVEL9K_ANACONDA_CONTENT_EXPANSION='${${${${CONDA_PROMPT_MODIFIER#\(}% }%\)}:-${CONDA_PREFIX:t}}' + + # Custom icon. + # typeset -g POWERLEVEL9K_ANACONDA_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ pyenv: python environment (https://github.com/pyenv/pyenv) ]################ + # Pyenv color. + typeset -g POWERLEVEL9K_PYENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_PYENV_BACKGROUND=4 + # Hide python version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PYENV_SOURCES=(shell local global) + # If set to false, hide python version if it's the same as global: + # $(pyenv version-name) == $(pyenv global). + typeset -g POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide python version if it's equal to "system". + typeset -g POWERLEVEL9K_PYENV_SHOW_SYSTEM=true + + # Pyenv segment format. The following parameters are available within the expansion. + # + # - P9K_CONTENT Current pyenv environment (pyenv version-name). + # - P9K_PYENV_PYTHON_VERSION Current python version (python --version). + # + # The default format has the following logic: + # + # 1. Display just "$P9K_CONTENT" if it's equal to "$P9K_PYENV_PYTHON_VERSION" or + # starts with "$P9K_PYENV_PYTHON_VERSION/". + # 2. Otherwise display "$P9K_CONTENT $P9K_PYENV_PYTHON_VERSION". + typeset -g POWERLEVEL9K_PYENV_CONTENT_EXPANSION='${P9K_CONTENT}${${P9K_CONTENT:#$P9K_PYENV_PYTHON_VERSION(|/*)}:+ $P9K_PYENV_PYTHON_VERSION}' + + # Custom icon. + # typeset -g POWERLEVEL9K_PYENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ goenv: go environment (https://github.com/syndbg/goenv) ]################ + # Goenv color. + typeset -g POWERLEVEL9K_GOENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_GOENV_BACKGROUND=4 + # Hide go version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_GOENV_SOURCES=(shell local global) + # If set to false, hide go version if it's the same as global: + # $(goenv version-name) == $(goenv global). + typeset -g POWERLEVEL9K_GOENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide go version if it's equal to "system". + typeset -g POWERLEVEL9K_GOENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_GOENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ nodenv: node.js version from nodenv (https://github.com/nodenv/nodenv) ]########## + # Nodenv color. + typeset -g POWERLEVEL9K_NODENV_FOREGROUND=2 + typeset -g POWERLEVEL9K_NODENV_BACKGROUND=0 + # Hide node version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_NODENV_SOURCES=(shell local global) + # If set to false, hide node version if it's the same as global: + # $(nodenv version-name) == $(nodenv global). + typeset -g POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide node version if it's equal to "system". + typeset -g POWERLEVEL9K_NODENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ nvm: node.js version from nvm (https://github.com/nvm-sh/nvm) ]############### + # Nvm color. + typeset -g POWERLEVEL9K_NVM_FOREGROUND=0 + typeset -g POWERLEVEL9K_NVM_BACKGROUND=5 + # Custom icon. + # typeset -g POWERLEVEL9K_NVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ nodeenv: node.js environment (https://github.com/ekalinin/nodeenv) ]############ + # Nodeenv color. + typeset -g POWERLEVEL9K_NODEENV_FOREGROUND=2 + typeset -g POWERLEVEL9K_NODEENV_BACKGROUND=0 + # Don't show Node version next to the environment name. + typeset -g POWERLEVEL9K_NODEENV_SHOW_NODE_VERSION=false + # Separate environment name from Node version only with a space. + typeset -g POWERLEVEL9K_NODEENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_NODEENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############################[ node_version: node.js version ]############################### + # Node version color. + typeset -g POWERLEVEL9K_NODE_VERSION_FOREGROUND=7 + typeset -g POWERLEVEL9K_NODE_VERSION_BACKGROUND=2 + # Show node version only when in a directory tree containing package.json. + typeset -g POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ go_version: go version (https://golang.org) ]######################## + # Go version color. + typeset -g POWERLEVEL9K_GO_VERSION_FOREGROUND=255 + typeset -g POWERLEVEL9K_GO_VERSION_BACKGROUND=2 + # Show go version only when in a go project subdirectory. + typeset -g POWERLEVEL9K_GO_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_GO_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ rust_version: rustc version (https://www.rust-lang.org) ]################## + # Rust version color. + typeset -g POWERLEVEL9K_RUST_VERSION_FOREGROUND=0 + typeset -g POWERLEVEL9K_RUST_VERSION_BACKGROUND=208 + # Show rust version only when in a rust project subdirectory. + typeset -g POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_RUST_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ dotnet_version: .NET version (https://dotnet.microsoft.com) ]################ + # .NET version color. + typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND=7 + typeset -g POWERLEVEL9K_DOTNET_VERSION_BACKGROUND=5 + # Show .NET version only when in a .NET project subdirectory. + typeset -g POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_DOTNET_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ php_version: php version (https://www.php.net/) ]###################### + # PHP version color. + typeset -g POWERLEVEL9K_PHP_VERSION_FOREGROUND=0 + typeset -g POWERLEVEL9K_PHP_VERSION_BACKGROUND=5 + # Show PHP version only when in a PHP project subdirectory. + typeset -g POWERLEVEL9K_PHP_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHP_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ laravel_version: laravel php framework version (https://laravel.com/) ]########### + # Laravel version color. + typeset -g POWERLEVEL9K_LARAVEL_VERSION_FOREGROUND=1 + typeset -g POWERLEVEL9K_LARAVEL_VERSION_BACKGROUND=7 + # Custom icon. + # typeset -g POWERLEVEL9K_LARAVEL_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ rbenv: ruby version from rbenv (https://github.com/rbenv/rbenv) ]############## + # Rbenv color. + typeset -g POWERLEVEL9K_RBENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_RBENV_BACKGROUND=1 + # Hide ruby version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_RBENV_SOURCES=(shell local global) + # If set to false, hide ruby version if it's the same as global: + # $(rbenv version-name) == $(rbenv global). + typeset -g POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide ruby version if it's equal to "system". + typeset -g POWERLEVEL9K_RBENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_RBENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ####################[ java_version: java version (https://www.java.com/) ]#################### + # Java version color. + typeset -g POWERLEVEL9K_JAVA_VERSION_FOREGROUND=1 + typeset -g POWERLEVEL9K_JAVA_VERSION_BACKGROUND=7 + # Show java version only when in a java project subdirectory. + typeset -g POWERLEVEL9K_JAVA_VERSION_PROJECT_ONLY=true + # Show brief version. + typeset -g POWERLEVEL9K_JAVA_VERSION_FULL=false + # Custom icon. + # typeset -g POWERLEVEL9K_JAVA_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###[ package: name@version from package.json (https://docs.npmjs.com/files/package.json) ]#### + # Package color. + typeset -g POWERLEVEL9K_PACKAGE_FOREGROUND=0 + typeset -g POWERLEVEL9K_PACKAGE_BACKGROUND=6 + + # Package format. The following parameters are available within the expansion. + # + # - P9K_PACKAGE_NAME The value of `name` field in package.json. + # - P9K_PACKAGE_VERSION The value of `version` field in package.json. + # + # typeset -g POWERLEVEL9K_PACKAGE_CONTENT_EXPANSION='${P9K_PACKAGE_NAME//\%/%%}@${P9K_PACKAGE_VERSION//\%/%%}' + + # Custom icon. + # typeset -g POWERLEVEL9K_PACKAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ rvm: ruby version from rvm (https://rvm.io) ]######################## + # Rvm color. + typeset -g POWERLEVEL9K_RVM_FOREGROUND=0 + typeset -g POWERLEVEL9K_RVM_BACKGROUND=240 + # Don't show @gemset at the end. + typeset -g POWERLEVEL9K_RVM_SHOW_GEMSET=false + # Don't show ruby- at the front. + typeset -g POWERLEVEL9K_RVM_SHOW_PREFIX=false + # Custom icon. + # typeset -g POWERLEVEL9K_RVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ fvm: flutter version management (https://github.com/leoafarias/fvm) ]############ + # Fvm color. + typeset -g POWERLEVEL9K_FVM_FOREGROUND=0 + typeset -g POWERLEVEL9K_FVM_BACKGROUND=4 + # Custom icon. + # typeset -g POWERLEVEL9K_FVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ luaenv: lua version from luaenv (https://github.com/cehoffman/luaenv) ]########### + # Lua color. + typeset -g POWERLEVEL9K_LUAENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_LUAENV_BACKGROUND=4 + # Hide lua version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_LUAENV_SOURCES=(shell local global) + # If set to false, hide lua version if it's the same as global: + # $(luaenv version-name) == $(luaenv global). + typeset -g POWERLEVEL9K_LUAENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide lua version if it's equal to "system". + typeset -g POWERLEVEL9K_LUAENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_LUAENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ jenv: java version from jenv (https://github.com/jenv/jenv) ]################ + # Java color. + typeset -g POWERLEVEL9K_JENV_FOREGROUND=1 + typeset -g POWERLEVEL9K_JENV_BACKGROUND=7 + # Hide java version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_JENV_SOURCES=(shell local global) + # If set to false, hide java version if it's the same as global: + # $(jenv version-name) == $(jenv global). + typeset -g POWERLEVEL9K_JENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide java version if it's equal to "system". + typeset -g POWERLEVEL9K_JENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_JENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ plenv: perl version from plenv (https://github.com/tokuhirom/plenv) ]############ + # Perl color. + typeset -g POWERLEVEL9K_PLENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_PLENV_BACKGROUND=4 + # Hide perl version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PLENV_SOURCES=(shell local global) + # If set to false, hide perl version if it's the same as global: + # $(plenv version-name) == $(plenv global). + typeset -g POWERLEVEL9K_PLENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide perl version if it's equal to "system". + typeset -g POWERLEVEL9K_PLENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PLENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ perlbrew: perl version from perlbrew (https://github.com/gugod/App-perlbrew) ]############ + # Perlbrew color. + typeset -g POWERLEVEL9K_PERLBREW_FOREGROUND=67 + # Show perlbrew version only when in a perl project subdirectory. + typeset -g POWERLEVEL9K_PERLBREW_PROJECT_ONLY=true + # Don't show "perl-" at the front. + typeset -g POWERLEVEL9K_PERLBREW_SHOW_PREFIX=false + # Custom icon. + # typeset -g POWERLEVEL9K_PERLBREW_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ phpenv: php version from phpenv (https://github.com/phpenv/phpenv) ]############ + # PHP color. + typeset -g POWERLEVEL9K_PHPENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_PHPENV_BACKGROUND=5 + # Hide php version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PHPENV_SOURCES=(shell local global) + # If set to false, hide php version if it's the same as global: + # $(phpenv version-name) == $(phpenv global). + typeset -g POWERLEVEL9K_PHPENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide PHP version if it's equal to "system". + typeset -g POWERLEVEL9K_PHPENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHPENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######[ scalaenv: scala version from scalaenv (https://github.com/scalaenv/scalaenv) ]####### + # Scala color. + typeset -g POWERLEVEL9K_SCALAENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_SCALAENV_BACKGROUND=1 + # Hide scala version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_SCALAENV_SOURCES=(shell local global) + # If set to false, hide scala version if it's the same as global: + # $(scalaenv version-name) == $(scalaenv global). + typeset -g POWERLEVEL9K_SCALAENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide scala version if it's equal to "system". + typeset -g POWERLEVEL9K_SCALAENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_SCALAENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ haskell_stack: haskell version from stack (https://haskellstack.org/) ]########### + # Haskell color. + typeset -g POWERLEVEL9K_HASKELL_STACK_FOREGROUND=0 + typeset -g POWERLEVEL9K_HASKELL_STACK_BACKGROUND=3 + + # Hide haskell version if it doesn't come from one of these sources. + # + # shell: version is set by STACK_YAML + # local: version is set by stack.yaml up the directory tree + # global: version is set by the implicit global project (~/.stack/global-project/stack.yaml) + typeset -g POWERLEVEL9K_HASKELL_STACK_SOURCES=(shell local) + # If set to false, hide haskell version if it's the same as in the implicit global project. + typeset -g POWERLEVEL9K_HASKELL_STACK_ALWAYS_SHOW=true + # Custom icon. + # typeset -g POWERLEVEL9K_HASKELL_STACK_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ terraform: terraform workspace (https://www.terraform.io) ]################# + # Don't show terraform workspace if it's literally "default". + typeset -g POWERLEVEL9K_TERRAFORM_SHOW_DEFAULT=false + # POWERLEVEL9K_TERRAFORM_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current terraform workspace gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_TERRAFORM_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_TERRAFORM_CLASSES defines the workspace class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' OTHER) + # + # If your current terraform workspace is "project_test", its class is TEST because "project_test" + # doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_FOREGROUND=2 + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_BACKGROUND=0 + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' OTHER) + typeset -g POWERLEVEL9K_TERRAFORM_OTHER_FOREGROUND=4 + typeset -g POWERLEVEL9K_TERRAFORM_OTHER_BACKGROUND=0 + # typeset -g POWERLEVEL9K_TERRAFORM_OTHER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ terraform_version: terraform version (https://www.terraform.io) ]############## + # Terraform version color. + typeset -g POWERLEVEL9K_TERRAFORM_VERSION_FOREGROUND=4 + typeset -g POWERLEVEL9K_TERRAFORM_VERSION_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_TERRAFORM_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ terraform_version: It shows active terraform version (https://www.terraform.io) ]################# + typeset -g POWERLEVEL9K_TERRAFORM_VERSION_SHOW_ON_COMMAND='terraform|tf' + + #############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]############# + # Show kubecontext only when the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show kubecontext. + typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito|k9s|helmfile|flux|fluxctl|stern|kubeseal|skaffold|kubent|kubecolor' + + # Kubernetes context classes for the purpose of using different colors, icons and expansions with + # different contexts. + # + # POWERLEVEL9K_KUBECONTEXT_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current kubernetes context gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_KUBECONTEXT_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_KUBECONTEXT_CLASSES defines the context class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current kubernetes context is "deathray-testing/default", its class is TEST + # because "deathray-testing/default" doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=0 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_BACKGROUND=2 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_FOREGROUND=7 + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_BACKGROUND=5 + # typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext + # segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # Within the expansion the following parameters are always available: + # + # - P9K_CONTENT The content that would've been displayed if there was no content + # expansion defined. + # - P9K_KUBECONTEXT_NAME The current context's name. Corresponds to column NAME in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_CLUSTER The current context's cluster. Corresponds to column CLUSTER in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_NAMESPACE The current context's namespace. Corresponds to column NAMESPACE + # in the output of `kubectl config get-contexts`. If there is no + # namespace, the parameter is set to "default". + # - P9K_KUBECONTEXT_USER The current context's user. Corresponds to column AUTHINFO in the + # output of `kubectl config get-contexts`. + # + # If the context points to Google Kubernetes Engine (GKE) or Elastic Kubernetes Service (EKS), + # the following extra parameters are available: + # + # - P9K_KUBECONTEXT_CLOUD_NAME Either "gke" or "eks". + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT Account/project ID. + # - P9K_KUBECONTEXT_CLOUD_ZONE Availability zone. + # - P9K_KUBECONTEXT_CLOUD_CLUSTER Cluster. + # + # P9K_KUBECONTEXT_CLOUD_* parameters are derived from P9K_KUBECONTEXT_CLUSTER. For example, + # if P9K_KUBECONTEXT_CLUSTER is "gke_my-account_us-east1-a_my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=gke + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=my-account + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east1-a + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + # + # If P9K_KUBECONTEXT_CLUSTER is "arn:aws:eks:us-east-1:123456789012:cluster/my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=eks + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=123456789012 + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east-1 + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION= + # Show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back to P9K_KUBECONTEXT_NAME. + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}' + # Append the current context's namespace if it's not "default". + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}' + + # Custom prefix. + # typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX='at ' + + #[ aws: aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) ]# + # Show aws only when the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show aws. + typeset -g POWERLEVEL9K_AWS_SHOW_ON_COMMAND='aws|awless|terraform|pulumi|terragrunt' + + # POWERLEVEL9K_AWS_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current AWS profile gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_AWS_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_AWS_CLASSES defines the profile class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_AWS_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current AWS profile is "company_test", its class is TEST + # because "company_test" doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_AWS_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_AWS_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_AWS_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_AWS_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_AWS_DEFAULT_FOREGROUND=7 + typeset -g POWERLEVEL9K_AWS_DEFAULT_BACKGROUND=1 + # typeset -g POWERLEVEL9K_AWS_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # AWS segment format. The following parameters are available within the expansion. + # + # - P9K_AWS_PROFILE The name of the current AWS profile. + # - P9K_AWS_REGION The region associated with the current AWS profile. + typeset -g POWERLEVEL9K_AWS_CONTENT_EXPANSION='${P9K_AWS_PROFILE//\%/%%}${P9K_AWS_REGION:+ ${P9K_AWS_REGION//\%/%%}}' + + #[ aws_eb_env: aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) ]# + # AWS Elastic Beanstalk environment color. + typeset -g POWERLEVEL9K_AWS_EB_ENV_FOREGROUND=2 + typeset -g POWERLEVEL9K_AWS_EB_ENV_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ azure: azure account name (https://docs.microsoft.com/en-us/cli/azure) ]########## + # Show azure only when the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show azure. + typeset -g POWERLEVEL9K_AZURE_SHOW_ON_COMMAND='az|terraform|pulumi|terragrunt' + # Azure account name color. + typeset -g POWERLEVEL9K_AZURE_FOREGROUND=7 + typeset -g POWERLEVEL9K_AZURE_BACKGROUND=4 + # Custom icon. + # typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ gcloud: google cloud account and project (https://cloud.google.com/) ]########### + # Show gcloud only when the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show gcloud. + typeset -g POWERLEVEL9K_GCLOUD_SHOW_ON_COMMAND='gcloud|gcs|gsutil' + # Google cloud color. + typeset -g POWERLEVEL9K_GCLOUD_FOREGROUND=7 + typeset -g POWERLEVEL9K_GCLOUD_BACKGROUND=4 + + # Google cloud format. Change the value of POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION and/or + # POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION if the default is too verbose or not informative + # enough. You can use the following parameters in the expansions. Each of them corresponds to the + # output of `gcloud` tool. + # + # Parameter | Source + # -------------------------|-------------------------------------------------------------------- + # P9K_GCLOUD_CONFIGURATION | gcloud config configurations list --format='value(name)' + # P9K_GCLOUD_ACCOUNT | gcloud config get-value account + # P9K_GCLOUD_PROJECT_ID | gcloud config get-value project + # P9K_GCLOUD_PROJECT_NAME | gcloud projects describe $P9K_GCLOUD_PROJECT_ID --format='value(name)' + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurrences of '%' replaced with '%%'. + # + # Obtaining project name requires sending a request to Google servers. This can take a long time + # and even fail. When project name is unknown, P9K_GCLOUD_PROJECT_NAME is not set and gcloud + # prompt segment is in state PARTIAL. When project name gets known, P9K_GCLOUD_PROJECT_NAME gets + # set and gcloud prompt segment transitions to state COMPLETE. + # + # You can customize the format, icon and colors of gcloud segment separately for states PARTIAL + # and COMPLETE. You can also hide gcloud in state PARTIAL by setting + # POWERLEVEL9K_GCLOUD_PARTIAL_VISUAL_IDENTIFIER_EXPANSION and + # POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION to empty. + typeset -g POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_ID//\%/%%}' + typeset -g POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_NAME//\%/%%}' + + # Send a request to Google (by means of `gcloud projects describe ...`) to obtain project name + # this often. Negative value disables periodic polling. In this mode project name is retrieved + # only when the current configuration, account or project id changes. + typeset -g POWERLEVEL9K_GCLOUD_REFRESH_PROJECT_NAME_SECONDS=60 + + # Custom icon. + # typeset -g POWERLEVEL9K_GCLOUD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ google_app_cred: google application credentials (https://cloud.google.com/docs/authentication/production) ]# + # Show google_app_cred only when the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show google_app_cred. + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_SHOW_ON_COMMAND='terraform|pulumi|terragrunt' + + # Google application credentials classes for the purpose of using different colors, icons and + # expansions with different credentials. + # + # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES is an array with even number of elements. The first + # element in each pair defines a pattern against which the current kubernetes context gets + # matched. More specifically, it's P9K_CONTENT prior to the application of context expansion + # (see below) that gets matched. If you unset all POWERLEVEL9K_GOOGLE_APP_CRED_*CONTENT_EXPANSION + # parameters, you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES defines the context class. Patterns are tried in order. + # The first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=( + # '*:*prod*:*' PROD + # '*:*test*:*' TEST + # '*' DEFAULT) + # + # If your current Google application credentials is "service_account deathray-testing x@y.com", + # its class is TEST because it doesn't match the pattern '* *prod* *' but does match '* *test* *'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_CONTENT_EXPANSION='$P9K_GOOGLE_APP_CRED_PROJECT_ID' + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=( + # '*:*prod*:*' PROD # These values are examples that are unlikely + # '*:*test*:*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_FOREGROUND=7 + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_BACKGROUND=4 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_GOOGLE_APP_CRED_CONTENT_EXPANSION to specify the content displayed by + # google_app_cred segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # You can use the following parameters in the expansion. Each of them corresponds to one of the + # fields in the JSON file pointed to by GOOGLE_APPLICATION_CREDENTIALS. + # + # Parameter | JSON key file field + # ---------------------------------+--------------- + # P9K_GOOGLE_APP_CRED_TYPE | type + # P9K_GOOGLE_APP_CRED_PROJECT_ID | project_id + # P9K_GOOGLE_APP_CRED_CLIENT_EMAIL | client_email + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurrences of '%' replaced by '%%'. + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_CONTENT_EXPANSION='${P9K_GOOGLE_APP_CRED_PROJECT_ID//\%/%%}' + + ##############[ toolbox: toolbox name (https://github.com/containers/toolbox) ]############### + # Toolbox color. + typeset -g POWERLEVEL9K_TOOLBOX_FOREGROUND=0 + typeset -g POWERLEVEL9K_TOOLBOX_BACKGROUND=3 + # Don't display the name of the toolbox if it matches fedora-toolbox-*. + typeset -g POWERLEVEL9K_TOOLBOX_CONTENT_EXPANSION='${P9K_TOOLBOX_NAME:#fedora-toolbox-*}' + # Custom icon. + # typeset -g POWERLEVEL9K_TOOLBOX_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_TOOLBOX_PREFIX='in ' + + ###############################[ public_ip: public IP address ]############################### + # Public IP color. + typeset -g POWERLEVEL9K_PUBLIC_IP_FOREGROUND=7 + typeset -g POWERLEVEL9K_PUBLIC_IP_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_PUBLIC_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ########################[ vpn_ip: virtual private network indicator ]######################### + # VPN IP color. + typeset -g POWERLEVEL9K_VPN_IP_FOREGROUND=0 + typeset -g POWERLEVEL9K_VPN_IP_BACKGROUND=6 + # When on VPN, show just an icon without the IP address. + # Tip: To display the private IP address when on VPN, remove the next line. + typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= + # Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN + # to see the name of the interface. + typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(gpd|wg|(.*tun)|tailscale)[0-9]*|(zt.*)' + # If set to true, show one segment per matching network interface. If set to false, show only + # one segment corresponding to the first matching network interface. + # Tip: If you set it to true, you'll probably want to unset POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION. + typeset -g POWERLEVEL9K_VPN_IP_SHOW_ALL=false + # Custom icon. + # typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ ip: ip address and bandwidth usage for a specified network interface ]########### + # IP color. + typeset -g POWERLEVEL9K_IP_BACKGROUND=4 + typeset -g POWERLEVEL9K_IP_FOREGROUND=0 + # The following parameters are accessible within the expansion: + # + # Parameter | Meaning + # ----------------------+------------------------------------------- + # P9K_IP_IP | IP address + # P9K_IP_INTERFACE | network interface + # P9K_IP_RX_BYTES | total number of bytes received + # P9K_IP_TX_BYTES | total number of bytes sent + # P9K_IP_RX_BYTES_DELTA | number of bytes received since last prompt + # P9K_IP_TX_BYTES_DELTA | number of bytes sent since last prompt + # P9K_IP_RX_RATE | receive rate (since last prompt) + # P9K_IP_TX_RATE | send rate (since last prompt) + typeset -g POWERLEVEL9K_IP_CONTENT_EXPANSION='${P9K_IP_RX_RATE:+⇣$P9K_IP_RX_RATE }${P9K_IP_TX_RATE:+⇡$P9K_IP_TX_RATE }$P9K_IP_IP' + # Show information for the first network interface whose name matches this regular expression. + # Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces. + typeset -g POWERLEVEL9K_IP_INTERFACE='[ew].*' + # Custom icon. + # typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #########################[ proxy: system-wide http/https/ftp proxy ]########################## + # Proxy color. + typeset -g POWERLEVEL9K_PROXY_FOREGROUND=4 + typeset -g POWERLEVEL9K_PROXY_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_PROXY_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################################[ battery: internal battery ]################################# + # Show battery in red when it's below this level and not connected to power supply. + typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=20 + typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=1 + # Show battery in green when it's charging or fully charged. + typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND=2 + # Show battery in yellow when it's discharging. + typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND=3 + # Battery pictograms going from low to high level of charge. + typeset -g POWERLEVEL9K_BATTERY_STAGES='\uf58d\uf579\uf57a\uf57b\uf57c\uf57d\uf57e\uf57f\uf580\uf581\uf578' + # Don't show the remaining time to charge/discharge. + typeset -g POWERLEVEL9K_BATTERY_VERBOSE=false + typeset -g POWERLEVEL9K_BATTERY_BACKGROUND=0 + + #####################################[ wifi: wifi speed ]##################################### + # WiFi color. + typeset -g POWERLEVEL9K_WIFI_FOREGROUND=0 + typeset -g POWERLEVEL9K_WIFI_BACKGROUND=4 + # Custom icon. + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use different colors and icons depending on signal strength ($P9K_WIFI_BARS). + # + # # Wifi colors and icons for different signal strength levels (low to high). + # typeset -g my_wifi_fg=(0 0 0 0 0) # <-- change these values + # typeset -g my_wifi_icon=('WiFi' 'WiFi' 'WiFi' 'WiFi' 'WiFi') # <-- change these values + # + # typeset -g POWERLEVEL9K_WIFI_CONTENT_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}$P9K_WIFI_LAST_TX_RATE Mbps' + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}${my_wifi_icon[P9K_WIFI_BARS+1]}' + # + # The following parameters are accessible within the expansions: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_WIFI_SSID | service set identifier, a.k.a. network name + # P9K_WIFI_LINK_AUTH | authentication protocol such as "wpa2-psk" or "none"; empty if unknown + # P9K_WIFI_LAST_TX_RATE | wireless transmit rate in megabits per second + # P9K_WIFI_RSSI | signal strength in dBm, from -120 to 0 + # P9K_WIFI_NOISE | noise in dBm, from -120 to 0 + # P9K_WIFI_BARS | signal strength in bars, from 0 to 4 (derived from P9K_WIFI_RSSI and P9K_WIFI_NOISE) + + ####################################[ time: current time ]#################################### + # Current time color. + typeset -g POWERLEVEL9K_TIME_FOREGROUND=0 + typeset -g POWERLEVEL9K_TIME_BACKGROUND=7 + # Format for the current time: 09:51:02. See `man 3 strftime`. + typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%I:%M:%S %p}' + # If set to true, time will update when you hit enter. This way prompts for the past + # commands will contain the start times of their commands as opposed to the default + # behavior where they contain the end times of their preceding commands. + typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false + # Custom icon. + # typeset -g POWERLEVEL9K_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_TIME_PREFIX='at ' + + # Example of a user-defined prompt segment. Function prompt_example will be called on every + # prompt if `example` prompt segment is added to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or + # POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. It displays an icon and yellow text on red background + # greeting the user. + # + # Type `p10k help segment` for documentation and a more sophisticated example. + function prompt_example() { + p10k segment -b 1 -f 3 -i '⭐' -t 'hello, %n' + } + + # User-defined prompt segments may optionally provide an instant_prompt_* function. Its job + # is to generate the prompt segment for display in instant prompt. See + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # + # Powerlevel10k will call instant_prompt_* at the same time as the regular prompt_* function + # and will record all `p10k segment` calls it makes. When displaying instant prompt, Powerlevel10k + # will replay these calls without actually calling instant_prompt_*. It is imperative that + # instant_prompt_* always makes the same `p10k segment` calls regardless of environment. If this + # rule is not observed, the content of instant prompt will be incorrect. + # + # Usually, you should either not define instant_prompt_* or simply call prompt_* from it. If + # instant_prompt_* is not defined for a segment, the segment won't be shown in instant prompt. + function instant_prompt_example() { + # Since prompt_example always makes the same `p10k segment` calls, we can call it from + # instant_prompt_example. This will give us the same `example` prompt segment in the instant + # and regular prompts. + prompt_example + } + + # User-defined prompt segments can be customized the same way as built-in segments. + typeset -g POWERLEVEL9K_EXAMPLE_FOREGROUND=3 + typeset -g POWERLEVEL9K_EXAMPLE_BACKGROUND=1 + # typeset -g POWERLEVEL9K_EXAMPLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Transient prompt works similarly to the builtin transient_rprompt option. It trims down prompt + # when accepting a command line. Supported values: + # + # - off: Don't change prompt when accepting a command line. + # - always: Trim down prompt when accepting a command line. + # - same-dir: Trim down prompt when accepting a command line unless this is the first command + # typed after changing current working directory. + typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=off + + # Instant prompt mode. + # + # - off: Disable instant prompt. Choose this if you've tried instant prompt and found + # it incompatible with your zsh configuration files. + # - quiet: Enable instant prompt and don't print warnings when detecting console output + # during zsh initialization. Choose this if you've read and understood + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # - verbose: Enable instant prompt and print a warning when detecting console output during + # zsh initialization. Choose this if you've never tried instant prompt, haven't + # seen the warning, or if you are unsure what this all means. + typeset -g POWERLEVEL9K_INSTANT_PROMPT=verbose + + # Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized. + # For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload + # can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you + # really need it. + typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true + + # If p10k is already loaded, reload configuration. + # This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true. + (( ! $+functions[p10k] )) || p10k reload +} + +# Tell `p10k configure` which file it should overwrite. +typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a} + +(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} +'builtin' 'unset' 'p10k_config_opts' diff --git a/scripts/config/.tmux.conf b/scripts/config/.tmux.conf new file mode 100644 index 00000000..1d12ff39 --- /dev/null +++ b/scripts/config/.tmux.conf @@ -0,0 +1,86 @@ +# List of plugins +set -g @plugin 'tmux-plugins/tmux-sidebar' +set -g @plugin 'tmux-plugins/tpm' +set -g @plugin 'tmux-plugins/tmux-sensible' + +# Set colors +set -g default-terminal "screen-256color" +setw -g xterm-keys on + +#### COLOUR (Solarized 256) + +# Default statusbar colors +set-option -g status-bg colour235 #base02 +set-option -g status-fg colour136 #yellow +##set-option -g status-attr default +set-option -g status-style default + +# Default window title colors +#set-window-option -g window-status-fg colour244 #base0 +#set-window-option -g window-status-bg default +##set-window-option -g window-status-attr dim +set-window-option -g window-status-style fg=colour244,bg=default,dim + +# Active window title colors +#set-window-option -g window-status-current-fg colour166 #orange +#set-window-option -g window-status-current-bg default +##set-window-option -g window-status-current-attr bright +set-window-option -g window-status-style fg=colour166,bg=default,bright + + +# Pane border +#set-option -g pane-border-fg colour235 #base02 +#set-option -g pane-active-border-fg colour240 #base01 +set-option -g pane-border-style fg=colour235 +set-option -g pane-active-border-style fg=colour240 + +# Message text +#set-option -g message-bg colour235 #base02 +#set-option -g message-fg colour166 #orange +set-option -g message-style bg=colour235,fg=colour166 + +# Pane number display +set-option -g display-panes-active-colour colour33 #blue +set-option -g display-panes-colour colour166 #orange + +# Clock +set-window-option -g clock-mode-colour colour64 #green + +# Bell +set-window-option -g window-status-bell-style fg=colour235,bg=colour160 #base02, red + +# Center the window list +set -g status-justify centre + +bind O kill-pane -a + +if-shell "[ -f ~/.osx-paste-fix.conf ]" 'source ~/.osx-paste-fix.conf' + +set-option -g history-limit 4000 + +# this is set a the session level, not when you attach +set-option -g update-environment 'ITERM_PROFILE COLORFGBG' + +bind C new-session +# +# Fixing bug requring escape to be double pressed. https://github.com/tmux/tmux/issues/131 +set -g escape-time 10 + +# Smart pane switching with awareness of Vim splits. +# See: https://github.com/christoomey/vim-tmux-navigator + +bind -n C-k send-keys -R \; send-keys C-l \; clear-history + +is_vim="ps -o state= -o comm= -t '#{pane_tty}' \ + | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'" + bind-key -n C-h if-shell "$is_vim" "send-keys C-h" "select-pane -L" + bind-key -n C-j if-shell "$is_vim" "send-keys C-j" "select-pane -D" + bind-key -n C-k if-shell "$is_vim" "send-keys C-k" "select-pane -U" + bind-key -n C-l if-shell "$is_vim" "send-keys C-l" "select-pane -R" + bind-key -T copy-mode-vi C-h select-pane -L + bind-key -T copy-mode-vi C-j select-pane -D + bind-key -T copy-mode-vi C-k select-pane -U + bind-key -T copy-mode-vi C-l select-pane -R + +# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) +run '~/.tmux/plugins/tpm/tpm' diff --git a/scripts/config/.vimrc.local b/scripts/config/.vimrc.local new file mode 100644 index 00000000..a88f009e --- /dev/null +++ b/scripts/config/.vimrc.local @@ -0,0 +1,146 @@ +syntax enable + +set encoding=utf8 + +" ---------- FZF Configuration [Begin] ---------- + +" This is the default extra key bindings +let g:fzf_action = { + \ 'ctrl-t': 'tab split', + \ 'ctrl-x': 'split', + \ 'ctrl-v': 'vsplit' } + +" Default fzf layout +" - down / up / left / right +let g:fzf_layout = { 'down': '~40%' } + +" In Neovim, you can set up fzf window using a Vim command +let g:fzf_layout = { 'window': 'enew' } +let g:fzf_layout = { 'window': '-tabnew' } +let g:fzf_layout = { 'window': '10split enew' } + +" Customize fzf colors to match your color scheme +let g:fzf_colors = +\ { 'fg': ['fg', 'Normal'], + \ 'bg': ['bg', 'Normal'], + \ 'hl': ['fg', 'Comment'], + \ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'], + \ 'bg+': ['bg', 'CursorLine', 'CursorColumn'], + \ 'hl+': ['fg', 'Statement'], + \ 'info': ['fg', 'PreProc'], + \ 'border': ['fg', 'Ignore'], + \ 'prompt': ['fg', 'Conditional'], + \ 'pointer': ['fg', 'Exception'], + \ 'marker': ['fg', 'Keyword'], + \ 'spinner': ['fg', 'Label'], + \ 'header': ['fg', 'Comment'] } + +" Enable per-command history. +" CTRL-N and CTRL-P will be automatically bound to next-history and +" previous-history instead of down and up. If you don't like the change, +" explicitly bind the keys to down and up in your $FZF_DEFAULT_OPTS. +let g:fzf_history_dir = '~/.local/share/fzf-history' + +" [Buffers] Jump to the existing window if possible +let g:fzf_buffers_jump = 1 + +" [[B]Commits] Customize the options used by 'git log': +let g:fzf_commits_log_options = '--graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"' + +" [Tags] Command to generate tags file +let g:fzf_tags_command = 'ctags -R' + +" [Commands] --expect expression for directly executing the command +let g:fzf_commands_expect = 'alt-enter,ctrl-x' + +" Command for git grep +" - fzf#vim#grep(command, with_column, [options], [fullscreen]) +command! -bang -nargs=* GGrep + \ call fzf#vim#grep('git grep --line-number '.shellescape(), 0, 0) + +" Override Colors command. You can safely do this in your .vimrc as fzf.vim +" will not override existing commands. +command! -bang Colors + \ call fzf#vim#colors({'left': '15%', 'options': '--reverse --margin 30%,0'}, 0) + +" Augmenting Ag command using fzf#vim#with_preview function +" * fzf#vim#with_preview([[options], preview window, [toggle keys...]]) +" * For syntax-highlighting, Ruby and any of the following tools are required: +" - Highlight: http://www.andre-simon.de/doku/highlight/en/highlight.php +" - CodeRay: http://coderay.rubychan.de/ +" - Rouge: https://github.com/jneen/rouge +" +" :Ag - Start fzf with hidden preview window that can be enabled with "?" key +" :Ag! - Start fzf in fullscreen and display the preview window above +command! -bang -nargs=* Ag + \ call fzf#vim#ag(, + \ 0 ? fzf#vim#with_preview('up:60%') + \ : fzf#vim#with_preview('right:50%:hidden', '?'), + \ 0) + +" Similarly, we can apply it to fzf#vim#grep. To use ripgrep instead of ag: +command! -bang -nargs=* Rg + \ call fzf#vim#grep( + \ 'rg --column --line-number --no-heading --color=always '.shellescape(), 1, + \ 0 ? fzf#vim#with_preview('up:60%') + \ : fzf#vim#with_preview('right:50%:hidden', '?'), + \ 0) + +" Likewise, Files command with preview windowcommand! -bang -nargs=? -complete=dir Files + \ call fzf#vim#files(, fzf#vim#with_preview(), 0) + +" ---------- FZF Configuration [END] ---------- + +let g:rehash256 = 1 +let g:onedark_termcolors = 256 +let g:lessspace_whitelist = ['ruby', 'vim'] +let g:lessspace_blacklist = ['python'] + +"if has('gui_running') +" set background=light +"else +" set background=dark +"endif + +set background=dark + +"colorscheme solarized +"colorscheme molokai +"colorscheme ir_black +"colorscheme peaksea +"colorscheme base16-railscasts +"colorscheme railscasts +colorscheme darcula +"colorscheme dracula +"colorscheme onedark + +if has("gui_running") + if has("gui_gtk2") + set guifont=Monospace\ 9 + elseif has("gui_photon") + set guifont=Monospace:s9 + elseif has("gui_kde") + set guifont=Monospace/9/-1/5/50/0/0/0/1/0 + elseif has("x11") + set guifont=-*-r-normal-*-*-90-*-*-m-*-* + else + set guifont=Monospace:h9:cDEFAULT + endif +endif + +" With tmux (show fullpath filename) tab +" references: +" http://stackoverflow.com/questions/15123477/tmux-tabs-with-name-of-file-open-in-vim +" ----------------------------------------- +" autocmd BufReadPost,FileReadPost,BufNewFile * call system("tmux rename-window " . expand("%")) +autocmd BufEnter * call system("tmux rename-window " . expand("%:t")) +autocmd VimLeave * call system("tmux rename-window bash") +autocmd BufEnter * let &titlestring = ' ' . expand("%:t") +set title + +highlight ExtraWhitespace ctermbg=red guibg=red +match ExtraWhitespace /\s\+$/ +autocmd BufWinEnter * match ExtraWhitespace /\s\+$/ +autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@> $HOME/.bashrc &&\ + ln -sf $HOME/.tfenv/bin/* /usr/local/bin &&\ + mkdir -p $HOME/.local/bin/ &&\ + ln -sf $HOME/.tfenv/bin/* $HOME/.local/bin + +# =================== # +# Install Terraform # +# =================== # +/usr/local/bin/tfenv install ${TERRAFORM_VERSION} &&\ + /usr/local/bin/terraform use ${TERRAFORM_VERSION} &&\ + /usr/local/bin/terraform version + +# ============== # +# Install Helm # +# ============== # +curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 &&\ + chmod +x get_helm.sh &&\ + export VERIFY_CHECKSUM=${VERIFY_CHECKSUM} &&\ + ./get_helm.sh &&\ + helm version + +# ===================== # +# Install Helm Plugins # +# ===================== # +helm repo add stable https://charts.helm.sh/stable + +helm plugin install https://github.com/databus23/helm-diff &&\ + helm plugin install https://github.com/futuresimple/helm-secrets &&\ + helm plugin install https://github.com/hypnoglow/helm-s3.git &&\ + helm plugin install https://github.com/aslafy-z/helm-git.git &&\ + helm plugin install https://github.com/rimusz/helm-tiller &&\ + helm repo update + +# ================== # +# Install Helmfile # +# ================== # +sudo wget -O /usr/local/bin/helmfile \ + https://github.com/roboll/helmfile/releases/download/v${HELMFILE_VERSION}/helmfile_linux_amd64 &&\ + sudo chmod +x /usr/local/bin/helmfile &&\ + helmfile --version + +# ================= # +# Install Kubectl # +# ================= # +sudo wget -O /usr/local/bin/kubectl \ + https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl &&\ + sudo chmod +x /usr/local/bin/kubectl + +# ============= # +# Install K9S # +# ============= # +sudo wget -O /usr/local/bin/k9s \ + https://github.com/derailed/k9s/releases/download/v${K9S_VERSION}/k9s_Linux_amd64.tar.gz &&\ + sudo chmod +x /usr/local/bin/k9s + +# ====================== # +# Install Tmux Plugins # +# ====================== # +git clone https://github.com/tmux-plugins/tpm $HOME/.tmux/plugins/tpm +cp config/.tmux.conf $HOME +cp config/tmuxcolors.tmux $HOME + +# ============= # +# Install GVM # +# ============= # +sudo yum install go -y + +curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer | bash +gvm install go${GOLANG_VERSION}; sync +gvm use go${GOLANG_VERSION} --default; sync + +# ================ # +# Install Docker # +# ================ # +sudo amazon-linux-extras install docker + +# ======================= # +# Install Docker Buildx # +# ======================= # +curl --silent -L https://github.com/docker/buildx/releases/download/v${DOCKER_BUILDX_VERSION}/buildx-v${DOCKER_BUILDX_VERSION}.linux-amd64 -o buildx-v${DOCKER_BUILDX_VERSION}.linux-amd64 +chmod a+x buildx-v${DOCKER_BUILDX_VERSION}.linux-amd64 +mkdir -p $HOME/.docker/cli-plugins +mv buildx-v${DOCKER_BUILDX_VERSION}.linux-amd64 $HOME/.docker/cli-plugins/docker-buildx + +# ========================= # +# Install Docker-Compose # +# ========================= # +sudo curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m) -o ${DOCKER_COMPOSE_PATH} +sudo chmod +x /usr/bin/docker-compose + +touch $HOME/.zshrc +echo '' >> $HOME/.zshrc +echo '### Docker ### +export DOCKER_CLIENT_TIMEOUT=300 +export COMPOSE_HTTP_TIMEOUT=300' >> $HOME/.zshrc + +##### CONFIGURE DOCKER ##### +sudo usermod -a -G docker ec2-user + +# ======== # +# Others # +# ======== # +## Set Locale +sudo touch /etc/environment +sudo echo 'LANG=en_US.utf-8' >> /etc/environment +sudo echo 'LC_ALL=en_US.utf-8' >> /etc/environment + +## Adding Custom Sysctl +sudo echo 'vm.max_map_count=524288' >> /etc/sysctl.conf +sudo echo 'fs.file-max=131072' >> /etc/sysctl.conf + +# =================== # +# Install AWSCli v2 # +# =================== # +curl -s https://awscli.amazonaws.com/awscli-exe-linux-x86_64-${AWS_CLI_VERSION}.zip -o awscliv2.zip &&\ + unzip awscliv2.zip &&\ + ./aws/install --bin-dir /usr/local/bin/ + +# =================== # +# Install Oh-My-ZSH # +# =================== # +sudo yum install util-linux-user -y +sudo chsh -s $(which zsh) $(whoami) + +sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" + +# ========================= # +# Install Oh-My-ZSH Theme # +# ========================= # +git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k +cp config/.p10k.zsh $HOME diff --git a/scripts/eksctl-adot-collector.sh b/scripts/eksctl-adot-collector.sh new file mode 100755 index 00000000..134a84f4 --- /dev/null +++ b/scripts/eksctl-adot-collector.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +export AWS_REGION="us-west-2" +export ACCOUNT_ID="YOUR_AWS_ACCOUNT" +export EKS_CLUSTER="devopscorner-prod" +export EKS_VPC_ID="vpc-0987612345" + +kubectl config use-context arn:aws:eks:${AWS_REGION}:${ACCOUNT_ID}:cluster/${EKS_CLUSTER} + +kubectl apply -f https://amazon-eks.s3.amazonaws.com/docs/addons-otel-permissions.yaml + +aws eks create-addon --addon-name adot --cluster-name ${EKS_CLUSTER} +aws eks list-clusters --region ${AWS_REGION} +aws eks describe-addon --addon-name adot --cluster-name ${EKS_CLUSTER} + +eksctl create iamserviceaccount \ + --name adot-collector \ + --namespace observability \ + --cluster ${EKS_CLUSTER} \ + --attach-policy-arn arn:aws:iam::aws:policy/AmazonPrometheusRemoteWriteAccess \ + --attach-policy-arn arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess \ + --attach-policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy \ + --approve \ + --override-existing-serviceaccounts + +## Cleanup ### +eksctl delete iamserviceaccount \ + --name adot-collector \ + --namespace observability \ + --cluster ${EKS_CLUSTER} \ No newline at end of file diff --git a/scripts/fluentbit-template-latest.yaml b/scripts/fluentbit-template-latest.yaml new file mode 100644 index 00000000..1583ab22 --- /dev/null +++ b/scripts/fluentbit-template-latest.yaml @@ -0,0 +1,242 @@ + +--- +# Source: fluent-bit/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: fluent-bit + labels: + helm.sh/chart: fluent-bit-0.25.0 + app.kubernetes.io/name: fluent-bit + app.kubernetes.io/instance: fluent-bit + app.kubernetes.io/version: "2.0.10" + app.kubernetes.io/managed-by: Helm +--- +# Source: fluent-bit/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: fluent-bit + labels: + helm.sh/chart: fluent-bit-0.25.0 + app.kubernetes.io/name: fluent-bit + app.kubernetes.io/instance: fluent-bit + app.kubernetes.io/version: "2.0.10" + app.kubernetes.io/managed-by: Helm +data: + custom_parsers.conf: | + [PARSER] + Name docker_no_time + Format json + Time_Keep Off + Time_Key time + Time_Format %Y-%m-%dT%H:%M:%S.%L + + fluent-bit.conf: | + [SERVICE] + Daemon Off + Flush 1 + Log_Level info + Parsers_File parsers.conf + Parsers_File custom_parsers.conf + HTTP_Server On + HTTP_Listen 0.0.0.0 + HTTP_Port 2020 + Health_Check On + + [INPUT] + Name tail + Path /var/log/containers/*.log + multiline.parser docker, cri + Tag kube.* + Mem_Buf_Limit 5MB + Skip_Long_Lines On + + [INPUT] + Name systemd + Tag host.* + Systemd_Filter _SYSTEMD_UNIT=kubelet.service + Read_From_Tail On + + [FILTER] + Name kubernetes + Match kube.* + Merge_Log On + Keep_Log Off + K8S-Logging.Parser On + K8S-Logging.Exclude On + + [OUTPUT] + Name es + Match kube.* + Host elasticsearch-master + Logstash_Format On + Retry_Limit False + + [OUTPUT] + Name es + Match host.* + Host elasticsearch-master + Logstash_Format On + Logstash_Prefix node + Retry_Limit False +--- +# Source: fluent-bit/templates/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: fluent-bit + labels: + helm.sh/chart: fluent-bit-0.25.0 + app.kubernetes.io/name: fluent-bit + app.kubernetes.io/instance: fluent-bit + app.kubernetes.io/version: "2.0.10" + app.kubernetes.io/managed-by: Helm +rules: + - apiGroups: + - "" + resources: + - namespaces + - pods + verbs: + - get + - list + - watch +--- +# Source: fluent-bit/templates/clusterrolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: fluent-bit + labels: + helm.sh/chart: fluent-bit-0.25.0 + app.kubernetes.io/name: fluent-bit + app.kubernetes.io/instance: fluent-bit + app.kubernetes.io/version: "2.0.10" + app.kubernetes.io/managed-by: Helm +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: fluent-bit +subjects: + - kind: ServiceAccount + name: fluent-bit + namespace: observability +--- +# Source: fluent-bit/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: fluent-bit + labels: + helm.sh/chart: fluent-bit-0.25.0 + app.kubernetes.io/name: fluent-bit + app.kubernetes.io/instance: fluent-bit + app.kubernetes.io/version: "2.0.10" + app.kubernetes.io/managed-by: Helm +spec: + type: ClusterIP + ports: + - port: 2020 + targetPort: http + protocol: TCP + name: http + selector: + app.kubernetes.io/name: fluent-bit + app.kubernetes.io/instance: fluent-bit +--- +# Source: fluent-bit/templates/daemonset.yaml +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: fluent-bit + labels: + helm.sh/chart: fluent-bit-0.25.0 + app.kubernetes.io/name: fluent-bit + app.kubernetes.io/instance: fluent-bit + app.kubernetes.io/version: "2.0.10" + app.kubernetes.io/managed-by: Helm +spec: + selector: + matchLabels: + app.kubernetes.io/name: fluent-bit + app.kubernetes.io/instance: fluent-bit + template: + metadata: + annotations: + checksum/config: 87dc00bd75a056e84415ee734cdd8187878a8b02e26c6bca36b69cecd71a7290 + checksum/luascripts: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + labels: + app.kubernetes.io/name: fluent-bit + app.kubernetes.io/instance: fluent-bit + spec: + serviceAccountName: fluent-bit + hostNetwork: false + dnsPolicy: ClusterFirst + containers: + - name: fluent-bit + image: "cr.fluentbit.io/fluent/fluent-bit:2.0.10" + imagePullPolicy: Always + ports: + - name: http + containerPort: 2020 + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: /api/v1/health + port: http + volumeMounts: + - mountPath: /fluent-bit/etc/fluent-bit.conf + name: config + subPath: fluent-bit.conf + - mountPath: /fluent-bit/etc/custom_parsers.conf + name: config + subPath: custom_parsers.conf + - mountPath: /var/log + name: varlog + - mountPath: /var/lib/docker/containers + name: varlibdockercontainers + readOnly: true + - mountPath: /etc/machine-id + name: etcmachineid + readOnly: true + volumes: + - name: config + configMap: + name: fluent-bit + - hostPath: + path: /var/log + name: varlog + - hostPath: + path: /var/lib/docker/containers + name: varlibdockercontainers + - hostPath: + path: /etc/machine-id + type: File + name: etcmachineid +--- +# Source: fluent-bit/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "fluent-bit-test-connection" + labels: + helm.sh/chart: fluent-bit-0.25.0 + app.kubernetes.io/name: fluent-bit + app.kubernetes.io/instance: fluent-bit + app.kubernetes.io/version: "2.0.10" + app.kubernetes.io/managed-by: Helm + annotations: + "helm.sh/hook": test-success +spec: + containers: + - name: wget + image: "busybox:latest" + imagePullPolicy: Always + command: ['wget'] + args: ['fluent-bit:2020'] + restartPolicy: Never diff --git a/scripts/fluentbit-template.yaml b/scripts/fluentbit-template.yaml new file mode 100644 index 00000000..7b70e00a --- /dev/null +++ b/scripts/fluentbit-template.yaml @@ -0,0 +1,303 @@ +--- +# Source: fluent-bit/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: fluent-bit + labels: + helm.sh/chart: fluent-bit-0.25.0 + app.kubernetes.io/name: fluent-bit + app.kubernetes.io/instance: fluent-bit + app.kubernetes.io/version: "2.0.10" + app.kubernetes.io/managed-by: Helm +--- +# Source: fluent-bit/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: fluent-bit + labels: + helm.sh/chart: fluent-bit-0.25.0 + app.kubernetes.io/name: fluent-bit + app.kubernetes.io/instance: fluent-bit + app.kubernetes.io/version: "2.0.10" + app.kubernetes.io/managed-by: Helm +data: + custom_parsers.conf: | + [PARSER] + Name docker_no_time + Format json + Time_Keep Off + Time_Key time + Time_Format %Y-%m-%dT%H:%M:%S.%L + + fluent-bit.conf: | + [SERVICE] + Daemon Off + Flush 1 + Log_Level info + Parsers_File parsers.conf + Parsers_File custom_parsers.conf + HTTP_Server On + HTTP_Listen 0.0.0.0 + HTTP_Port 2020 + Health_Check On + + [INPUT] + Name tail + Tag kube.* + Path /var/log/containers/*.log + Parser docker + DB /var/log/flb_kube.db + Mem_Buf_Limit 50MB + Skip_Long_Lines On + Refresh_Interval 10 + + [INPUT] + Name tail + Path /var/log/containers/*.log + multiline.parser docker, cri + Tag kube.* + Mem_Buf_Limit 10MB + Skip_Long_Lines On + + [INPUT] + Name systemd + Tag host.* + Systemd_Filter _SYSTEMD_UNIT=kubelet.service + Read_From_Tail On + + [FILTER] + Name kubernetes + Match kube.* + Merge_Log On + Keep_Log Off + K8S-Logging.Parser On + K8S-Logging.Exclude On + + [OUTPUT] + Name es + Match kube.* + Host opensearch-cluster-master.observability.svc.cluster.local + Port 9200 + TLS Off + Logstash_Format On + Retry_Limit 6 + + [OUTPUT] + Name es + Match host.* + Host opensearch-cluster-master.observability.svc.cluster.local + Port 9200 + TLS Off + Logstash_Format On + Logstash_Prefix node + Retry_Limit 6 + + parsers.conf: | + [PARSER] + Name apache + Format regex + Regex ^(?[^ ]*) [^ ]* (?[^ ]*) \[(?