├── .editorconfig ├── .envrc_default ├── .github ├── auto-merge.yml ├── dependabot.yml_ ├── stale.yml └── workflows │ ├── lint.yml │ └── push.yml ├── .gitignore ├── .mergify.yml ├── CODEOWNERS ├── LICENSE.md ├── README.md ├── VERSION ├── change.sh ├── charts ├── .terraform-version ├── 00-variable.tf.json ├── 00-variables.tf ├── 01-data.tf ├── 04-backend.tf ├── 05-providers.tf ├── 30-charts.tf └── modules │ ├── argo │ ├── main.tf │ ├── values │ │ ├── argo-cd.yaml │ │ ├── argo-events-webhook.yaml │ │ ├── argo-events.yaml │ │ ├── argo-gatekeeper.yaml │ │ ├── argo-rollouts.yaml │ │ └── argo.yaml │ └── variable.tf │ ├── ingress │ ├── main.tf │ ├── values │ │ ├── cert-manager-issuers.yml │ │ ├── cert-manager.yml │ │ ├── external-dns.yml │ │ ├── ingress-nginx.yml │ │ └── metrics-server.yml │ └── variables.tf │ ├── istio │ ├── main.tf │ ├── values │ │ ├── kiali-gatekeeper.yaml │ │ └── tracing-gatekeeper.yaml │ └── variable.tf │ ├── jenkins │ ├── jenkins-secret.tf │ ├── main.tf │ ├── values │ │ ├── env │ │ │ └── jenkins-env.groovy │ │ ├── jenkins.yaml │ │ └── secret │ │ │ ├── jenkins.txt │ │ │ └── secret.txt │ └── variable.tf │ ├── keycloak │ ├── main.tf │ ├── output.tf │ ├── values │ │ ├── keycloak.yaml │ │ └── realm │ │ │ └── demo.json │ └── variable.tf │ ├── logging │ └── loki │ │ ├── main.tf │ │ ├── values │ │ └── loki-stack.yaml │ │ └── variables.tf │ ├── monitoring │ ├── main.tf │ ├── outpit.tf │ ├── values │ │ ├── grafana.yaml │ │ ├── prometheus-adapter.yaml │ │ ├── prometheus-alert-rules.yaml │ │ └── prometheus-operator.yaml │ └── variables.tf │ ├── repository │ ├── main.tf │ ├── values │ │ ├── archiva.yaml │ │ ├── chartmuseum.yaml │ │ └── sonatype-nexus.yaml │ └── variable.tf │ ├── sonarqube │ ├── main.tf │ ├── values │ │ └── sonarqube.yaml │ └── variables.tf │ └── weave │ ├── main.tf │ ├── values │ ├── weave-scope-gatekeeper.yaml │ └── weave-scope.yaml │ └── variable.tf ├── eks-vpc ├── .terraform-version ├── 00-variables.tf ├── 01-data.tf ├── 03-locals.tf ├── 04-backend.tf ├── 05-providers.tf ├── 10-vpc.tf ├── 30-kubernetes.tf ├── 40-rds.tf ├── 99-output.tf └── modules │ ├── kubernetes │ ├── data.tf │ ├── irsa.tf │ ├── main.tf │ ├── output.tf │ ├── providers.tf │ ├── values │ │ ├── cluster-autoscaler.yaml │ │ └── k8s-spot-termination-handler.yaml │ └── variables.tf │ ├── rds │ ├── data.tf │ ├── main.tf │ └── variable.tf │ └── vpc │ ├── main.tf │ ├── output.tf │ └── variables.tf └── images └── image1.png /.editorconfig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyand-dev-team/terraform-eks-env-workshop/f7b338d4ca5a44f5d5067b05e28041fdfa4efcda/.editorconfig -------------------------------------------------------------------------------- /.envrc_default: -------------------------------------------------------------------------------- 1 | export AWS_CONFIG_FILE= 2 | export AWS_SHARED_CREDENTIALS_FILE= 3 | export KUBECONFIG=$(pwd)/eks-vpc/kubeconfig_GOD-EKS -------------------------------------------------------------------------------- /.github/auto-merge.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-auto-merge - https://github.com/bobvanderlinden/probot-auto-merge 2 | 3 | updateBranch: true 4 | deleteBranchAfterMerge: true 5 | reportStatus: true 6 | 7 | minApprovals: 8 | COLLABORATOR: 0 9 | maxRequestedChanges: 10 | NONE: 0 11 | blockingLabels: 12 | - blocked 13 | 14 | # Will merge whenever the above conditions are met, but also 15 | # the owner has approved or merge label was added. 16 | rules: 17 | - minApprovals: 18 | OWNER: 1 19 | - requiredLabels: 20 | - merge -------------------------------------------------------------------------------- /.github/dependabot.yml_: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: terraform 4 | directory: "/eks-vpc" 5 | schedule: 6 | interval: daily 7 | time: "04:00" 8 | open-pull-requests-limit: 10 9 | reviewers: 10 | - timurgaleev 11 | - package-ecosystem: terraform 12 | directory: "/charts" 13 | schedule: 14 | interval: daily 15 | time: "04:00" 16 | open-pull-requests-limit: 10 17 | reviewers: 18 | - timurgaleev 19 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: 6 | - "**" 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v2 15 | with: 16 | fetch-depth: 1 17 | 18 | - name: Setup Terraform 19 | uses: hashicorp/setup-terraform@v1 20 | with: 21 | terraform_version: 0.12.26 22 | 23 | - name: terraform fmt 24 | run: terraform fmt -check -recursive -diff 25 | 26 | # - name: 'module: terraform init' 27 | # run: terraform init -backend=false 28 | 29 | - name: Lint Code Base 30 | uses: docker://github/super-linter:v3.13.1 31 | env: 32 | VALIDATE_ALL_CODEBASE: false 33 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 34 | 35 | # - name: Rocket.Chat Notification 36 | # uses: RocketChat/Rocket.Chat.GitHub.Action.Notification@master 37 | # if: always() 38 | # with: 39 | # type: ${{ job.status }} 40 | # job_name: ':rocket: *Tests passed ${{ github.ref }}*' 41 | # # mention: 'here' 42 | # # mention_if: 'failure' 43 | # # channel: '#github' 44 | # commit: true 45 | # url: ${{ secrets.ROCKETCHAT_WEBHOOK }} 46 | # token: ${{ secrets.GITHUB_TOKEN}} 47 | -------------------------------------------------------------------------------- /.github/workflows/push.yml: -------------------------------------------------------------------------------- 1 | name: Build-Push 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v2 15 | with: 16 | fetch-depth: 1 17 | 18 | - name: Bump Version 19 | uses: timzu/act-build@master 20 | with: 21 | args: --version 22 | 23 | - name: Release 24 | uses: timzu/act-build@master 25 | with: 26 | args: --release 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | 30 | # - name: Rocket.Chat Notification 31 | # uses: RocketChat/Rocket.Chat.GitHub.Action.Notification@master 32 | # if: always() 33 | # with: 34 | # type: ${{ job.status }} 35 | # job_name: ':rocket: *Publish new release ${{ github.ref }}*' 36 | # mention: 'here' 37 | # mention_if: 'failure' 38 | # channel: '#github' 39 | # commit: true 40 | # url: ${{ secrets.ROCKETCHAT_WEBHOOK }} 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # .gitignore 2 | 3 | config-map-aws-auth_*.yaml 4 | kubeconfig_* 5 | .terraform 6 | local 7 | .idea 8 | 9 | # use other *.tfvars files for parametrization of config-modules 10 | terraform.tfvars 11 | *.tfstate* 12 | 13 | # direnv.net config 14 | .envrc 15 | 16 | # OS generated files # 17 | .DS_Store 18 | .DS_Store? 19 | ._* 20 | .Spotlight-V100 21 | .Trashes 22 | ehthumbs.db 23 | Thumbs.db -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | - name: automatic merge 3 | conditions: 4 | - base=master 5 | - "#approved-reviews-by>=1" 6 | # - "status-success=ci/circleci" 7 | actions: 8 | merge: 9 | method: merge 10 | # method: rebase 11 | # rebase_fallback: merge 12 | # strict: smart 13 | dismiss_reviews: {} 14 | delete_head_branch: {} -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @timurgaleev @Duneyr -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Timur Galeev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TERRAFORM-EKS-ENV-WORKSHOP 2 | 3 | [![GitHub Actions status](https://github.com/GOD-mbh/terraform-eks-env-workshop/workflows/Build-Push/badge.svg)](https://github.com/GOD-mbh/terraform-eks-env-workshop/actions) 4 | [![GitHub Releases](https://img.shields.io/github/release/GOD-mbh/terraform-eks-env-workshop.svg)](https://github.com/GOD-mbh/terraform-eks-env-workshop/releases) 5 | 6 | > :warning: The repository may be out of date. 7 | > We split the modules and migrated the repository to [god-aws-eks-env](https://github.com/GOD-mbh/god-aws-eks-env). Modules named as https://github.com/GOD-mbh/god-terraform-'name'/tree/main 8 | 9 | Terraform and helm charts to provide deployment of the full EKS cluster 10 | 11 |

12 | 13 |

14 | 15 | ## Prerequsite 16 | 17 | ```bash 18 | brew update 19 | brew install kubernetes-cli 20 | brew install python3 21 | easy_install pip 22 | pip install awscli — upgrade — user 23 | export PATH=~/.local/bin:$PATH 24 | brew install terraform 25 | brew install terragrunt 26 | brew install direnv 27 | brew install tfenv 28 | ``` 29 | 30 | ### Setup .envrc 31 | 32 | Setup your `KUBECONFIG` and aws credentials 33 | 34 | ```bash 35 | export AWS_CONFIG_FILE= 36 | export AWS_SHARED_CREDENTIALS_FILE= 37 | export KUBECONFIG=$(pwd)/eks-vpc/kubeconfig_GOD-EKS 38 | ``` 39 | 40 | ### Authorize users to access the cluster 41 | 42 | Initially, only the system that deployed the cluster will be able to access the cluster. To authorize other users for accessing the cluster, config needs to be modified by using the steps given below: 43 | 44 | * Modify file `eks-vpc/locals.tf`as: 45 | 46 | 47 | ```yaml 48 | 49 | locals { 50 | 51 | map_users = [ 52 | { 53 | userarn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:user/tgaleev" 54 | username = "tgaleev" 55 | groups = ["system:masters"] 56 | } 57 | ] 58 | 59 | map_roles = [] 60 | 61 | map_accounts = [] 62 | } 63 | ``` 64 | 65 | ## How to use this example 66 | 67 | Install EKS 68 | 69 | - `cd eks-vpc` 70 | - Run `terraform init` 71 | - Run `terraform plan` and review 72 | - Run `terraform apply` 73 | 74 | Install helm charts 75 | 76 | - `cd charts` 77 | - Run `terraform init` 78 | - Run `terraform plan` and review 79 | - Run `terraform apply` 80 | 81 | 82 | ## Structure 83 | This repository provides the minimal set of resources, which may be required for starting comfortably developing the process of new IaC project: 84 | 85 | main.tf - data from modules 86 | 87 | modules.tf - list of modules and their redefined values 88 | 89 | providers.tf - list of providers and their values 90 | 91 | variables.tf - variables used in modules. Customize it for your project data !!! 92 | 93 | variables.tf.json - list of versions for variables. Customize it for your project data !!! 94 | 95 | ## Work with cluster 96 | 97 | For destroy some module just remove it from modules.tf and run. 98 | 99 | `terraform plan -out plan && terraform apply plan` 100 | 101 | ## What resources via helm are created 102 | 103 | - external-dns 104 | - metrics-server 105 | - ingress-nginx 106 | - cert-manager 107 | - archiva 108 | - sonarqube 109 | - sonatype-nexus 110 | - argo 111 | - weave 112 | - loki 113 | - keycloack 114 | - monitoring (grafana) 115 | - jenkins 116 | 117 | ### Cleaning up 118 | 119 | You can destroy this cluster entirely by running: 120 | 121 | ```bash 122 | terraform plan -destroy 123 | terraform destroy --force 124 | ``` 125 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | v1.3.x -------------------------------------------------------------------------------- /change.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | OS_NAME="$(uname | awk '{print tolower($0)}')" 4 | 5 | # check vars 6 | export ACCOUNT_ID=$(aws sts get-caller-identity | jq .Account -r) 7 | export REGION="$(aws configure get region)" 8 | export BUCKET="terraform-env-${1:-${ACCOUNT_ID}}" 9 | 10 | export LOCK_TABLE="terraform-resource-env-lock" 11 | 12 | command -v tput > /dev/null && TPUT=true 13 | 14 | _echo() { 15 | if [ "${TPUT}" != "" ] && [ "$2" != "" ]; then 16 | echo -e "$(tput setaf $2)$1$(tput sgr0)" 17 | else 18 | echo -e "$1" 19 | fi 20 | } 21 | 22 | _result() { 23 | echo 24 | _echo "# $@" 4 25 | } 26 | 27 | _command() { 28 | echo 29 | _echo "$ $@" 3 30 | } 31 | 32 | _success() { 33 | echo 34 | _echo "+ $@" 2 35 | exit 0 36 | } 37 | 38 | _error() { 39 | echo 40 | _echo "- $@" 1 41 | exit 1 42 | } 43 | 44 | _replace() { 45 | if [ "${OS_NAME}" == "darwin" ]; then 46 | sed -i "" -e "$1" "$2" 47 | else 48 | sed -i -e "$1" "$2" 49 | fi 50 | } 51 | 52 | _find_replace() { 53 | if [ "${OS_NAME}" == "darwin" ]; then 54 | find . -name "$2" -exec sed -i "" -e "$1" {} \; 55 | else 56 | find . -name "$2" -exec sed -i -e "$1" {} \; 57 | fi 58 | } 59 | 60 | _main() { 61 | _result "ACCOUNT_ID = ${ACCOUNT_ID}" 62 | 63 | _result "REGION = ${REGION}" 64 | _result "BUCKET = ${BUCKET}" 65 | 66 | _result "DOMAIN = ${DOMAIN}" 67 | 68 | if [ "${DOMAIN}" == "" ]; then 69 | _error "DOMAIN is empty." 70 | fi 71 | 72 | # replace 73 | _find_replace "s/terraform-workshop-[[:alnum:]]*/${BUCKET}/g" "*.tf" 74 | 75 | _find_replace "s/godapp.de/${DOMAIN}/g" "*.tf" 76 | _find_replace "s/godapp.de/${DOMAIN}/g" "*.yaml" 77 | _find_replace "s/godapp.de/${DOMAIN}/g" "*.json" 78 | 79 | _find_replace "s/ADMIN_USERNAME/${ADMIN_USERNAME}/g" "*.tf" 80 | _find_replace "s/ADMIN_PASSWORD/${ADMIN_PASSWORD}/g" "*.tf" 81 | 82 | # create s3 bucket 83 | COUNT=$(aws s3 ls | grep ${BUCKET} | wc -l | xargs) 84 | if [ "x${COUNT}" == "x0" ]; then 85 | _command "aws s3 mb s3://${BUCKET}" 86 | aws s3 mb s3://${BUCKET} --region ${REGION} 87 | fi 88 | 89 | # create dynamodb table 90 | COUNT=$(aws dynamodb list-tables | jq -r .TableNames | grep ${LOCK_TABLE} | wc -l | xargs) 91 | if [ "x${COUNT}" == "x0" ]; then 92 | _command "aws dynamodb create-table --table-name ${LOCK_TABLE}" 93 | aws dynamodb create-table \ 94 | --table-name ${LOCK_TABLE} \ 95 | --attribute-definitions AttributeName=LockID,AttributeType=S \ 96 | --key-schema AttributeName=LockID,KeyType=HASH \ 97 | --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 \ 98 | --region ${REGION} | jq . 99 | fi 100 | 101 | } 102 | 103 | _main 104 | 105 | _success -------------------------------------------------------------------------------- /charts/.terraform-version: -------------------------------------------------------------------------------- 1 | 0.12.29 -------------------------------------------------------------------------------- /charts/00-variable.tf.json: -------------------------------------------------------------------------------- 1 | { 2 | "variable": { 3 | "bitnami_external_dns": { 4 | "default": "3.5.1", 5 | "description": "bitnami/external-dns" 6 | }, 7 | "codecentric_keycloak": { 8 | "default": "8.3.0", 9 | "description": "codecentric/keycloak" 10 | }, 11 | "gabibbo97_keycloak_gatekeeper": { 12 | "default": "3.3.1", 13 | "description": "gabibbo97/keycloak-gatekeeper" 14 | }, 15 | "jetstack_cert_manager": { 16 | "default": "1.1.0-alpha.1", 17 | "description": "jetstack/cert-manager" 18 | }, 19 | "oteemo_sonarqube": { 20 | "default": "6.8.0", 21 | "description": "oteemo/sonarqube" 22 | }, 23 | "oteemo_sonatype_nexus": { 24 | "default": "2.8.0", 25 | "description": "oteemo/sonatype-nexus" 26 | }, 27 | "stable_chartmuseum": { 28 | "default": "2.13.3", 29 | "description": "stable/chartmuseum" 30 | }, 31 | "stable_grafana": { 32 | "default": "5.5.5", 33 | "description": "stable/grafana" 34 | }, 35 | "stable_jenkins": { 36 | "default": "2.5.2", 37 | "description": "stable/jenkins" 38 | }, 39 | "stable_metrics_server": { 40 | "default": "2.11.2", 41 | "description": "stable/metrics-server" 42 | }, 43 | "stable_nginx_ingress": { 44 | "default": "1.41.2", 45 | "description": "stable/nginx-ingress" 46 | }, 47 | "stable_prometheus_adapter": { 48 | "default": "2.5.0", 49 | "description": "stable/prometheus-adapter" 50 | }, 51 | "stable_prometheus_operator": { 52 | "default": "9.3.1", 53 | "description": "stable/prometheus-operator" 54 | }, 55 | "argo_argo": { 56 | "default": "0.12.1", 57 | "description": "argo/argo" 58 | }, 59 | "argo_argo_cd": { 60 | "default": "2.9.5", 61 | "description": "argo/argo-cd" 62 | }, 63 | "argo_argo_events": { 64 | "default": "1.0.0", 65 | "description": "argo/argo-events" 66 | }, 67 | "argo_argo_rollouts": { 68 | "default": "0.3.8", 69 | "description": "argo/argo-rollouts" 70 | }, 71 | "stable_weave_scope": { 72 | "default": "1.1.10", 73 | "description": "stable/weave-scope" 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /charts/00-variables.tf: -------------------------------------------------------------------------------- 1 | variable "aws_region" { 2 | description = "Name the aws region (eu-central-1, us-central-1 and etc.)" 3 | default = "eu-central-1" 4 | } 5 | 6 | variable "cert_manager_email" { 7 | type = string 8 | description = "Email to cert-manager" 9 | default = "" 10 | } 11 | 12 | variable "domains" { 13 | type = string 14 | description = "domain name for ingress" 15 | default = "" 16 | } 17 | 18 | ######### Charts 19 | 20 | variable "jenkins_enabled" { 21 | default = false 22 | } 23 | 24 | variable "chartmuseum_enabled" { 25 | default = false 26 | } 27 | 28 | variable "archiva_enabled" { 29 | default = false 30 | } 31 | 32 | variable "nexus_enabled" { 33 | default = false 34 | } 35 | 36 | variable "sonarqube_enabled" { 37 | default = false 38 | } 39 | 40 | variable "kiali_gatekeeper_enabled" { 41 | default = false 42 | } 43 | 44 | variable "tracing_gatekeeper_enabled" { 45 | default = false 46 | } 47 | 48 | variable "argo_enabled" { 49 | default = false 50 | } -------------------------------------------------------------------------------- /charts/01-data.tf: -------------------------------------------------------------------------------- 1 | data "aws_region" "current" {} -------------------------------------------------------------------------------- /charts/04-backend.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.12" 3 | backend "s3" { 4 | bucket = "tfstate-demo-infra" 5 | key = "terraform/states/charts.tfstate" 6 | region = "eu-central-1" 7 | encrypt = true 8 | dynamodb_table = "tfstate_god_charts" 9 | } 10 | } -------------------------------------------------------------------------------- /charts/05-providers.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = var.aws_region 3 | version = "~>2.66" 4 | } 5 | 6 | provider "random" { 7 | version = "~> 2.1" 8 | } -------------------------------------------------------------------------------- /charts/30-charts.tf: -------------------------------------------------------------------------------- 1 | ### Eks-charts 2 | ##################################################### 3 | 4 | module "repository" { 5 | source = "./modules/repository" 6 | chartmuseum_count = var.chartmuseum_enabled 7 | nexus_count = var.nexus_enabled 8 | stable_chartmuseum_version = var.stable_chartmuseum 9 | archiva_version = var.archiva_enabled 10 | oteemo_sonatype_nexus_version = var.oteemo_sonatype_nexus 11 | } 12 | 13 | module "ingress" { 14 | source = "./modules/ingress" 15 | 16 | bitnami_external_dns_version = var.bitnami_external_dns 17 | stable_nginx_ingress_version = var.stable_nginx_ingress 18 | jetstack_cert_manager_version = var.jetstack_cert_manager 19 | stable_metrics_server_version = var.stable_metrics_server 20 | 21 | domain = var.domains 22 | cert_manager_email = var.cert_manager_email 23 | module_depends_on = [module.monitoring.prometheus-operator] 24 | } 25 | 26 | module "monitoring" { 27 | source = "./modules/monitoring" 28 | stable_grafana_version = var.stable_grafana 29 | stable_prometheus_adapter_version = var.stable_prometheus_adapter 30 | stable_prometheus_operator_version = var.stable_prometheus_operator 31 | } 32 | 33 | module "keycloak" { 34 | source = "./modules/keycloak" 35 | codecentric_keycloak_version = var.codecentric_keycloak 36 | module_depends_on = [module.monitoring.prometheus-operator] 37 | domains = var.domains 38 | } 39 | 40 | module "istio" { 41 | source = "./modules/istio" 42 | tracing_gatekeeper_count = var.tracing_gatekeeper_enabled 43 | kiali_gatekeeper_count = var.kiali_gatekeeper_enabled 44 | gabibbo97_keycloak_gatekeeper_version = var.gabibbo97_keycloak_gatekeeper 45 | module_depends_on = [module.keycloak.keycloak_realese] 46 | } 47 | 48 | module "weave" { 49 | source = "./modules/weave" 50 | gabibbo97_keycloak_gatekeeper_version = var.gabibbo97_keycloak_gatekeeper 51 | stable_weave_scope_version = var.stable_weave_scope 52 | module_depends_on = [module.keycloak.keycloak_realese] 53 | } 54 | 55 | module "jenkins" { 56 | source = "./modules/jenkins" 57 | jenkins_count = var.jenkins_enabled 58 | module_depends_on = [module.monitoring.prometheus-operator] 59 | jenkins_version = var.stable_jenkins 60 | domains = var.domains 61 | } 62 | 63 | module "sonarqube" { 64 | source = "./modules/sonarqube" 65 | sonarqube_count = var.sonarqube_enabled 66 | module_depends_on = [module.monitoring.prometheus-operator] 67 | sonarqube_version = var.oteemo_sonarqube 68 | } 69 | 70 | module "loki" { 71 | source = "./modules/logging/loki" 72 | module_depends_on = [module.monitoring.prometheus-operator] 73 | } 74 | 75 | module "argo" { 76 | source = "./modules/argo" 77 | module_depends_on = [module.monitoring.prometheus-operator, module.keycloak.keycloak_realese] 78 | argo_count = var.argo_enabled 79 | aws_region = data.aws_region.current.name 80 | argo_argo_version = var.argo_argo 81 | argo_argo_events_version = var.argo_argo_events 82 | gabibbo97_keycloak_gatekeeper_version = var.gabibbo97_keycloak_gatekeeper 83 | argo_argo_rollouts_version = var.argo_argo_rollouts 84 | argo_argo_cd_version = var.argo_argo_cd 85 | } -------------------------------------------------------------------------------- /charts/modules/argo/main.tf: -------------------------------------------------------------------------------- 1 | resource "helm_release" "argo" { 2 | count = var.argo_count ? 1 : 0 3 | repository = "https://argoproj.github.io/argo-helm" 4 | chart = "argo" 5 | version = var.argo_argo_version 6 | 7 | namespace = "argo" 8 | name = "argo" 9 | 10 | values = [ 11 | file("./modules/argo/values/argo.yaml") 12 | ] 13 | 14 | set { 15 | name = "server.ingress.enabled" 16 | value = var.argo_count ? false : true 17 | } 18 | 19 | set { 20 | name = "artifactRepository.s3.region" 21 | value = var.aws_region 22 | } 23 | 24 | create_namespace = true 25 | 26 | depends_on = [ 27 | var.module_depends_on 28 | ] 29 | } 30 | 31 | resource "helm_release" "argo-events" { 32 | count = var.argo_count ? 1 : 0 33 | repository = "https://argoproj.github.io/argo-helm" 34 | chart = "argo-events" 35 | version = var.argo_argo_events_version 36 | 37 | namespace = "argo-events" 38 | name = "argo-events" 39 | 40 | values = [ 41 | file("./modules/argo/values/argo-events.yaml") 42 | ] 43 | 44 | wait = false 45 | 46 | create_namespace = true 47 | } 48 | 49 | resource "helm_release" "argo-events-webhook" { 50 | count = var.argo_count ? 1 : 0 51 | 52 | repository = "https://charts.helm.sh/incubator" 53 | chart = "raw" 54 | 55 | namespace = "argo-events" 56 | name = "argo-events-webhook" 57 | 58 | values = [ 59 | file("./modules/argo/values/argo-webhook.yaml") 60 | ] 61 | 62 | wait = false 63 | 64 | create_namespace = true 65 | 66 | depends_on = [ 67 | helm_release.argo, 68 | helm_release.argo-events, 69 | ] 70 | } 71 | 72 | resource "helm_release" "argo-gatekeeper" { 73 | count = var.argo_count ? 1 : 0 74 | 75 | repository = "https://gabibbo97.github.io/charts/" 76 | chart = "keycloak-gatekeeper" 77 | version = var.gabibbo97_keycloak_gatekeeper_version 78 | 79 | namespace = "argo" 80 | name = "argo-gatekeeper" 81 | 82 | values = [ 83 | file("./modules/argo/values/argo-gatekeeper.yaml") 84 | ] 85 | 86 | wait = false 87 | 88 | create_namespace = true 89 | 90 | depends_on = [ 91 | helm_release.argo, 92 | var.module_depends_on 93 | ] 94 | } 95 | 96 | resource "kubernetes_cluster_role_binding" "admin-argo-default" { 97 | count = var.argo_count ? 1 : 0 98 | metadata { 99 | name = "admin:argo:default" 100 | } 101 | 102 | role_ref { 103 | api_group = "rbac.authorization.k8s.io" 104 | kind = "ClusterRole" 105 | name = "admin" 106 | } 107 | 108 | subject { 109 | kind = "ServiceAccount" 110 | namespace = "argo" 111 | name = "default" 112 | } 113 | 114 | depends_on = [ 115 | helm_release.argo, 116 | ] 117 | } 118 | 119 | resource "kubernetes_cluster_role_binding" "edit-default-default" { 120 | count = var.argo_count ? 1 : 0 121 | metadata { 122 | name = "edit:default:default" 123 | } 124 | 125 | role_ref { 126 | api_group = "rbac.authorization.k8s.io" 127 | kind = "ClusterRole" 128 | name = "edit" 129 | } 130 | 131 | subject { 132 | kind = "ServiceAccount" 133 | namespace = "default" 134 | name = "default" 135 | } 136 | } 137 | 138 | # argo-cd & argo-rollouts 139 | 140 | resource "helm_release" "argo-rollouts" { 141 | count = var.argo_count ? 1 : 0 142 | repository = "https://argoproj.github.io/argo-helm" 143 | chart = "argo-rollouts" 144 | version = var.argo_argo_rollouts_version 145 | 146 | namespace = "argo-rollouts" 147 | name = "argo-rollouts" 148 | 149 | values = [ 150 | file("./modules/argo/values/argo-rollouts.yaml") 151 | ] 152 | 153 | create_namespace = true 154 | } 155 | 156 | resource "helm_release" "argo-cd" { 157 | count = var.argo_count ? 1 : 0 158 | repository = "https://argoproj.github.io/argo-helm" 159 | chart = "argo-cd" 160 | version = var.argo_argo_cd_version 161 | 162 | namespace = "argo-cd" 163 | name = "argocd" 164 | 165 | values = [ 166 | file("./modules/argo/values/argo-cd.yaml") 167 | ] 168 | 169 | wait = false 170 | 171 | create_namespace = true 172 | 173 | depends_on = [ 174 | var.module_depends_on, 175 | helm_release.argo-rollouts, 176 | ] 177 | } 178 | 179 | -------------------------------------------------------------------------------- /charts/modules/argo/values/argo-cd.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: argocd 2 | 3 | installCRDs: true 4 | 5 | controller: 6 | metrics: 7 | enabled: true 8 | serviceMonitor: 9 | enabled: true 10 | additionalLabels: 11 | release: prometheus-operator 12 | podAnnotations: 13 | cluster-autoscaler.kubernetes.io/safe-to-evict: "false" 14 | 15 | server: 16 | extraArgs: 17 | - --insecure 18 | 19 | metrics: 20 | enabled: true 21 | serviceMonitor: 22 | enabled: true 23 | additionalLabels: 24 | release: prometheus-operator 25 | podAnnotations: 26 | cluster-autoscaler.kubernetes.io/safe-to-evict: "false" 27 | 28 | ingress: 29 | enabled: true 30 | annotations: 31 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 32 | kubernetes.io/ingress.class: nginx 33 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 34 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 35 | hosts: 36 | - "argocd.godapp.de" 37 | tls: 38 | - secretName: argocd-server-tls 39 | hosts: 40 | - "argocd.godapp.de" 41 | 42 | config: 43 | url: "https://argocd.godapp.de" 44 | 45 | repositories: | 46 | - name: stable 47 | type: helm 48 | url: https://charts.helm.sh/stable 49 | - name: argo 50 | type: helm 51 | url: https://argoproj.github.io/argo-helm 52 | 53 | oidc.config: | 54 | name: SSO 55 | clientID: 'argo-cd' 56 | clientSecret: 'd91fdbbc-5dbb-43ab-b388-ce4170ff79c6' 57 | issuer: 'https://keycloak.godapp.de/auth/realms/demo' 58 | requestedScopes: 59 | - openid 60 | - email 61 | - profile 62 | - groups 63 | 64 | # https://argoproj.github.io/argo-cd/operator-manual/user-management/keycloak/ 65 | 66 | rbacConfig: 67 | policy.default: role:readonly 68 | policy.csv: | 69 | g, "/admin", role:admin 70 | 71 | additionalProjects: [] 72 | -------------------------------------------------------------------------------- /charts/modules/argo/values/argo-events-webhook.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - apiVersion: argoproj.io/v1alpha1 3 | kind: EventSource 4 | metadata: 5 | name: webhook 6 | spec: 7 | service: 8 | ports: 9 | - port: 12000 10 | targetPort: 12000 11 | webhook: 12 | example: 13 | port: "12000" 14 | endpoint: /example 15 | method: POST 16 | 17 | - apiVersion: argoproj.io/v1alpha1 18 | kind: Sensor 19 | metadata: 20 | name: webhook 21 | spec: 22 | template: 23 | serviceAccountName: argo-events-sa 24 | dependencies: 25 | - name: test-dep 26 | eventSourceName: webhook 27 | eventName: example 28 | triggers: 29 | - template: 30 | name: webhook-workflow-trigger 31 | k8s: 32 | group: argoproj.io 33 | version: v1alpha1 34 | resource: workflows 35 | operation: create 36 | source: 37 | resource: 38 | apiVersion: argoproj.io/v1alpha1 39 | kind: Workflow 40 | metadata: 41 | generateName: webhook- 42 | spec: 43 | entrypoint: whalesay 44 | arguments: 45 | parameters: 46 | - name: message 47 | # the value will get overridden by event payload from test-dep 48 | value: hello world 49 | templates: 50 | - name: whalesay 51 | serviceAccountName: argo-events-sa 52 | inputs: 53 | parameters: 54 | - name: message 55 | container: 56 | image: docker/whalesay:latest 57 | command: [cowsay] 58 | args: ["{{inputs.parameters.message}}"] 59 | parameters: 60 | - src: 61 | dependencyName: test-dep 62 | dest: spec.arguments.parameters.0.value -------------------------------------------------------------------------------- /charts/modules/argo/values/argo-events.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: argo-events 2 | 3 | installCRD: true 4 | -------------------------------------------------------------------------------- /charts/modules/argo/values/argo-gatekeeper.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: argo-gatekeeper 2 | 3 | discoveryURL: https://keycloak.godapp.de/auth/realms/demo 4 | 5 | upstreamURL: http://argo-server.argo.svc.cluster.local:2746 6 | 7 | ClientID: argo 8 | ClientSecret: 60820e7d-80a1-4e63-9ae1-b83972eaa020 9 | 10 | ingress: 11 | enabled: true 12 | annotations: 13 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 14 | kubernetes.io/ingress.class: nginx 15 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 16 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 17 | hosts: 18 | - "argo.godapp.de" 19 | tls: 20 | - secretName: argo-gatekeeper-tls 21 | hosts: 22 | - "argo.godapp.de" 23 | -------------------------------------------------------------------------------- /charts/modules/argo/values/argo-rollouts.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: argo-rollouts 2 | 3 | installCRDs: true 4 | 5 | controller: 6 | 7 | -------------------------------------------------------------------------------- /charts/modules/argo/values/argo.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: argo 2 | 3 | installCRD: true 4 | 5 | init: 6 | serviceAccount: "" 7 | 8 | controller: 9 | podAnnotations: 10 | cluster-autoscaler.kubernetes.io/safe-to-evict: "false" 11 | iam.amazonaws.com/role: "eks-demo-worker-bucket" 12 | serviceMonitor: 13 | enabled: true 14 | additionalLabels: 15 | release: prometheus-operator 16 | workflowNamespaces: 17 | - default 18 | 19 | server: 20 | podAnnotations: 21 | cluster-autoscaler.kubernetes.io/safe-to-evict: "false" 22 | ingress: 23 | enabled: false 24 | annotations: 25 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 26 | kubernetes.io/ingress.class: nginx 27 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 28 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 29 | hosts: 30 | - "argo.godapp.de" 31 | tls: 32 | - secretName: argo-tls 33 | hosts: 34 | - "argo.godapp.de" 35 | 36 | useDefaultArtifactRepo: true 37 | useStaticCredentials: false 38 | 39 | artifactRepository: 40 | s3: 41 | bucket: "eks-demo-argo-demo" 42 | endpoint: s3.amazonaws.com 43 | -------------------------------------------------------------------------------- /charts/modules/argo/variable.tf: -------------------------------------------------------------------------------- 1 | variable "module_depends_on" { 2 | default = [] 3 | } 4 | 5 | variable "aws_region" { 6 | type = string 7 | description = "AWS Region" 8 | } 9 | 10 | variable "argo_argo_version" { 11 | type = string 12 | description = "Argo Version" 13 | } 14 | 15 | variable "argo_argo_events_version" { 16 | type = string 17 | description = "Argo Events Version" 18 | } 19 | 20 | variable "gabibbo97_keycloak_gatekeeper_version" { 21 | type = string 22 | description = "Keycloak Gatekeeper Version" 23 | } 24 | 25 | variable "argo_argo_rollouts_version" { 26 | type = string 27 | description = "Argo Rollouts Version" 28 | } 29 | 30 | variable "argo_argo_cd_version" { 31 | type = string 32 | description = "Argo CD Version" 33 | } 34 | 35 | variable "argo_count" { 36 | default = [] 37 | } -------------------------------------------------------------------------------- /charts/modules/ingress/main.tf: -------------------------------------------------------------------------------- 1 | resource "helm_release" "nginx-ingress" { 2 | repository = "https://charts.helm.sh/stable" 3 | chart = "nginx-ingress" 4 | version = var.stable_nginx_ingress_version 5 | 6 | namespace = "kube-ingress" 7 | name = "nginx-ingress" 8 | 9 | values = [ 10 | file("./modules/ingress/values/ingress-nginx.yml") 11 | ] 12 | 13 | wait = false 14 | 15 | create_namespace = true 16 | 17 | depends_on = [ 18 | var.module_depends_on 19 | ] 20 | } 21 | 22 | ### Cert manager 23 | 24 | resource "helm_release" "cert-manager-issuers" { 25 | repository = "https://charts.helm.sh/incubator" 26 | chart = "raw" 27 | 28 | namespace = "cert-manager" 29 | name = "cert-manager-issuers" 30 | 31 | values = [ 32 | file("./modules/ingress/values/cert-manager-issuers.yml") 33 | ] 34 | 35 | wait = false 36 | 37 | create_namespace = true 38 | 39 | depends_on = [ 40 | helm_release.cert-manager, 41 | ] 42 | } 43 | 44 | resource "helm_release" "cert-manager" { 45 | repository = "https://charts.jetstack.io" 46 | chart = "cert-manager" 47 | version = var.jetstack_cert_manager_version 48 | 49 | namespace = "cert-manager" 50 | name = "cert-manager" 51 | 52 | values = [ 53 | file("./modules/ingress/values/cert-manager.yml") 54 | ] 55 | 56 | create_namespace = true 57 | } 58 | 59 | ### External-DNS 60 | 61 | resource "helm_release" "external-dns" { 62 | repository = "https://charts.bitnami.com/bitnami" 63 | chart = "external-dns" 64 | version = var.bitnami_external_dns_version 65 | 66 | namespace = "kube-ingress" 67 | name = "external-dns" 68 | 69 | values = [ 70 | file("./modules/ingress/values/external-dns.yml") 71 | ] 72 | 73 | set { 74 | name = "domainFilters[0]" 75 | value = var.domain 76 | } 77 | 78 | wait = false 79 | 80 | create_namespace = true 81 | } 82 | 83 | ### Metrics server 84 | 85 | resource "helm_release" "metrics-server" { 86 | repository = "https://charts.helm.sh/stable" 87 | chart = "metrics-server" 88 | version = var.stable_metrics_server_version 89 | 90 | namespace = "kube-system" 91 | name = "metrics-server" 92 | 93 | values = [ 94 | file("./modules/ingress/values/metrics-server.yml") 95 | ] 96 | 97 | wait = false 98 | } -------------------------------------------------------------------------------- /charts/modules/ingress/values/cert-manager-issuers.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - apiVersion: cert-manager.io/v1alpha2 3 | kind: ClusterIssuer 4 | metadata: 5 | name: letsencrypt-prod 6 | spec: 7 | acme: 8 | # The ACME server URL 9 | server: https://acme-v02.api.letsencrypt.org/directory 10 | # Email address used for ACME registration 11 | email: timur_galeev@outlook.com 12 | # Name of a secret used to store the ACME account private key 13 | privateKeySecretRef: 14 | name: letsencrypt-prod 15 | solvers: 16 | # An empty 'selector' means that this solver matches all domains 17 | - selector: {} 18 | http01: 19 | ingress: 20 | class: nginx -------------------------------------------------------------------------------- /charts/modules/ingress/values/cert-manager.yml: -------------------------------------------------------------------------------- 1 | nameOverride: cert-manager 2 | 3 | installCRDs: true 4 | 5 | rbac: 6 | create: true 7 | 8 | ingressShim: 9 | defaultIssuerName: letsencrypt-prod 10 | defaultIssuerKind: ClusterIssuer -------------------------------------------------------------------------------- /charts/modules/ingress/values/external-dns.yml: -------------------------------------------------------------------------------- 1 | nameOverride: external-dns 2 | provider: aws 3 | policy: upsert-only 4 | sources: 5 | - service 6 | # - ingress 7 | 8 | rbac: 9 | create: true -------------------------------------------------------------------------------- /charts/modules/ingress/values/ingress-nginx.yml: -------------------------------------------------------------------------------- 1 | nameOverride: nginx-ingress 2 | 3 | controller: 4 | kind: DaemonSet 5 | config: 6 | proxy-protocol: "true" 7 | real-ip-header: "proxy_protocol" 8 | # set-real-ip-from: "0.0.0.0/0" 9 | use-forwarded-headers: "true" 10 | service: 11 | annotations: 12 | external-dns.alpha.kubernetes.io/hostname: "*.godapp.de" 13 | # external-dns.alpha.kubernetes.io/ttl: "300" 14 | # service.beta.kubernetes.io/aws-load-balancer-type: "nlb" 15 | # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http" 16 | service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "3600" 17 | service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" 18 | # service.beta.kubernetes.io/aws-load-balancer-security-groups: "" 19 | service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "" 20 | service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" 21 | 22 | # externalTrafficPolicy: "Cluster" 23 | 24 | stats: 25 | enabled: true 26 | metrics: 27 | enabled: true 28 | # service: 29 | # annotations: 30 | # prometheus.io/scrape: "true" 31 | # prometheus.io/port: "10254" 32 | serviceMonitor: 33 | enabled: true 34 | additionalLabels: 35 | release: prometheus-operator 36 | -------------------------------------------------------------------------------- /charts/modules/ingress/values/metrics-server.yml: -------------------------------------------------------------------------------- 1 | nameOverride: metrics-server 2 | 3 | args: 4 | - --kubelet-insecure-tls 5 | - --kubelet-preferred-address-types=InternalDNS,InternalIP,ExternalDNS,ExternalIP,Hostname 6 | 7 | podAnnotations: 8 | cluster-autoscaler.kubernetes.io/safe-to-evict: "false" -------------------------------------------------------------------------------- /charts/modules/ingress/variables.tf: -------------------------------------------------------------------------------- 1 | variable "module_depends_on" { 2 | default = [] 3 | } 4 | 5 | variable "bitnami_external_dns_version" { 6 | type = string 7 | description = "External DNS Version" 8 | } 9 | 10 | variable "stable_nginx_ingress_version" { 11 | type = string 12 | description = "Nginx Ingress Version" 13 | } 14 | 15 | variable "jetstack_cert_manager_version" { 16 | type = string 17 | description = "Jetstack Cert Manager Version" 18 | } 19 | 20 | variable "stable_metrics_server_version" { 21 | type = string 22 | description = "Metrics Server Version" 23 | } 24 | 25 | variable "cert_manager_email" { 26 | type = string 27 | description = "Set email for Cert manager notifications" 28 | } 29 | 30 | variable "domain" { 31 | type = string 32 | description = "Domain name for Extarnal DNS service" 33 | } -------------------------------------------------------------------------------- /charts/modules/istio/main.tf: -------------------------------------------------------------------------------- 1 | # istio 2 | 3 | # istioctl manifest apply --set profile=demo --set values.kiali.dashboard.auth.strategy=anonymous 4 | 5 | resource "helm_release" "kiali-gatekeeper" { 6 | count = var.kiali_gatekeeper_count ? 1 : 0 7 | repository = "https://gabibbo97.github.io/charts/" 8 | chart = "keycloak-gatekeeper" 9 | version = var.gabibbo97_keycloak_gatekeeper_version 10 | 11 | namespace = "istio-system" 12 | name = "kiali-gatekeeper" 13 | 14 | values = [ 15 | file("./modules/istio/values/kiali-gatekeeper.yaml") 16 | ] 17 | 18 | wait = false 19 | 20 | create_namespace = true 21 | 22 | depends_on = [ 23 | var.module_depends_on 24 | ] 25 | } 26 | 27 | resource "helm_release" "tracing-gatekeeper" { 28 | count = var.tracing_gatekeeper_count ? 1 : 0 29 | repository = "https://gabibbo97.github.io/charts/" 30 | chart = "keycloak-gatekeeper" 31 | version = var.gabibbo97_keycloak_gatekeeper_version 32 | 33 | namespace = "istio-system" 34 | name = "tracing-gatekeeper" 35 | 36 | values = [ 37 | file("./modules/istio/values/tracing-gatekeeper.yaml") 38 | ] 39 | 40 | wait = false 41 | 42 | create_namespace = true 43 | 44 | depends_on = [ 45 | var.module_depends_on 46 | ] 47 | } -------------------------------------------------------------------------------- /charts/modules/istio/values/kiali-gatekeeper.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: kiali-gatekeeper 2 | 3 | discoveryURL: https://keycloak.godapp.de/auth/realms/demo 4 | 5 | upstreamURL: http://kiali-gatekeeper.istio-system.svc.cluster.local:20001 6 | 7 | ClientID: kiali 8 | ClientSecret: 746b5179-2b86-4c5c-8b1f-440e893f650b 9 | 10 | ingress: 11 | enabled: true 12 | annotations: 13 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 14 | kubernetes.io/ingress.class: nginx 15 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 16 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 17 | hosts: 18 | - "kiali-istio.godapp.de" 19 | tls: 20 | - secretName: kiali-tls 21 | hosts: 22 | - "kiali-istio.godapp.de" -------------------------------------------------------------------------------- /charts/modules/istio/values/tracing-gatekeeper.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: tracing-gatekeeper 2 | 3 | discoveryURL: https://keycloak.godapp.de/auth/realms/demo 4 | 5 | upstreamURL: http://tracing-gatekeeper.istio-system.svc.cluster.local:80 6 | 7 | ClientID: tracing 8 | ClientSecret: 0e94208b-1ea1-4e9b-b6e4-3e0b15c9fb9d 9 | 10 | ingress: 11 | enabled: true 12 | annotations: 13 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 14 | kubernetes.io/ingress.class: nginx 15 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 16 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 17 | hosts: 18 | - "tracing-istio.godapp.de" 19 | tls: 20 | - secretName: tracing-tls 21 | hosts: 22 | - "tracing-istio.godapp.de" -------------------------------------------------------------------------------- /charts/modules/istio/variable.tf: -------------------------------------------------------------------------------- 1 | variable "module_depends_on" { 2 | default = [] 3 | } 4 | 5 | variable "gabibbo97_keycloak_gatekeeper_version" { 6 | type = string 7 | description = "Keycloak Gatekeeper Version" 8 | } 9 | 10 | variable "kiali_gatekeeper_count" { 11 | default = [] 12 | } 13 | 14 | variable "tracing_gatekeeper_count" { 15 | default = [] 16 | } -------------------------------------------------------------------------------- /charts/modules/jenkins/jenkins-secret.tf: -------------------------------------------------------------------------------- 1 | # jenkins secret 2 | 3 | # https://github.com/jenkinsci/kubernetes-credentials-provider-plugin/tree/master/docs/examples 4 | 5 | resource "kubernetes_secret" "jenkins-secret-username" { 6 | count = var.jenkins_count ? 1 : 0 7 | metadata { 8 | namespace = "jenkins" 9 | name = "jenkins-secret-username" 10 | 11 | labels = { 12 | "jenkins.io/credentials-type" : "usernamePassword" 13 | } 14 | 15 | annotations = { 16 | "jenkins.io/credentials-description" : "credentials from Kubernetes" 17 | } 18 | } 19 | 20 | type = "Opaque" 21 | 22 | data = { 23 | "username" = "username" 24 | "password" = "password" 25 | } 26 | 27 | depends_on = [ 28 | helm_release.jenkins, 29 | ] 30 | } 31 | 32 | resource "kubernetes_secret" "jenkins-secret-text" { 33 | count = var.jenkins_count ? 1 : 0 34 | metadata { 35 | namespace = "jenkins" 36 | name = "jenkins-secret-text" 37 | 38 | labels = { 39 | "jenkins.io/credentials-type" : "secretText" 40 | } 41 | 42 | annotations = { 43 | "jenkins.io/credentials-description" : "secret text credential from Kubernetes" 44 | } 45 | } 46 | 47 | type = "Opaque" 48 | 49 | data = { 50 | "text" = "Hello World!" 51 | } 52 | 53 | depends_on = [ 54 | helm_release.jenkins, 55 | ] 56 | } 57 | 58 | resource "kubernetes_secret" "jenkins-secret-file" { 59 | count = var.jenkins_count ? 1 : 0 60 | metadata { 61 | namespace = "jenkins" 62 | name = "jenkins-secret-file" 63 | 64 | labels = { 65 | "jenkins.io/credentials-type" : "secretFile" 66 | } 67 | 68 | annotations = { 69 | "jenkins.io/credentials-description" : "secret file credential from Kubernetes" 70 | } 71 | } 72 | 73 | type = "Opaque" 74 | 75 | data = { 76 | "filename" = "secret.txt" 77 | "data" = file("./modules/jenkins/values/secret/secret.txt") 78 | } 79 | 80 | depends_on = [ 81 | helm_release.jenkins, 82 | ] 83 | } 84 | 85 | resource "kubernetes_secret" "jenkins-secret-private-key" { 86 | count = var.jenkins_count ? 1 : 0 87 | metadata { 88 | namespace = "jenkins" 89 | name = "jenkins-secret-private-key" 90 | 91 | labels = { 92 | "jenkins.io/credentials-type" : "basicSSHUserPrivateKey" 93 | } 94 | 95 | annotations = { 96 | "jenkins.io/credentials-description" : "basic user private key credential from Kubernetes" 97 | } 98 | } 99 | 100 | type = "Opaque" 101 | 102 | data = { 103 | "username" = "jenkins" 104 | "privateKey" = file("./modules/jenkins/values/secret/jenkins.txt") 105 | } 106 | 107 | depends_on = [ 108 | helm_release.jenkins, 109 | ] 110 | } -------------------------------------------------------------------------------- /charts/modules/jenkins/main.tf: -------------------------------------------------------------------------------- 1 | # jenkins 2 | 3 | resource "helm_release" "jenkins" { 4 | count = var.jenkins_count ? 1 : 0 5 | repository = "https://charts.helm.sh/stable" 6 | chart = "jenkins" 7 | version = var.jenkins_version 8 | 9 | namespace = "jenkins" 10 | name = "jenkins" 11 | 12 | values = [ 13 | file("./modules/jenkins/values/jenkins.yaml") 14 | ] 15 | 16 | wait = false 17 | 18 | create_namespace = true 19 | 20 | depends_on = [ 21 | var.module_depends_on 22 | ] 23 | } 24 | 25 | resource "kubernetes_cluster_role_binding" "cluster-admin-jenkins-default" { 26 | count = var.jenkins_count ? 1 : 0 27 | metadata { 28 | name = "cluster-admin:jenkins:default" 29 | } 30 | 31 | role_ref { 32 | api_group = "rbac.authorization.k8s.io" 33 | kind = "ClusterRole" 34 | name = "cluster-admin" 35 | } 36 | 37 | subject { 38 | kind = "ServiceAccount" 39 | namespace = "jenkins" 40 | name = "default" 41 | } 42 | 43 | depends_on = [ 44 | var.module_depends_on 45 | ] 46 | } 47 | 48 | # for jenkins 49 | resource "kubernetes_config_map" "jenkins-env" { 50 | count = var.jenkins_count ? 1 : 0 51 | metadata { 52 | namespace = "default" 53 | name = "jenkins-env" 54 | } 55 | 56 | data = { 57 | "groovy" = file("./modules/jenkins/values/env/jenkins-env.groovy") 58 | } 59 | } -------------------------------------------------------------------------------- /charts/modules/jenkins/values/env/jenkins-env.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/groovy 2 | import groovy.transform.Field 3 | @Field 4 | def role = "devops" 5 | @Field 6 | def cluster = "EKS-DEMO" 7 | @Field 8 | def base_domain = "godapp.de" 9 | @Field 10 | def slack_token = "REPLACEME/REPLACEME/REPLACEME" 11 | @Field 12 | def jenkins = "jenkins.godapp.de" 13 | @Field 14 | def archiva = "archiva.godapp.de" 15 | @Field 16 | def chartmuseum = "chartmuseum.godapp.de" 17 | @Field 18 | def nexus = "nexus.godapp.de" 19 | @Field 20 | def sonarqube = "sonarqube.godapp.de" 21 | @Field 22 | def registry = "249565476171.dkr.ecr.eu-central-1.amazonaws.com" 23 | return this -------------------------------------------------------------------------------- /charts/modules/jenkins/values/jenkins.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: jenkins 2 | 3 | master: 4 | adminUser: "admin" 5 | adminPassword: "password" 6 | 7 | resources: 8 | requests: 9 | cpu: 1000m 10 | memory: 1Gi 11 | limits: 12 | cpu: 1000m 13 | memory: 2Gi 14 | 15 | podAnnotations: 16 | cluster-autoscaler.kubernetes.io/safe-to-evict: "false" 17 | 18 | # hostNetworking: true 19 | 20 | javaOpts: "-Dorg.apache.commons.jelly.tags.fmt.timeZone=Europe/Berlin" 21 | 22 | # customConfigMap: true 23 | # overwriteConfig: true 24 | # overwriteJobs: true 25 | 26 | ingress: 27 | enabled: true 28 | annotations: 29 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 30 | kubernetes.io/ingress.class: nginx 31 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 32 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 33 | hostName: "jenkins.godapp.de" 34 | tls: 35 | - secretName: jenkins-tls 36 | hosts: 37 | - "jenkins.godapp.de" 38 | 39 | # https://github.com/helm/charts/blob/master/stable/jenkins/values.yaml 40 | installPlugins: 41 | - configuration-as-code:latest 42 | - credentials-binding:latest 43 | - git:latest 44 | - kubernetes:latest 45 | - workflow-aggregator:latest 46 | - workflow-job:latest 47 | 48 | # https://plugins.jenkins.io/ 49 | additionalPlugins: 50 | - authorize-project:latest 51 | - blueocean:latest 52 | - github-pullrequest:latest 53 | - job-dsl:latest 54 | - keycloak:latest 55 | - kubernetes-credentials-provider:latest 56 | - pipeline-github-lib:latest 57 | - prometheus:latest 58 | - role-strategy:latest 59 | # - generic-webhook-trigger:latest 60 | 61 | overwritePlugins: true 62 | 63 | prometheus: 64 | enabled: true 65 | serviceMonitorAdditionalLabels: 66 | release: prometheus-operator 67 | 68 | # https://plugins.jenkins.io/configuration-as-code/ 69 | JCasC: 70 | # enabled: true 71 | # defaultConfig: true 72 | 73 | configScripts: 74 | welcome-message: |- 75 | jenkins: 76 | systemMessage: | 77 | Welcome to CI\CD server. 78 | This Jenkins is configured and managed 'as code'. 79 | # https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/demos/keycloak/README.md 80 | keycloak: |- 81 | unclassified: 82 | keycloakSecurityRealm: 83 | keycloakJson: |- 84 | { 85 | "realm": "demo", 86 | "auth-server-url": "https://keycloak.godapp.de/auth/", 87 | "ssl-required": "external", 88 | "resource": "jenkins", 89 | "credentials": { 90 | "secret": "f76f3359-4be2-45dd-aba9-6f5204e62438" 91 | }, 92 | "confidential-port": 0 93 | } 94 | # https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/docs/seed-jobs.md 95 | # https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/demos/jobs/multibranch-github.yaml 96 | jobs: |- 97 | jobs: 98 | - script: > 99 | multibranchPipelineJob('sample-spring') { 100 | branchSources { 101 | git { 102 | id = 'sample-spring' 103 | remote('https://github.com/timurgaleev/sample-spring.git') 104 | } 105 | } 106 | orphanedItemStrategy { 107 | discardOldItems { 108 | numToKeep(15) 109 | } 110 | } 111 | } 112 | # https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/demos/keycloak/README.md 113 | securityRealm: |- 114 | keycloak 115 | # https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/demos/role-strategy-auth/README.md 116 | authorizationStrategy: |- 117 | roleBased: 118 | roles: 119 | global: 120 | - name: "admin" 121 | description: "Administrators" 122 | permissions: 123 | - "Overall/Administer" 124 | assignments: 125 | - "admin" 126 | - "timur_galeev@outlook.com" 127 | - name: "readonly" 128 | description: "Read-only users" 129 | permissions: 130 | - "Overall/Read" 131 | - "Job/Read" 132 | assignments: 133 | - "authenticated" 134 | items: 135 | - name: "sample" 136 | description: "Sample projects" 137 | pattern: "sample-.*" 138 | permissions: 139 | - "Job/Configure" 140 | - "Job/Build" 141 | - "Job/Delete" 142 | assignments: 143 | - "user1" 144 | - "user2" 145 | persistence: 146 | enabled: true 147 | size: 20Gi 148 | 149 | rbac: 150 | create: true 151 | readSecrets: true 152 | 153 | serviceAccount: 154 | create: true 155 | 156 | serviceAccountAgent: 157 | create: true -------------------------------------------------------------------------------- /charts/modules/jenkins/values/secret/jenkins.txt: -------------------------------------------------------------------------------- 1 | hello jenkins world -------------------------------------------------------------------------------- /charts/modules/jenkins/values/secret/secret.txt: -------------------------------------------------------------------------------- 1 | hello secret file -------------------------------------------------------------------------------- /charts/modules/jenkins/variable.tf: -------------------------------------------------------------------------------- 1 | variable "module_depends_on" { 2 | default = [] 3 | } 4 | 5 | variable "jenkins_version" { 6 | type = string 7 | description = "version" 8 | } 9 | 10 | variable "jenkins_count" { 11 | default = [] 12 | } 13 | 14 | variable "domains" { 15 | description = "domain name for ingress" 16 | } -------------------------------------------------------------------------------- /charts/modules/keycloak/main.tf: -------------------------------------------------------------------------------- 1 | # keycloak 2 | 3 | resource "kubernetes_namespace" "keycloak" { 4 | metadata { 5 | name = "keycloak" 6 | } 7 | } 8 | 9 | resource "kubernetes_secret" "keycloak-admin" { 10 | count = var.keycloak_enabled ? 1 : 0 11 | 12 | metadata { 13 | namespace = "keycloak" 14 | name = "keycloak-admin" 15 | } 16 | 17 | type = "Opaque" 18 | 19 | data = { 20 | "username" = "admin" 21 | "password" = "password" 22 | } 23 | 24 | depends_on = [ 25 | kubernetes_namespace.keycloak, 26 | ] 27 | } 28 | 29 | resource "kubernetes_secret" "keycloak-realm" { 30 | metadata { 31 | namespace = "keycloak" 32 | name = "keycloak-realm" 33 | } 34 | 35 | type = "Opaque" 36 | 37 | data = { 38 | "demo.json" = file("./modules/keycloak/values/realm/demo.json") 39 | } 40 | 41 | depends_on = [ 42 | kubernetes_namespace.keycloak, 43 | ] 44 | } 45 | 46 | resource "helm_release" "keycloak" { 47 | repository = "https://codecentric.github.io/helm-charts" 48 | chart = "keycloak" 49 | version = var.codecentric_keycloak_version 50 | 51 | namespace = "keycloak" 52 | name = "keycloak" 53 | 54 | values = [ 55 | file("./modules/keycloak/values/keycloak.yaml") 56 | ] 57 | 58 | set { 59 | name = "keycloak.ingress.hosts[0]" 60 | value = "keycloak.${var.domains}" 61 | } 62 | 63 | set { 64 | name = "keycloak.ingress.tls[0].secretName" 65 | value = "keycloak-tls" 66 | } 67 | 68 | set { 69 | name = "keycloak.ingress.tls[0].hosts[0]" 70 | value = "keycloak.${var.domains}" 71 | } 72 | 73 | depends_on = [ 74 | kubernetes_secret.keycloak-admin, 75 | kubernetes_secret.keycloak-realm, 76 | var.module_depends_on 77 | ] 78 | } -------------------------------------------------------------------------------- /charts/modules/keycloak/output.tf: -------------------------------------------------------------------------------- 1 | output "keycloak_realese" { 2 | value = helm_release.keycloak 3 | } -------------------------------------------------------------------------------- /charts/modules/keycloak/values/keycloak.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: keycloak 2 | 3 | keycloak: 4 | replicas: 2 5 | 6 | username: "admin" 7 | password: "password" 8 | 9 | cli: 10 | enabled: false 11 | 12 | ingress: 13 | enabled: true 14 | annotations: 15 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 16 | kubernetes.io/ingress.class: nginx 17 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 18 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 19 | 20 | podAnnotations: 21 | cluster-autoscaler.kubernetes.io/safe-to-evict: "false" 22 | 23 | extraEnv: | 24 | - name: PROXY_ADDRESS_FORWARDING 25 | value: "true" 26 | 27 | extraVolumes: | 28 | - name: keycloak-realm 29 | secret: 30 | secretName: keycloak-realm 31 | 32 | extraVolumeMounts: | 33 | - name: keycloak-realm 34 | mountPath: "/realm/" 35 | readOnly: true 36 | 37 | extraArgs: -Dkeycloak.import=/realm/demo.json 38 | 39 | persistence: 40 | deployPostgres: true 41 | dbVendor: postgres 42 | dbHost: keycloak-postgresql 43 | dbPort: 5432 44 | dbUser: keycloak 45 | dbPassword: password 46 | 47 | postgresql: 48 | enabled: true 49 | postgresqlUsername: keycloak 50 | postgresqlPassword: password 51 | persistence: 52 | enabled: true 53 | size: 10Gi 54 | 55 | prometheus: 56 | operator: 57 | enabled: true 58 | 59 | serviceMonitor: 60 | selector: 61 | release: prometheus-operator 62 | 63 | prometheusRules: 64 | ## Add Prometheus Rules? 65 | enabled: false 66 | 67 | ## Additional labels to add to the PrometheusRule so it is picked up by the operator. 68 | ## If using the [Helm Chart](https://github.com/helm/charts/tree/master/stable/prometheus-operator) this is the name of the Helm release and 'app: prometheus-operator' 69 | selector: 70 | app: prometheus-operator 71 | release: prometheus 72 | 73 | ## Some example rules. 74 | rules: {} 75 | # - alert: keycloak-IngressHigh5xxRate 76 | # annotations: 77 | # message: The percentage of 5xx errors for keycloak over the last 5 minutes is over 1%. 78 | # expr: (sum(rate(nginx_ingress_controller_response_duration_seconds_count{exported_namespace="mynamespace",ingress="mynamespace-keycloak",status=~"5[0-9]{2}"}[1m]))/sum(rate(nginx_ingress_controller_response_duration_seconds_count{exported_namespace="mynamespace",ingress="mynamespace-keycloak"}[1m])))*100 > 1 79 | # for: 5m 80 | # labels: 81 | # severity: warning 82 | # - alert: keycloak-IngressHigh5xxRate 83 | # annotations: 84 | # message: The percentage of 5xx errors for keycloak over the last 5 minutes is over 5%. 85 | # expr: (sum(rate(nginx_ingress_controller_response_duration_seconds_count{exported_namespace="mynamespace",ingress="mynamespace-keycloak",status=~"5[0-9]{2}"}[1m]))/sum(rate(nginx_ingress_controller_response_duration_seconds_count{exported_namespace="mynamespace",ingress="mynamespace-keycloak"}[1m])))*100 > 5 86 | # for: 5m 87 | # labels: 88 | # severity: critical -------------------------------------------------------------------------------- /charts/modules/keycloak/values/realm/demo.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "demo", 3 | "realm": "demo", 4 | "notBefore": 0, 5 | "revokeRefreshToken": false, 6 | "refreshTokenMaxReuse": 0, 7 | "accessTokenLifespan": 300, 8 | "accessTokenLifespanForImplicitFlow": 900, 9 | "ssoSessionIdleTimeout": 1800, 10 | "ssoSessionMaxLifespan": 36000, 11 | "ssoSessionIdleTimeoutRememberMe": 0, 12 | "ssoSessionMaxLifespanRememberMe": 0, 13 | "offlineSessionIdleTimeout": 2592000, 14 | "offlineSessionMaxLifespanEnabled": false, 15 | "offlineSessionMaxLifespan": 5184000, 16 | "clientSessionIdleTimeout": 0, 17 | "clientSessionMaxLifespan": 0, 18 | "accessCodeLifespan": 60, 19 | "accessCodeLifespanUserAction": 300, 20 | "accessCodeLifespanLogin": 1800, 21 | "actionTokenGeneratedByAdminLifespan": 43200, 22 | "actionTokenGeneratedByUserLifespan": 300, 23 | "enabled": true, 24 | "sslRequired": "external", 25 | "registrationAllowed": false, 26 | "registrationEmailAsUsername": false, 27 | "rememberMe": false, 28 | "verifyEmail": false, 29 | "loginWithEmailAllowed": true, 30 | "duplicateEmailsAllowed": false, 31 | "resetPasswordAllowed": false, 32 | "editUsernameAllowed": false, 33 | "bruteForceProtected": false, 34 | "permanentLockout": false, 35 | "maxFailureWaitSeconds": 900, 36 | "minimumQuickLoginWaitSeconds": 60, 37 | "waitIncrementSeconds": 60, 38 | "quickLoginCheckMilliSeconds": 1000, 39 | "maxDeltaTimeSeconds": 43200, 40 | "failureFactor": 30, 41 | "roles": { 42 | "realm": [ 43 | { 44 | "id": "042f9add-d0f3-4168-9efe-b515b0c6a7df", 45 | "name": "offline_access", 46 | "description": "${role_offline-access}", 47 | "composite": false, 48 | "clientRole": false, 49 | "containerId": "demo", 50 | "attributes": {} 51 | }, 52 | { 53 | "id": "28cbf5ee-479b-45f7-bd46-f2a0472c973e", 54 | "name": "uma_authorization", 55 | "description": "${role_uma_authorization}", 56 | "composite": false, 57 | "clientRole": false, 58 | "containerId": "demo", 59 | "attributes": {} 60 | } 61 | ], 62 | "client": { 63 | "realm-management": [ 64 | { 65 | "id": "5fb7cc7d-73c2-4e9b-8791-bac4b8b8d8cd", 66 | "name": "create-client", 67 | "description": "${role_create-client}", 68 | "composite": false, 69 | "clientRole": true, 70 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 71 | "attributes": {} 72 | }, 73 | { 74 | "id": "a55cafa4-91cf-49c2-ac5e-cd060bbe1ad0", 75 | "name": "view-realm", 76 | "description": "${role_view-realm}", 77 | "composite": false, 78 | "clientRole": true, 79 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 80 | "attributes": {} 81 | }, 82 | { 83 | "id": "58045c9b-edb6-4c96-908d-273110299a50", 84 | "name": "view-identity-providers", 85 | "description": "${role_view-identity-providers}", 86 | "composite": false, 87 | "clientRole": true, 88 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 89 | "attributes": {} 90 | }, 91 | { 92 | "id": "420a4870-f087-4cab-a8f5-7f511f806fdb", 93 | "name": "query-clients", 94 | "description": "${role_query-clients}", 95 | "composite": false, 96 | "clientRole": true, 97 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 98 | "attributes": {} 99 | }, 100 | { 101 | "id": "b4d38bcd-afdc-4f18-be66-f8bcc0461073", 102 | "name": "view-events", 103 | "description": "${role_view-events}", 104 | "composite": false, 105 | "clientRole": true, 106 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 107 | "attributes": {} 108 | }, 109 | { 110 | "id": "7653631a-df3c-44b4-ab80-36b855d17899", 111 | "name": "manage-users", 112 | "description": "${role_manage-users}", 113 | "composite": false, 114 | "clientRole": true, 115 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 116 | "attributes": {} 117 | }, 118 | { 119 | "id": "85bf25a0-9c09-4d9c-a240-787599184592", 120 | "name": "manage-realm", 121 | "description": "${role_manage-realm}", 122 | "composite": false, 123 | "clientRole": true, 124 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 125 | "attributes": {} 126 | }, 127 | { 128 | "id": "cab35dbe-dbb0-4d12-8517-100f7bf0753d", 129 | "name": "impersonation", 130 | "description": "${role_impersonation}", 131 | "composite": false, 132 | "clientRole": true, 133 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 134 | "attributes": {} 135 | }, 136 | { 137 | "id": "33ea3697-f043-453c-b0f4-012491aa06d1", 138 | "name": "manage-identity-providers", 139 | "description": "${role_manage-identity-providers}", 140 | "composite": false, 141 | "clientRole": true, 142 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 143 | "attributes": {} 144 | }, 145 | { 146 | "id": "ed18ba34-72ae-4c16-b49a-ddeebd939f22", 147 | "name": "view-users", 148 | "description": "${role_view-users}", 149 | "composite": true, 150 | "composites": { 151 | "client": { 152 | "realm-management": [ 153 | "query-groups", 154 | "query-users" 155 | ] 156 | } 157 | }, 158 | "clientRole": true, 159 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 160 | "attributes": {} 161 | }, 162 | { 163 | "id": "92494901-9cac-42f0-84fc-0a1c6e242bce", 164 | "name": "manage-events", 165 | "description": "${role_manage-events}", 166 | "composite": false, 167 | "clientRole": true, 168 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 169 | "attributes": {} 170 | }, 171 | { 172 | "id": "c8e0d842-bca1-44e9-89e3-478571a92873", 173 | "name": "query-groups", 174 | "description": "${role_query-groups}", 175 | "composite": false, 176 | "clientRole": true, 177 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 178 | "attributes": {} 179 | }, 180 | { 181 | "id": "34c00c7a-066b-4ca7-a7f9-9cb38fda22f1", 182 | "name": "query-users", 183 | "description": "${role_query-users}", 184 | "composite": false, 185 | "clientRole": true, 186 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 187 | "attributes": {} 188 | }, 189 | { 190 | "id": "9edcaae5-c716-4e70-b853-e36d2eca3c8b", 191 | "name": "manage-clients", 192 | "description": "${role_manage-clients}", 193 | "composite": false, 194 | "clientRole": true, 195 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 196 | "attributes": {} 197 | }, 198 | { 199 | "id": "50c529bb-ddeb-4fde-a36c-9286cb668a3f", 200 | "name": "view-clients", 201 | "description": "${role_view-clients}", 202 | "composite": true, 203 | "composites": { 204 | "client": { 205 | "realm-management": [ 206 | "query-clients" 207 | ] 208 | } 209 | }, 210 | "clientRole": true, 211 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 212 | "attributes": {} 213 | }, 214 | { 215 | "id": "ff67c08b-b00b-4936-82bc-17b2249e8802", 216 | "name": "manage-authorization", 217 | "description": "${role_manage-authorization}", 218 | "composite": false, 219 | "clientRole": true, 220 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 221 | "attributes": {} 222 | }, 223 | { 224 | "id": "8487dc3b-580a-45b0-ac17-b08827d0bf06", 225 | "name": "view-authorization", 226 | "description": "${role_view-authorization}", 227 | "composite": false, 228 | "clientRole": true, 229 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 230 | "attributes": {} 231 | }, 232 | { 233 | "id": "b9b846a2-3960-436d-9f5c-df1581afa9d6", 234 | "name": "realm-admin", 235 | "description": "${role_realm-admin}", 236 | "composite": true, 237 | "composites": { 238 | "client": { 239 | "realm-management": [ 240 | "create-client", 241 | "view-realm", 242 | "view-identity-providers", 243 | "query-clients", 244 | "view-events", 245 | "manage-users", 246 | "manage-realm", 247 | "impersonation", 248 | "manage-identity-providers", 249 | "view-users", 250 | "manage-events", 251 | "query-groups", 252 | "query-users", 253 | "manage-clients", 254 | "view-clients", 255 | "manage-authorization", 256 | "view-authorization", 257 | "query-realms" 258 | ] 259 | } 260 | }, 261 | "clientRole": true, 262 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 263 | "attributes": {} 264 | }, 265 | { 266 | "id": "48404444-9d17-4eed-b4a8-7b523472ed27", 267 | "name": "query-realms", 268 | "description": "${role_query-realms}", 269 | "composite": false, 270 | "clientRole": true, 271 | "containerId": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 272 | "attributes": {} 273 | } 274 | ], 275 | "argo-cd": [], 276 | "argo": [], 277 | "grafana": [], 278 | "jenkins": [], 279 | "kiali": [], 280 | "sonarqube": [], 281 | "tracing": [], 282 | "weave-scope": [], 283 | "security-admin-console": [], 284 | "admin-cli": [], 285 | "account-console": [], 286 | "broker": [ 287 | { 288 | "id": "63cedc86-30d9-4e53-8069-ab05b8b5beed", 289 | "name": "read-token", 290 | "description": "${role_read-token}", 291 | "composite": false, 292 | "clientRole": true, 293 | "containerId": "ca173dc3-cb1b-4b36-bcf0-7fd671ba03a5", 294 | "attributes": {} 295 | } 296 | ], 297 | "account": [ 298 | { 299 | "id": "3784680f-42f2-4cfb-a541-fefb926374e1", 300 | "name": "view-profile", 301 | "description": "${role_view-profile}", 302 | "composite": false, 303 | "clientRole": true, 304 | "containerId": "a5373a78-0450-425d-bcc8-793df7ab90b8", 305 | "attributes": {} 306 | }, 307 | { 308 | "id": "4b6890a7-64d9-429a-a5a2-31dc164d9164", 309 | "name": "manage-account", 310 | "description": "${role_manage-account}", 311 | "composite": true, 312 | "composites": { 313 | "client": { 314 | "account": [ 315 | "manage-account-links" 316 | ] 317 | } 318 | }, 319 | "clientRole": true, 320 | "containerId": "a5373a78-0450-425d-bcc8-793df7ab90b8", 321 | "attributes": {} 322 | }, 323 | { 324 | "id": "6809cadc-a255-4d3d-9d81-712c3d9aa5ce", 325 | "name": "view-consent", 326 | "description": "${role_view-consent}", 327 | "composite": false, 328 | "clientRole": true, 329 | "containerId": "a5373a78-0450-425d-bcc8-793df7ab90b8", 330 | "attributes": {} 331 | }, 332 | { 333 | "id": "0816bb6e-fe5a-46cd-aa65-361eb233f24f", 334 | "name": "view-applications", 335 | "description": "${role_view-applications}", 336 | "composite": false, 337 | "clientRole": true, 338 | "containerId": "a5373a78-0450-425d-bcc8-793df7ab90b8", 339 | "attributes": {} 340 | }, 341 | { 342 | "id": "4f7f1c59-31b7-43b4-9e39-389daa2d2305", 343 | "name": "manage-account-links", 344 | "description": "${role_manage-account-links}", 345 | "composite": false, 346 | "clientRole": true, 347 | "containerId": "a5373a78-0450-425d-bcc8-793df7ab90b8", 348 | "attributes": {} 349 | }, 350 | { 351 | "id": "eec77c7b-4c19-4782-bd87-d693617a86d7", 352 | "name": "manage-consent", 353 | "description": "${role_manage-consent}", 354 | "composite": true, 355 | "composites": { 356 | "client": { 357 | "account": [ 358 | "view-consent" 359 | ] 360 | } 361 | }, 362 | "clientRole": true, 363 | "containerId": "a5373a78-0450-425d-bcc8-793df7ab90b8", 364 | "attributes": {} 365 | } 366 | ] 367 | } 368 | }, 369 | "groups": [ 370 | { 371 | "id": "3582df01-23d2-4a6e-8106-1f97a8757cf7", 372 | "name": "admin", 373 | "path": "/admin", 374 | "attributes": {}, 375 | "realmRoles": [], 376 | "clientRoles": {}, 377 | "subGroups": [] 378 | }, 379 | { 380 | "id": "5104d8eb-a6f7-4299-907c-0434f7db352c", 381 | "name": "dev", 382 | "path": "/dev", 383 | "attributes": {}, 384 | "realmRoles": [], 385 | "clientRoles": {}, 386 | "subGroups": [] 387 | }, 388 | { 389 | "id": "b35fcaa3-ca59-4f42-9a41-fce68e6bd55a", 390 | "name": "ops", 391 | "path": "/ops", 392 | "attributes": {}, 393 | "realmRoles": [], 394 | "clientRoles": {}, 395 | "subGroups": [] 396 | } 397 | ], 398 | "defaultRoles": [ 399 | "offline_access", 400 | "uma_authorization" 401 | ], 402 | "requiredCredentials": [ 403 | "password" 404 | ], 405 | "otpPolicyType": "totp", 406 | "otpPolicyAlgorithm": "HmacSHA1", 407 | "otpPolicyInitialCounter": 0, 408 | "otpPolicyDigits": 6, 409 | "otpPolicyLookAheadWindow": 1, 410 | "otpPolicyPeriod": 30, 411 | "otpSupportedApplications": [ 412 | "FreeOTP", 413 | "Google Authenticator" 414 | ], 415 | "webAuthnPolicyRpEntityName": "keycloak", 416 | "webAuthnPolicySignatureAlgorithms": [ 417 | "ES256" 418 | ], 419 | "webAuthnPolicyRpId": "", 420 | "webAuthnPolicyAttestationConveyancePreference": "not specified", 421 | "webAuthnPolicyAuthenticatorAttachment": "not specified", 422 | "webAuthnPolicyRequireResidentKey": "not specified", 423 | "webAuthnPolicyUserVerificationRequirement": "not specified", 424 | "webAuthnPolicyCreateTimeout": 0, 425 | "webAuthnPolicyAvoidSameAuthenticatorRegister": false, 426 | "webAuthnPolicyAcceptableAaguids": [], 427 | "webAuthnPolicyPasswordlessRpEntityName": "keycloak", 428 | "webAuthnPolicyPasswordlessSignatureAlgorithms": [ 429 | "ES256" 430 | ], 431 | "webAuthnPolicyPasswordlessRpId": "", 432 | "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified", 433 | "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified", 434 | "webAuthnPolicyPasswordlessRequireResidentKey": "not specified", 435 | "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified", 436 | "webAuthnPolicyPasswordlessCreateTimeout": 0, 437 | "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false, 438 | "webAuthnPolicyPasswordlessAcceptableAaguids": [], 439 | "scopeMappings": [ 440 | { 441 | "clientScope": "offline_access", 442 | "roles": [ 443 | "offline_access" 444 | ] 445 | } 446 | ], 447 | "clientScopeMappings": { 448 | "account": [ 449 | { 450 | "client": "account-console", 451 | "roles": [ 452 | "manage-account" 453 | ] 454 | } 455 | ] 456 | }, 457 | "clients": [ 458 | { 459 | "id": "a5373a78-0450-425d-bcc8-793df7ab90b8", 460 | "clientId": "account", 461 | "name": "${client_account}", 462 | "rootUrl": "${authBaseUrl}", 463 | "baseUrl": "/realms/demo/account/", 464 | "surrogateAuthRequired": false, 465 | "enabled": true, 466 | "alwaysDisplayInConsole": false, 467 | "clientAuthenticatorType": "client-secret", 468 | "secret": "**********", 469 | "defaultRoles": [ 470 | "view-profile", 471 | "manage-account" 472 | ], 473 | "redirectUris": [ 474 | "/realms/demo/account/*" 475 | ], 476 | "webOrigins": [], 477 | "notBefore": 0, 478 | "bearerOnly": false, 479 | "consentRequired": false, 480 | "standardFlowEnabled": true, 481 | "implicitFlowEnabled": false, 482 | "directAccessGrantsEnabled": false, 483 | "serviceAccountsEnabled": false, 484 | "publicClient": false, 485 | "frontchannelLogout": false, 486 | "protocol": "openid-connect", 487 | "attributes": {}, 488 | "authenticationFlowBindingOverrides": {}, 489 | "fullScopeAllowed": false, 490 | "nodeReRegistrationTimeout": 0, 491 | "defaultClientScopes": [ 492 | "web-origins", 493 | "role_list", 494 | "profile", 495 | "roles", 496 | "email" 497 | ], 498 | "optionalClientScopes": [ 499 | "address", 500 | "phone", 501 | "offline_access", 502 | "microprofile-jwt" 503 | ] 504 | }, 505 | { 506 | "id": "9626926e-c67c-4d7c-b953-4cd93b296bd2", 507 | "clientId": "account-console", 508 | "name": "${client_account-console}", 509 | "rootUrl": "${authBaseUrl}", 510 | "baseUrl": "/realms/demo/account/", 511 | "surrogateAuthRequired": false, 512 | "enabled": true, 513 | "alwaysDisplayInConsole": false, 514 | "clientAuthenticatorType": "client-secret", 515 | "secret": "**********", 516 | "redirectUris": [ 517 | "/realms/demo/account/*" 518 | ], 519 | "webOrigins": [], 520 | "notBefore": 0, 521 | "bearerOnly": false, 522 | "consentRequired": false, 523 | "standardFlowEnabled": true, 524 | "implicitFlowEnabled": false, 525 | "directAccessGrantsEnabled": false, 526 | "serviceAccountsEnabled": false, 527 | "publicClient": true, 528 | "frontchannelLogout": false, 529 | "protocol": "openid-connect", 530 | "attributes": { 531 | "pkce.code.challenge.method": "S256" 532 | }, 533 | "authenticationFlowBindingOverrides": {}, 534 | "fullScopeAllowed": false, 535 | "nodeReRegistrationTimeout": 0, 536 | "protocolMappers": [ 537 | { 538 | "id": "210e9156-c32a-4cfd-9d22-e8bfb054c35b", 539 | "name": "audience resolve", 540 | "protocol": "openid-connect", 541 | "protocolMapper": "oidc-audience-resolve-mapper", 542 | "consentRequired": false, 543 | "config": {} 544 | } 545 | ], 546 | "defaultClientScopes": [ 547 | "web-origins", 548 | "role_list", 549 | "profile", 550 | "roles", 551 | "email" 552 | ], 553 | "optionalClientScopes": [ 554 | "address", 555 | "phone", 556 | "offline_access", 557 | "microprofile-jwt" 558 | ] 559 | }, 560 | { 561 | "id": "3e2a77bd-3828-418d-9e97-f97633f7731c", 562 | "clientId": "admin-cli", 563 | "name": "${client_admin-cli}", 564 | "surrogateAuthRequired": false, 565 | "enabled": true, 566 | "alwaysDisplayInConsole": false, 567 | "clientAuthenticatorType": "client-secret", 568 | "secret": "**********", 569 | "redirectUris": [], 570 | "webOrigins": [], 571 | "notBefore": 0, 572 | "bearerOnly": false, 573 | "consentRequired": false, 574 | "standardFlowEnabled": false, 575 | "implicitFlowEnabled": false, 576 | "directAccessGrantsEnabled": true, 577 | "serviceAccountsEnabled": false, 578 | "publicClient": true, 579 | "frontchannelLogout": false, 580 | "protocol": "openid-connect", 581 | "attributes": {}, 582 | "authenticationFlowBindingOverrides": {}, 583 | "fullScopeAllowed": false, 584 | "nodeReRegistrationTimeout": 0, 585 | "defaultClientScopes": [ 586 | "web-origins", 587 | "role_list", 588 | "profile", 589 | "roles", 590 | "email" 591 | ], 592 | "optionalClientScopes": [ 593 | "address", 594 | "phone", 595 | "offline_access", 596 | "microprofile-jwt" 597 | ] 598 | }, 599 | { 600 | "id": "ca173dc3-cb1b-4b36-bcf0-7fd671ba03a5", 601 | "clientId": "broker", 602 | "name": "${client_broker}", 603 | "surrogateAuthRequired": false, 604 | "enabled": true, 605 | "alwaysDisplayInConsole": false, 606 | "clientAuthenticatorType": "client-secret", 607 | "secret": "**********", 608 | "redirectUris": [], 609 | "webOrigins": [], 610 | "notBefore": 0, 611 | "bearerOnly": false, 612 | "consentRequired": false, 613 | "standardFlowEnabled": true, 614 | "implicitFlowEnabled": false, 615 | "directAccessGrantsEnabled": false, 616 | "serviceAccountsEnabled": false, 617 | "publicClient": false, 618 | "frontchannelLogout": false, 619 | "protocol": "openid-connect", 620 | "attributes": {}, 621 | "authenticationFlowBindingOverrides": {}, 622 | "fullScopeAllowed": false, 623 | "nodeReRegistrationTimeout": 0, 624 | "defaultClientScopes": [ 625 | "web-origins", 626 | "role_list", 627 | "profile", 628 | "roles", 629 | "email" 630 | ], 631 | "optionalClientScopes": [ 632 | "address", 633 | "phone", 634 | "offline_access", 635 | "microprofile-jwt" 636 | ] 637 | }, 638 | { 639 | "id": "8d3945a0-9df5-4f1b-bc94-6edcb6b0d6d3", 640 | "clientId": "argo-cd", 641 | "rootUrl": "https://argocd.godapp.de/", 642 | "adminUrl": "https://argocd.godapp.de/", 643 | "surrogateAuthRequired": false, 644 | "enabled": true, 645 | "alwaysDisplayInConsole": false, 646 | "clientAuthenticatorType": "client-secret", 647 | "secret": "d91fdbbc-5dbb-43ab-b388-ce4170ff79c6", 648 | "redirectUris": [ 649 | "https://argocd.godapp.de/*" 650 | ], 651 | "webOrigins": [ 652 | "https://argocd.godapp.de" 653 | ], 654 | "notBefore": 0, 655 | "bearerOnly": false, 656 | "consentRequired": false, 657 | "standardFlowEnabled": true, 658 | "implicitFlowEnabled": false, 659 | "directAccessGrantsEnabled": true, 660 | "serviceAccountsEnabled": false, 661 | "publicClient": false, 662 | "frontchannelLogout": false, 663 | "protocol": "openid-connect", 664 | "attributes": { 665 | "saml.assertion.signature": "false", 666 | "saml.force.post.binding": "false", 667 | "saml.multivalued.roles": "false", 668 | "saml.encrypt": "false", 669 | "saml.server.signature": "false", 670 | "saml.server.signature.keyinfo.ext": "false", 671 | "exclude.session.state.from.auth.response": "false", 672 | "saml_force_name_id_format": "false", 673 | "saml.client.signature": "false", 674 | "tls.client.certificate.bound.access.tokens": "false", 675 | "saml.authnstatement": "false", 676 | "display.on.consent.screen": "false", 677 | "saml.onetimeuse.condition": "false" 678 | }, 679 | "authenticationFlowBindingOverrides": {}, 680 | "fullScopeAllowed": true, 681 | "nodeReRegistrationTimeout": -1, 682 | "defaultClientScopes": [ 683 | "web-origins", 684 | "role_list", 685 | "profile", 686 | "roles", 687 | "groups", 688 | "email" 689 | ], 690 | "optionalClientScopes": [ 691 | "address", 692 | "phone", 693 | "offline_access", 694 | "microprofile-jwt" 695 | ] 696 | }, 697 | { 698 | "id": "859f441a-7820-4717-aa56-118762c4ba72", 699 | "clientId": "argo", 700 | "rootUrl": "https://argo.godapp.de/", 701 | "adminUrl": "https://argo.godapp.de/", 702 | "surrogateAuthRequired": false, 703 | "enabled": true, 704 | "alwaysDisplayInConsole": false, 705 | "clientAuthenticatorType": "client-secret", 706 | "secret": "60820e7d-80a1-4e63-9ae1-b83972eaa020", 707 | "redirectUris": [ 708 | "https://argo.godapp.de/*" 709 | ], 710 | "webOrigins": [ 711 | "https://argo.godapp.de" 712 | ], 713 | "notBefore": 0, 714 | "bearerOnly": false, 715 | "consentRequired": false, 716 | "standardFlowEnabled": true, 717 | "implicitFlowEnabled": false, 718 | "directAccessGrantsEnabled": true, 719 | "serviceAccountsEnabled": false, 720 | "publicClient": false, 721 | "frontchannelLogout": false, 722 | "protocol": "openid-connect", 723 | "attributes": { 724 | "saml.assertion.signature": "false", 725 | "saml.force.post.binding": "false", 726 | "saml.multivalued.roles": "false", 727 | "saml.encrypt": "false", 728 | "saml.server.signature": "false", 729 | "saml.server.signature.keyinfo.ext": "false", 730 | "exclude.session.state.from.auth.response": "false", 731 | "saml_force_name_id_format": "false", 732 | "saml.client.signature": "false", 733 | "tls.client.certificate.bound.access.tokens": "false", 734 | "saml.authnstatement": "false", 735 | "display.on.consent.screen": "false", 736 | "saml.onetimeuse.condition": "false" 737 | }, 738 | "authenticationFlowBindingOverrides": {}, 739 | "fullScopeAllowed": true, 740 | "nodeReRegistrationTimeout": -1, 741 | "defaultClientScopes": [ 742 | "audience", 743 | "web-origins", 744 | "role_list", 745 | "profile", 746 | "roles", 747 | "groups", 748 | "email" 749 | ], 750 | "optionalClientScopes": [ 751 | "address", 752 | "phone", 753 | "offline_access", 754 | "microprofile-jwt" 755 | ] 756 | }, 757 | { 758 | "id": "553f5b5f-1598-4170-9cf7-15197458e864", 759 | "clientId": "grafana", 760 | "rootUrl": "https://grafana.godapp.de/", 761 | "adminUrl": "https://grafana.godapp.de/", 762 | "surrogateAuthRequired": false, 763 | "enabled": true, 764 | "alwaysDisplayInConsole": false, 765 | "clientAuthenticatorType": "client-secret", 766 | "secret": "df7d395f-e833-49b6-b19c-eea8a54fb06a", 767 | "redirectUris": [ 768 | "https://grafana.godapp.de/*" 769 | ], 770 | "webOrigins": [ 771 | "https://grafana.godapp.de" 772 | ], 773 | "notBefore": 0, 774 | "bearerOnly": false, 775 | "consentRequired": false, 776 | "standardFlowEnabled": true, 777 | "implicitFlowEnabled": false, 778 | "directAccessGrantsEnabled": true, 779 | "serviceAccountsEnabled": false, 780 | "publicClient": false, 781 | "frontchannelLogout": false, 782 | "protocol": "openid-connect", 783 | "attributes": { 784 | "saml.assertion.signature": "false", 785 | "saml.force.post.binding": "false", 786 | "saml.multivalued.roles": "false", 787 | "saml.encrypt": "false", 788 | "saml.server.signature": "false", 789 | "saml.server.signature.keyinfo.ext": "false", 790 | "exclude.session.state.from.auth.response": "false", 791 | "saml_force_name_id_format": "false", 792 | "saml.client.signature": "false", 793 | "tls.client.certificate.bound.access.tokens": "false", 794 | "saml.authnstatement": "false", 795 | "display.on.consent.screen": "false", 796 | "saml.onetimeuse.condition": "false" 797 | }, 798 | "authenticationFlowBindingOverrides": {}, 799 | "fullScopeAllowed": true, 800 | "nodeReRegistrationTimeout": -1, 801 | "defaultClientScopes": [ 802 | "web-origins", 803 | "role_list", 804 | "profile", 805 | "roles", 806 | "email" 807 | ], 808 | "optionalClientScopes": [ 809 | "address", 810 | "phone", 811 | "offline_access", 812 | "microprofile-jwt" 813 | ] 814 | }, 815 | { 816 | "id": "8ee9c834-055e-4744-be15-6171be211f84", 817 | "clientId": "jenkins", 818 | "rootUrl": "https://jenkins.godapp.de/", 819 | "adminUrl": "https://jenkins.godapp.de/", 820 | "surrogateAuthRequired": false, 821 | "enabled": true, 822 | "alwaysDisplayInConsole": false, 823 | "clientAuthenticatorType": "client-secret", 824 | "secret": "f76f3359-4be2-45dd-aba9-6f5204e62438", 825 | "redirectUris": [ 826 | "https://jenkins.godapp.de/*" 827 | ], 828 | "webOrigins": [ 829 | "https://jenkins.godapp.de" 830 | ], 831 | "notBefore": 0, 832 | "bearerOnly": false, 833 | "consentRequired": false, 834 | "standardFlowEnabled": true, 835 | "implicitFlowEnabled": false, 836 | "directAccessGrantsEnabled": true, 837 | "serviceAccountsEnabled": false, 838 | "publicClient": false, 839 | "frontchannelLogout": false, 840 | "protocol": "openid-connect", 841 | "attributes": { 842 | "saml.assertion.signature": "false", 843 | "saml.force.post.binding": "false", 844 | "saml.multivalued.roles": "false", 845 | "saml.encrypt": "false", 846 | "saml.server.signature": "false", 847 | "saml.server.signature.keyinfo.ext": "false", 848 | "exclude.session.state.from.auth.response": "false", 849 | "saml_force_name_id_format": "false", 850 | "saml.client.signature": "false", 851 | "tls.client.certificate.bound.access.tokens": "false", 852 | "saml.authnstatement": "false", 853 | "display.on.consent.screen": "false", 854 | "saml.onetimeuse.condition": "false" 855 | }, 856 | "authenticationFlowBindingOverrides": {}, 857 | "fullScopeAllowed": true, 858 | "nodeReRegistrationTimeout": -1, 859 | "defaultClientScopes": [ 860 | "web-origins", 861 | "role_list", 862 | "profile", 863 | "roles", 864 | "email" 865 | ], 866 | "optionalClientScopes": [ 867 | "address", 868 | "phone", 869 | "offline_access", 870 | "microprofile-jwt" 871 | ] 872 | }, 873 | { 874 | "id": "459a8f61-0cf3-45ed-a1b3-d1339dd8d16a", 875 | "clientId": "kiali", 876 | "rootUrl": "https://kiali-istio.godapp.de/", 877 | "adminUrl": "https://kiali-istio.godapp.de/", 878 | "surrogateAuthRequired": false, 879 | "enabled": true, 880 | "alwaysDisplayInConsole": false, 881 | "clientAuthenticatorType": "client-secret", 882 | "secret": "746b5179-2b86-4c5c-8b1f-440e893f650b", 883 | "redirectUris": [ 884 | "https://kiali-istio.godapp.de/*" 885 | ], 886 | "webOrigins": [ 887 | "https://kiali-istio.godapp.de" 888 | ], 889 | "notBefore": 0, 890 | "bearerOnly": false, 891 | "consentRequired": false, 892 | "standardFlowEnabled": true, 893 | "implicitFlowEnabled": false, 894 | "directAccessGrantsEnabled": true, 895 | "serviceAccountsEnabled": false, 896 | "publicClient": false, 897 | "frontchannelLogout": false, 898 | "protocol": "openid-connect", 899 | "attributes": { 900 | "saml.assertion.signature": "false", 901 | "saml.force.post.binding": "false", 902 | "saml.multivalued.roles": "false", 903 | "saml.encrypt": "false", 904 | "saml.server.signature": "false", 905 | "saml.server.signature.keyinfo.ext": "false", 906 | "exclude.session.state.from.auth.response": "false", 907 | "saml_force_name_id_format": "false", 908 | "saml.client.signature": "false", 909 | "tls.client.certificate.bound.access.tokens": "false", 910 | "saml.authnstatement": "false", 911 | "display.on.consent.screen": "false", 912 | "saml.onetimeuse.condition": "false" 913 | }, 914 | "authenticationFlowBindingOverrides": {}, 915 | "fullScopeAllowed": true, 916 | "nodeReRegistrationTimeout": -1, 917 | "defaultClientScopes": [ 918 | "audience", 919 | "web-origins", 920 | "role_list", 921 | "profile", 922 | "roles", 923 | "email" 924 | ], 925 | "optionalClientScopes": [ 926 | "address", 927 | "phone", 928 | "offline_access", 929 | "microprofile-jwt" 930 | ] 931 | }, 932 | { 933 | "id": "8312e7b4-d18a-4b54-bf98-67d62ffce042", 934 | "clientId": "sonarqube", 935 | "rootUrl": "https://sonarqube.godapp.de/", 936 | "adminUrl": "https://sonarqube.godapp.de/", 937 | "surrogateAuthRequired": false, 938 | "enabled": true, 939 | "alwaysDisplayInConsole": false, 940 | "clientAuthenticatorType": "client-secret", 941 | "secret": "5ad5e8a7-85f2-44cf-979c-dd8faf53e84c", 942 | "redirectUris": [ 943 | "https://sonarqube.godapp.de/*" 944 | ], 945 | "webOrigins": [ 946 | "https://sonarqube.godapp.de" 947 | ], 948 | "notBefore": 0, 949 | "bearerOnly": false, 950 | "consentRequired": false, 951 | "standardFlowEnabled": true, 952 | "implicitFlowEnabled": false, 953 | "directAccessGrantsEnabled": true, 954 | "serviceAccountsEnabled": false, 955 | "publicClient": true, 956 | "frontchannelLogout": false, 957 | "protocol": "openid-connect", 958 | "attributes": {}, 959 | "authenticationFlowBindingOverrides": {}, 960 | "fullScopeAllowed": true, 961 | "nodeReRegistrationTimeout": -1, 962 | "defaultClientScopes": [ 963 | "web-origins", 964 | "role_list", 965 | "profile", 966 | "roles", 967 | "groups", 968 | "email" 969 | ], 970 | "optionalClientScopes": [ 971 | "address", 972 | "phone", 973 | "offline_access", 974 | "microprofile-jwt" 975 | ] 976 | }, 977 | { 978 | "id": "18a7c215-a6cf-4ac0-8abe-39fb2d5c47a7", 979 | "clientId": "tracing", 980 | "rootUrl": "https://tracing-istio.godapp.de/", 981 | "adminUrl": "https://tracing-istio.godapp.de/", 982 | "surrogateAuthRequired": false, 983 | "enabled": true, 984 | "alwaysDisplayInConsole": false, 985 | "clientAuthenticatorType": "client-secret", 986 | "secret": "0e94208b-1ea1-4e9b-b6e4-3e0b15c9fb9d", 987 | "redirectUris": [ 988 | "https://tracing-istio.godapp.de/*" 989 | ], 990 | "webOrigins": [ 991 | "https://tracing-istio.godapp.de" 992 | ], 993 | "notBefore": 0, 994 | "bearerOnly": false, 995 | "consentRequired": false, 996 | "standardFlowEnabled": true, 997 | "implicitFlowEnabled": false, 998 | "directAccessGrantsEnabled": true, 999 | "serviceAccountsEnabled": false, 1000 | "publicClient": false, 1001 | "frontchannelLogout": false, 1002 | "protocol": "openid-connect", 1003 | "attributes": { 1004 | "saml.assertion.signature": "false", 1005 | "saml.force.post.binding": "false", 1006 | "saml.multivalued.roles": "false", 1007 | "saml.encrypt": "false", 1008 | "saml.server.signature": "false", 1009 | "saml.server.signature.keyinfo.ext": "false", 1010 | "exclude.session.state.from.auth.response": "false", 1011 | "saml_force_name_id_format": "false", 1012 | "saml.client.signature": "false", 1013 | "tls.client.certificate.bound.access.tokens": "false", 1014 | "saml.authnstatement": "false", 1015 | "display.on.consent.screen": "false", 1016 | "saml.onetimeuse.condition": "false" 1017 | }, 1018 | "authenticationFlowBindingOverrides": {}, 1019 | "fullScopeAllowed": true, 1020 | "nodeReRegistrationTimeout": -1, 1021 | "defaultClientScopes": [ 1022 | "audience", 1023 | "web-origins", 1024 | "role_list", 1025 | "profile", 1026 | "roles", 1027 | "email" 1028 | ], 1029 | "optionalClientScopes": [ 1030 | "address", 1031 | "phone", 1032 | "offline_access", 1033 | "microprofile-jwt" 1034 | ] 1035 | }, 1036 | { 1037 | "id": "61b7101e-16c0-4050-a862-c641e0c9e5f3", 1038 | "clientId": "weave-scope", 1039 | "rootUrl": "https://weave-scope.godapp.de/", 1040 | "adminUrl": "https://weave-scope.godapp.de/", 1041 | "surrogateAuthRequired": false, 1042 | "enabled": true, 1043 | "alwaysDisplayInConsole": false, 1044 | "clientAuthenticatorType": "client-secret", 1045 | "secret": "5b93b5c3-2337-4002-962a-c7770c770024", 1046 | "redirectUris": [ 1047 | "https://weave-scope.godapp.de/*" 1048 | ], 1049 | "webOrigins": [ 1050 | "https://weave-scope.godapp.de" 1051 | ], 1052 | "notBefore": 0, 1053 | "bearerOnly": false, 1054 | "consentRequired": false, 1055 | "standardFlowEnabled": true, 1056 | "implicitFlowEnabled": false, 1057 | "directAccessGrantsEnabled": true, 1058 | "serviceAccountsEnabled": false, 1059 | "publicClient": false, 1060 | "frontchannelLogout": false, 1061 | "protocol": "openid-connect", 1062 | "attributes": { 1063 | "saml.assertion.signature": "false", 1064 | "saml.force.post.binding": "false", 1065 | "saml.multivalued.roles": "false", 1066 | "saml.encrypt": "false", 1067 | "saml.server.signature": "false", 1068 | "saml.server.signature.keyinfo.ext": "false", 1069 | "exclude.session.state.from.auth.response": "false", 1070 | "saml_force_name_id_format": "false", 1071 | "saml.client.signature": "false", 1072 | "tls.client.certificate.bound.access.tokens": "false", 1073 | "saml.authnstatement": "false", 1074 | "display.on.consent.screen": "false", 1075 | "saml.onetimeuse.condition": "false" 1076 | }, 1077 | "authenticationFlowBindingOverrides": {}, 1078 | "fullScopeAllowed": true, 1079 | "nodeReRegistrationTimeout": -1, 1080 | "defaultClientScopes": [ 1081 | "audience", 1082 | "web-origins", 1083 | "role_list", 1084 | "profile", 1085 | "roles", 1086 | "email" 1087 | ], 1088 | "optionalClientScopes": [ 1089 | "address", 1090 | "phone", 1091 | "offline_access", 1092 | "microprofile-jwt" 1093 | ] 1094 | }, 1095 | { 1096 | "id": "2b9d5442-db3a-4b6c-8eb3-bfb4b5d7c7c1", 1097 | "clientId": "realm-management", 1098 | "name": "${client_realm-management}", 1099 | "surrogateAuthRequired": false, 1100 | "enabled": true, 1101 | "alwaysDisplayInConsole": false, 1102 | "clientAuthenticatorType": "client-secret", 1103 | "secret": "**********", 1104 | "redirectUris": [], 1105 | "webOrigins": [], 1106 | "notBefore": 0, 1107 | "bearerOnly": true, 1108 | "consentRequired": false, 1109 | "standardFlowEnabled": true, 1110 | "implicitFlowEnabled": false, 1111 | "directAccessGrantsEnabled": false, 1112 | "serviceAccountsEnabled": false, 1113 | "publicClient": false, 1114 | "frontchannelLogout": false, 1115 | "protocol": "openid-connect", 1116 | "attributes": {}, 1117 | "authenticationFlowBindingOverrides": {}, 1118 | "fullScopeAllowed": false, 1119 | "nodeReRegistrationTimeout": 0, 1120 | "defaultClientScopes": [ 1121 | "web-origins", 1122 | "role_list", 1123 | "profile", 1124 | "roles", 1125 | "email" 1126 | ], 1127 | "optionalClientScopes": [ 1128 | "address", 1129 | "phone", 1130 | "offline_access", 1131 | "microprofile-jwt" 1132 | ] 1133 | }, 1134 | { 1135 | "id": "58a0a26c-a210-4a98-856e-7775a631e46e", 1136 | "clientId": "security-admin-console", 1137 | "name": "${client_security-admin-console}", 1138 | "rootUrl": "${authAdminUrl}", 1139 | "baseUrl": "/admin/demo/console/", 1140 | "surrogateAuthRequired": false, 1141 | "enabled": true, 1142 | "alwaysDisplayInConsole": false, 1143 | "clientAuthenticatorType": "client-secret", 1144 | "secret": "**********", 1145 | "redirectUris": [ 1146 | "/admin/demo/console/*" 1147 | ], 1148 | "webOrigins": [ 1149 | "+" 1150 | ], 1151 | "notBefore": 0, 1152 | "bearerOnly": false, 1153 | "consentRequired": false, 1154 | "standardFlowEnabled": true, 1155 | "implicitFlowEnabled": false, 1156 | "directAccessGrantsEnabled": false, 1157 | "serviceAccountsEnabled": false, 1158 | "publicClient": true, 1159 | "frontchannelLogout": false, 1160 | "protocol": "openid-connect", 1161 | "attributes": { 1162 | "pkce.code.challenge.method": "S256" 1163 | }, 1164 | "authenticationFlowBindingOverrides": {}, 1165 | "fullScopeAllowed": false, 1166 | "nodeReRegistrationTimeout": 0, 1167 | "protocolMappers": [ 1168 | { 1169 | "id": "0bac6168-b261-40b0-8608-9c3001a6a380", 1170 | "name": "locale", 1171 | "protocol": "openid-connect", 1172 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1173 | "consentRequired": false, 1174 | "config": { 1175 | "userinfo.token.claim": "true", 1176 | "user.attribute": "locale", 1177 | "id.token.claim": "true", 1178 | "access.token.claim": "true", 1179 | "claim.name": "locale", 1180 | "jsonType.label": "String" 1181 | } 1182 | } 1183 | ], 1184 | "defaultClientScopes": [ 1185 | "web-origins", 1186 | "role_list", 1187 | "profile", 1188 | "roles", 1189 | "email" 1190 | ], 1191 | "optionalClientScopes": [ 1192 | "address", 1193 | "phone", 1194 | "offline_access", 1195 | "microprofile-jwt" 1196 | ] 1197 | } 1198 | ], 1199 | "clientScopes": [ 1200 | { 1201 | "id": "fcff2c7b-f5da-4ccc-9f04-b72d1956842e", 1202 | "name": "groups", 1203 | "protocol": "openid-connect", 1204 | "attributes": { 1205 | "include.in.token.scope": "true", 1206 | "display.on.consent.screen": "true" 1207 | }, 1208 | "protocolMappers": [ 1209 | { 1210 | "id": "6f8703b0-025e-4cb0-a784-664517cb5298", 1211 | "name": "groups", 1212 | "protocol": "openid-connect", 1213 | "protocolMapper": "oidc-group-membership-mapper", 1214 | "consentRequired": false, 1215 | "config": { 1216 | "full.path": "true", 1217 | "id.token.claim": "true", 1218 | "access.token.claim": "true", 1219 | "claim.name": "groups", 1220 | "userinfo.token.claim": "true" 1221 | } 1222 | } 1223 | ] 1224 | }, 1225 | { 1226 | "id": "825a24ec-9255-43ef-be03-2412bb1c3248", 1227 | "name": "audience", 1228 | "protocol": "openid-connect", 1229 | "attributes": { 1230 | "include.in.token.scope": "true", 1231 | "display.on.consent.screen": "true" 1232 | }, 1233 | "protocolMappers": [ 1234 | { 1235 | "id": "7e034760-5fa7-4143-a2b7-c5861c6d958b", 1236 | "name": "argo", 1237 | "protocol": "openid-connect", 1238 | "protocolMapper": "oidc-audience-mapper", 1239 | "consentRequired": false, 1240 | "config": { 1241 | "included.client.audience": "argo", 1242 | "id.token.claim": "false", 1243 | "access.token.claim": "true" 1244 | } 1245 | }, 1246 | { 1247 | "id": "f6663974-4728-4da8-b4c5-491cf51f1914", 1248 | "name": "kiali", 1249 | "protocol": "openid-connect", 1250 | "protocolMapper": "oidc-audience-mapper", 1251 | "consentRequired": false, 1252 | "config": { 1253 | "included.client.audience": "kiali", 1254 | "id.token.claim": "false", 1255 | "access.token.claim": "true" 1256 | } 1257 | }, 1258 | { 1259 | "id": "6011286e-e075-4a7e-af29-21877d4449be", 1260 | "name": "tracing", 1261 | "protocol": "openid-connect", 1262 | "protocolMapper": "oidc-audience-mapper", 1263 | "consentRequired": false, 1264 | "config": { 1265 | "included.client.audience": "tracing", 1266 | "id.token.claim": "false", 1267 | "access.token.claim": "true" 1268 | } 1269 | }, 1270 | { 1271 | "id": "12fe282d-7890-4a0e-ade0-b27b990289a4", 1272 | "name": "weave-scope", 1273 | "protocol": "openid-connect", 1274 | "protocolMapper": "oidc-audience-mapper", 1275 | "consentRequired": false, 1276 | "config": { 1277 | "included.client.audience": "weave-scope", 1278 | "id.token.claim": "false", 1279 | "access.token.claim": "true" 1280 | } 1281 | } 1282 | ] 1283 | }, 1284 | { 1285 | "id": "c15a1710-ec6c-4fbc-9daf-498a3ecf0fce", 1286 | "name": "offline_access", 1287 | "description": "OpenID Connect built-in scope: offline_access", 1288 | "protocol": "openid-connect", 1289 | "attributes": { 1290 | "consent.screen.text": "${offlineAccessScopeConsentText}", 1291 | "display.on.consent.screen": "true" 1292 | } 1293 | }, 1294 | { 1295 | "id": "f7cde8b2-8249-4965-8670-de2039aa7340", 1296 | "name": "role_list", 1297 | "description": "SAML role list", 1298 | "protocol": "saml", 1299 | "attributes": { 1300 | "consent.screen.text": "${samlRoleListScopeConsentText}", 1301 | "display.on.consent.screen": "true" 1302 | }, 1303 | "protocolMappers": [ 1304 | { 1305 | "id": "77948ee9-481e-43cf-b2cc-0529894d62ea", 1306 | "name": "role list", 1307 | "protocol": "saml", 1308 | "protocolMapper": "saml-role-list-mapper", 1309 | "consentRequired": false, 1310 | "config": { 1311 | "single": "false", 1312 | "attribute.nameformat": "Basic", 1313 | "attribute.name": "Role" 1314 | } 1315 | } 1316 | ] 1317 | }, 1318 | { 1319 | "id": "357643e0-6f5d-4e94-ba55-b33c5eaaabaa", 1320 | "name": "profile", 1321 | "description": "OpenID Connect built-in scope: profile", 1322 | "protocol": "openid-connect", 1323 | "attributes": { 1324 | "include.in.token.scope": "true", 1325 | "display.on.consent.screen": "true", 1326 | "consent.screen.text": "${profileScopeConsentText}" 1327 | }, 1328 | "protocolMappers": [ 1329 | { 1330 | "id": "f92a8de9-71aa-4b1d-bde1-ae698f6d4643", 1331 | "name": "updated at", 1332 | "protocol": "openid-connect", 1333 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1334 | "consentRequired": false, 1335 | "config": { 1336 | "userinfo.token.claim": "true", 1337 | "user.attribute": "updatedAt", 1338 | "id.token.claim": "true", 1339 | "access.token.claim": "true", 1340 | "claim.name": "updated_at", 1341 | "jsonType.label": "String" 1342 | } 1343 | }, 1344 | { 1345 | "id": "fee830fe-7089-445e-a1b4-a3346fc6f294", 1346 | "name": "nickname", 1347 | "protocol": "openid-connect", 1348 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1349 | "consentRequired": false, 1350 | "config": { 1351 | "userinfo.token.claim": "true", 1352 | "user.attribute": "nickname", 1353 | "id.token.claim": "true", 1354 | "access.token.claim": "true", 1355 | "claim.name": "nickname", 1356 | "jsonType.label": "String" 1357 | } 1358 | }, 1359 | { 1360 | "id": "0474d9e3-a4c6-4946-98d3-1e70f3534a5c", 1361 | "name": "full name", 1362 | "protocol": "openid-connect", 1363 | "protocolMapper": "oidc-full-name-mapper", 1364 | "consentRequired": false, 1365 | "config": { 1366 | "id.token.claim": "true", 1367 | "access.token.claim": "true", 1368 | "userinfo.token.claim": "true" 1369 | } 1370 | }, 1371 | { 1372 | "id": "0f000924-f1a5-4d43-8c8b-e21fffdc4f33", 1373 | "name": "middle name", 1374 | "protocol": "openid-connect", 1375 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1376 | "consentRequired": false, 1377 | "config": { 1378 | "userinfo.token.claim": "true", 1379 | "user.attribute": "middleName", 1380 | "id.token.claim": "true", 1381 | "access.token.claim": "true", 1382 | "claim.name": "middle_name", 1383 | "jsonType.label": "String" 1384 | } 1385 | }, 1386 | { 1387 | "id": "1cbf860f-edbf-42c0-8812-6ea1c515f8aa", 1388 | "name": "zoneinfo", 1389 | "protocol": "openid-connect", 1390 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1391 | "consentRequired": false, 1392 | "config": { 1393 | "userinfo.token.claim": "true", 1394 | "user.attribute": "zoneinfo", 1395 | "id.token.claim": "true", 1396 | "access.token.claim": "true", 1397 | "claim.name": "zoneinfo", 1398 | "jsonType.label": "String" 1399 | } 1400 | }, 1401 | { 1402 | "id": "879675ff-00f3-4f6a-9081-6700e4ee8b4d", 1403 | "name": "locale", 1404 | "protocol": "openid-connect", 1405 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1406 | "consentRequired": false, 1407 | "config": { 1408 | "userinfo.token.claim": "true", 1409 | "user.attribute": "locale", 1410 | "id.token.claim": "true", 1411 | "access.token.claim": "true", 1412 | "claim.name": "locale", 1413 | "jsonType.label": "String" 1414 | } 1415 | }, 1416 | { 1417 | "id": "679aab94-9daa-4cb1-88be-36854b8c08bf", 1418 | "name": "family name", 1419 | "protocol": "openid-connect", 1420 | "protocolMapper": "oidc-usermodel-property-mapper", 1421 | "consentRequired": false, 1422 | "config": { 1423 | "userinfo.token.claim": "true", 1424 | "user.attribute": "lastName", 1425 | "id.token.claim": "true", 1426 | "access.token.claim": "true", 1427 | "claim.name": "family_name", 1428 | "jsonType.label": "String" 1429 | } 1430 | }, 1431 | { 1432 | "id": "20870ed0-03d6-438a-8e4e-adbd6e2b8bab", 1433 | "name": "given name", 1434 | "protocol": "openid-connect", 1435 | "protocolMapper": "oidc-usermodel-property-mapper", 1436 | "consentRequired": false, 1437 | "config": { 1438 | "userinfo.token.claim": "true", 1439 | "user.attribute": "firstName", 1440 | "id.token.claim": "true", 1441 | "access.token.claim": "true", 1442 | "claim.name": "given_name", 1443 | "jsonType.label": "String" 1444 | } 1445 | }, 1446 | { 1447 | "id": "4b3d0aa4-84d8-450c-b55c-3f2075d37496", 1448 | "name": "profile", 1449 | "protocol": "openid-connect", 1450 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1451 | "consentRequired": false, 1452 | "config": { 1453 | "userinfo.token.claim": "true", 1454 | "user.attribute": "profile", 1455 | "id.token.claim": "true", 1456 | "access.token.claim": "true", 1457 | "claim.name": "profile", 1458 | "jsonType.label": "String" 1459 | } 1460 | }, 1461 | { 1462 | "id": "98958802-0dd1-4216-9886-49f0230ba2a2", 1463 | "name": "website", 1464 | "protocol": "openid-connect", 1465 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1466 | "consentRequired": false, 1467 | "config": { 1468 | "userinfo.token.claim": "true", 1469 | "user.attribute": "website", 1470 | "id.token.claim": "true", 1471 | "access.token.claim": "true", 1472 | "claim.name": "website", 1473 | "jsonType.label": "String" 1474 | } 1475 | }, 1476 | { 1477 | "id": "46ee5510-19db-42ff-99c4-eeb077ec7fc9", 1478 | "name": "username", 1479 | "protocol": "openid-connect", 1480 | "protocolMapper": "oidc-usermodel-property-mapper", 1481 | "consentRequired": false, 1482 | "config": { 1483 | "userinfo.token.claim": "true", 1484 | "user.attribute": "username", 1485 | "id.token.claim": "true", 1486 | "access.token.claim": "true", 1487 | "claim.name": "preferred_username", 1488 | "jsonType.label": "String" 1489 | } 1490 | }, 1491 | { 1492 | "id": "b82ff5cb-7d54-45ac-bb63-85637d1f65f6", 1493 | "name": "gender", 1494 | "protocol": "openid-connect", 1495 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1496 | "consentRequired": false, 1497 | "config": { 1498 | "userinfo.token.claim": "true", 1499 | "user.attribute": "gender", 1500 | "id.token.claim": "true", 1501 | "access.token.claim": "true", 1502 | "claim.name": "gender", 1503 | "jsonType.label": "String" 1504 | } 1505 | }, 1506 | { 1507 | "id": "aed0d266-8eae-40dd-80f0-8593512a35ef", 1508 | "name": "picture", 1509 | "protocol": "openid-connect", 1510 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1511 | "consentRequired": false, 1512 | "config": { 1513 | "userinfo.token.claim": "true", 1514 | "user.attribute": "picture", 1515 | "id.token.claim": "true", 1516 | "access.token.claim": "true", 1517 | "claim.name": "picture", 1518 | "jsonType.label": "String" 1519 | } 1520 | }, 1521 | { 1522 | "id": "b342c494-f88f-468f-95b8-67bc45a2dbe0", 1523 | "name": "birthdate", 1524 | "protocol": "openid-connect", 1525 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1526 | "consentRequired": false, 1527 | "config": { 1528 | "userinfo.token.claim": "true", 1529 | "user.attribute": "birthdate", 1530 | "id.token.claim": "true", 1531 | "access.token.claim": "true", 1532 | "claim.name": "birthdate", 1533 | "jsonType.label": "String" 1534 | } 1535 | } 1536 | ] 1537 | }, 1538 | { 1539 | "id": "7f120e59-15e6-4789-a2a0-8d3c37650b2c", 1540 | "name": "email", 1541 | "description": "OpenID Connect built-in scope: email", 1542 | "protocol": "openid-connect", 1543 | "attributes": { 1544 | "include.in.token.scope": "true", 1545 | "display.on.consent.screen": "true", 1546 | "consent.screen.text": "${emailScopeConsentText}" 1547 | }, 1548 | "protocolMappers": [ 1549 | { 1550 | "id": "8e45e2cd-8619-4885-98c9-3b910b98f8b1", 1551 | "name": "email verified", 1552 | "protocol": "openid-connect", 1553 | "protocolMapper": "oidc-usermodel-property-mapper", 1554 | "consentRequired": false, 1555 | "config": { 1556 | "userinfo.token.claim": "true", 1557 | "user.attribute": "emailVerified", 1558 | "id.token.claim": "true", 1559 | "access.token.claim": "true", 1560 | "claim.name": "email_verified", 1561 | "jsonType.label": "boolean" 1562 | } 1563 | }, 1564 | { 1565 | "id": "a869a5a4-a6f2-4c9d-9e04-0dd11cfc6b16", 1566 | "name": "email", 1567 | "protocol": "openid-connect", 1568 | "protocolMapper": "oidc-usermodel-property-mapper", 1569 | "consentRequired": false, 1570 | "config": { 1571 | "userinfo.token.claim": "true", 1572 | "user.attribute": "email", 1573 | "id.token.claim": "true", 1574 | "access.token.claim": "true", 1575 | "claim.name": "email", 1576 | "jsonType.label": "String" 1577 | } 1578 | } 1579 | ] 1580 | }, 1581 | { 1582 | "id": "7a216895-33f1-4628-94f3-ce821114a059", 1583 | "name": "address", 1584 | "description": "OpenID Connect built-in scope: address", 1585 | "protocol": "openid-connect", 1586 | "attributes": { 1587 | "include.in.token.scope": "true", 1588 | "display.on.consent.screen": "true", 1589 | "consent.screen.text": "${addressScopeConsentText}" 1590 | }, 1591 | "protocolMappers": [ 1592 | { 1593 | "id": "e29df45e-0d0f-4c9a-b3ae-cbc931808f5b", 1594 | "name": "address", 1595 | "protocol": "openid-connect", 1596 | "protocolMapper": "oidc-address-mapper", 1597 | "consentRequired": false, 1598 | "config": { 1599 | "user.attribute.formatted": "formatted", 1600 | "user.attribute.country": "country", 1601 | "user.attribute.postal_code": "postal_code", 1602 | "userinfo.token.claim": "true", 1603 | "user.attribute.street": "street", 1604 | "id.token.claim": "true", 1605 | "user.attribute.region": "region", 1606 | "access.token.claim": "true", 1607 | "user.attribute.locality": "locality" 1608 | } 1609 | } 1610 | ] 1611 | }, 1612 | { 1613 | "id": "0bfea758-c83f-44c3-b7c1-e9530228e13e", 1614 | "name": "phone", 1615 | "description": "OpenID Connect built-in scope: phone", 1616 | "protocol": "openid-connect", 1617 | "attributes": { 1618 | "include.in.token.scope": "true", 1619 | "display.on.consent.screen": "true", 1620 | "consent.screen.text": "${phoneScopeConsentText}" 1621 | }, 1622 | "protocolMappers": [ 1623 | { 1624 | "id": "54830b23-4a56-4c8a-8a41-cd1d767b0d31", 1625 | "name": "phone number", 1626 | "protocol": "openid-connect", 1627 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1628 | "consentRequired": false, 1629 | "config": { 1630 | "userinfo.token.claim": "true", 1631 | "user.attribute": "phoneNumber", 1632 | "id.token.claim": "true", 1633 | "access.token.claim": "true", 1634 | "claim.name": "phone_number", 1635 | "jsonType.label": "String" 1636 | } 1637 | }, 1638 | { 1639 | "id": "9c595416-feb2-45aa-a865-1ac29ee3d257", 1640 | "name": "phone number verified", 1641 | "protocol": "openid-connect", 1642 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1643 | "consentRequired": false, 1644 | "config": { 1645 | "userinfo.token.claim": "true", 1646 | "user.attribute": "phoneNumberVerified", 1647 | "id.token.claim": "true", 1648 | "access.token.claim": "true", 1649 | "claim.name": "phone_number_verified", 1650 | "jsonType.label": "boolean" 1651 | } 1652 | } 1653 | ] 1654 | }, 1655 | { 1656 | "id": "b9b1532c-d30c-4a09-9362-5ca5b1792088", 1657 | "name": "roles", 1658 | "description": "OpenID Connect scope for add user roles to the access token", 1659 | "protocol": "openid-connect", 1660 | "attributes": { 1661 | "include.in.token.scope": "false", 1662 | "display.on.consent.screen": "true", 1663 | "consent.screen.text": "${rolesScopeConsentText}" 1664 | }, 1665 | "protocolMappers": [ 1666 | { 1667 | "id": "d6870e51-6abc-459e-b533-27fb1ad694ef", 1668 | "name": "realm roles", 1669 | "protocol": "openid-connect", 1670 | "protocolMapper": "oidc-usermodel-realm-role-mapper", 1671 | "consentRequired": false, 1672 | "config": { 1673 | "user.attribute": "foo", 1674 | "access.token.claim": "true", 1675 | "claim.name": "realm_access.roles", 1676 | "jsonType.label": "String", 1677 | "multivalued": "true" 1678 | } 1679 | }, 1680 | { 1681 | "id": "7e02d9e2-1f46-4ae2-8966-e46f5ff422de", 1682 | "name": "client roles", 1683 | "protocol": "openid-connect", 1684 | "protocolMapper": "oidc-usermodel-client-role-mapper", 1685 | "consentRequired": false, 1686 | "config": { 1687 | "user.attribute": "foo", 1688 | "access.token.claim": "true", 1689 | "claim.name": "resource_access.${client_id}.roles", 1690 | "jsonType.label": "String", 1691 | "multivalued": "true" 1692 | } 1693 | }, 1694 | { 1695 | "id": "017ca686-8a3c-4378-ae61-79538c1cc81c", 1696 | "name": "audience resolve", 1697 | "protocol": "openid-connect", 1698 | "protocolMapper": "oidc-audience-resolve-mapper", 1699 | "consentRequired": false, 1700 | "config": {} 1701 | } 1702 | ] 1703 | }, 1704 | { 1705 | "id": "b05dacf5-895e-4482-96f1-3c3c1e869c90", 1706 | "name": "web-origins", 1707 | "description": "OpenID Connect scope for add allowed web origins to the access token", 1708 | "protocol": "openid-connect", 1709 | "attributes": { 1710 | "include.in.token.scope": "false", 1711 | "display.on.consent.screen": "false", 1712 | "consent.screen.text": "" 1713 | }, 1714 | "protocolMappers": [ 1715 | { 1716 | "id": "85d5c8c2-593c-413e-9b25-bcc46eabfb71", 1717 | "name": "allowed web origins", 1718 | "protocol": "openid-connect", 1719 | "protocolMapper": "oidc-allowed-origins-mapper", 1720 | "consentRequired": false, 1721 | "config": {} 1722 | } 1723 | ] 1724 | }, 1725 | { 1726 | "id": "55547cec-6aec-4244-898b-c1a059c48380", 1727 | "name": "microprofile-jwt", 1728 | "description": "Microprofile - JWT built-in scope", 1729 | "protocol": "openid-connect", 1730 | "attributes": { 1731 | "include.in.token.scope": "true", 1732 | "display.on.consent.screen": "false" 1733 | }, 1734 | "protocolMappers": [ 1735 | { 1736 | "id": "fd171342-0bc2-47d9-8d75-e5f5f1c682c5", 1737 | "name": "groups", 1738 | "protocol": "openid-connect", 1739 | "protocolMapper": "oidc-usermodel-realm-role-mapper", 1740 | "consentRequired": false, 1741 | "config": { 1742 | "multivalued": "true", 1743 | "userinfo.token.claim": "true", 1744 | "user.attribute": "foo", 1745 | "id.token.claim": "true", 1746 | "access.token.claim": "true", 1747 | "claim.name": "groups", 1748 | "jsonType.label": "String" 1749 | } 1750 | }, 1751 | { 1752 | "id": "8b3cafae-e161-405f-88ff-bee2edcae5e9", 1753 | "name": "upn", 1754 | "protocol": "openid-connect", 1755 | "protocolMapper": "oidc-usermodel-property-mapper", 1756 | "consentRequired": false, 1757 | "config": { 1758 | "userinfo.token.claim": "true", 1759 | "user.attribute": "username", 1760 | "id.token.claim": "true", 1761 | "access.token.claim": "true", 1762 | "claim.name": "upn", 1763 | "jsonType.label": "String" 1764 | } 1765 | } 1766 | ] 1767 | } 1768 | ], 1769 | "defaultDefaultClientScopes": [ 1770 | "role_list", 1771 | "profile", 1772 | "email", 1773 | "roles", 1774 | "web-origins" 1775 | ], 1776 | "defaultOptionalClientScopes": [ 1777 | "offline_access", 1778 | "address", 1779 | "phone", 1780 | "microprofile-jwt" 1781 | ], 1782 | "browserSecurityHeaders": { 1783 | "contentSecurityPolicyReportOnly": "", 1784 | "xContentTypeOptions": "nosniff", 1785 | "xRobotsTag": "none", 1786 | "xFrameOptions": "SAMEORIGIN", 1787 | "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", 1788 | "xXSSProtection": "1; mode=block", 1789 | "strictTransportSecurity": "max-age=31536000; includeSubDomains" 1790 | }, 1791 | "smtpServer": {}, 1792 | "eventsEnabled": false, 1793 | "eventsListeners": [ 1794 | "jboss-logging" 1795 | ], 1796 | "enabledEventTypes": [], 1797 | "adminEventsEnabled": false, 1798 | "adminEventsDetailsEnabled": false, 1799 | "identityProviders": [ 1800 | { 1801 | "alias": "google", 1802 | "internalId": "c31b86b0-dd3a-4941-9cbb-fa32a50b0f62", 1803 | "providerId": "google", 1804 | "enabled": true, 1805 | "updateProfileFirstLoginMode": "on", 1806 | "trustEmail": false, 1807 | "storeToken": false, 1808 | "addReadTokenRoleOnCreate": false, 1809 | "authenticateByDefault": false, 1810 | "linkOnly": false, 1811 | "firstBrokerLoginFlowAlias": "first broker login", 1812 | "config": { 1813 | "hostedDomain": "mz.co.kr", 1814 | "syncMode": "IMPORT", 1815 | "clientSecret": "REPLACEME-REPLACEME", 1816 | "clientId": "REPLACEME-REPLACEME.apps.googleusercontent.com", 1817 | "useJwksUrl": "true" 1818 | } 1819 | } 1820 | ], 1821 | "components": { 1822 | "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ 1823 | { 1824 | "id": "e5f776f9-f571-47c8-a08d-f28d0570b82d", 1825 | "name": "Consent Required", 1826 | "providerId": "consent-required", 1827 | "subType": "anonymous", 1828 | "subComponents": {}, 1829 | "config": {} 1830 | }, 1831 | { 1832 | "id": "670c2797-5f42-46ca-ab00-9b0d7c03955d", 1833 | "name": "Trusted Hosts", 1834 | "providerId": "trusted-hosts", 1835 | "subType": "anonymous", 1836 | "subComponents": {}, 1837 | "config": { 1838 | "host-sending-registration-request-must-match": [ 1839 | "true" 1840 | ], 1841 | "client-uris-must-match": [ 1842 | "true" 1843 | ] 1844 | } 1845 | }, 1846 | { 1847 | "id": "84741ead-95a2-4570-a6ca-7f76b5969a59", 1848 | "name": "Allowed Protocol Mapper Types", 1849 | "providerId": "allowed-protocol-mappers", 1850 | "subType": "authenticated", 1851 | "subComponents": {}, 1852 | "config": { 1853 | "allowed-protocol-mapper-types": [ 1854 | "saml-user-attribute-mapper", 1855 | "oidc-sha256-pairwise-sub-mapper", 1856 | "oidc-usermodel-attribute-mapper", 1857 | "oidc-full-name-mapper", 1858 | "saml-user-property-mapper", 1859 | "saml-role-list-mapper", 1860 | "oidc-address-mapper", 1861 | "oidc-usermodel-property-mapper" 1862 | ] 1863 | } 1864 | }, 1865 | { 1866 | "id": "02fde9b4-3862-4966-a210-c4b440aa19aa", 1867 | "name": "Allowed Client Scopes", 1868 | "providerId": "allowed-client-templates", 1869 | "subType": "authenticated", 1870 | "subComponents": {}, 1871 | "config": { 1872 | "allow-default-scopes": [ 1873 | "true" 1874 | ] 1875 | } 1876 | }, 1877 | { 1878 | "id": "c60e944a-43d5-4cad-924f-7c3809ea8532", 1879 | "name": "Full Scope Disabled", 1880 | "providerId": "scope", 1881 | "subType": "anonymous", 1882 | "subComponents": {}, 1883 | "config": {} 1884 | }, 1885 | { 1886 | "id": "fa750c72-aca7-4e1f-b83c-20e100109579", 1887 | "name": "Max Clients Limit", 1888 | "providerId": "max-clients", 1889 | "subType": "anonymous", 1890 | "subComponents": {}, 1891 | "config": { 1892 | "max-clients": [ 1893 | "200" 1894 | ] 1895 | } 1896 | }, 1897 | { 1898 | "id": "1e50a241-b457-415a-a3ba-b4f532110f93", 1899 | "name": "Allowed Client Scopes", 1900 | "providerId": "allowed-client-templates", 1901 | "subType": "anonymous", 1902 | "subComponents": {}, 1903 | "config": { 1904 | "allow-default-scopes": [ 1905 | "true" 1906 | ] 1907 | } 1908 | }, 1909 | { 1910 | "id": "1f2d1b96-09c6-4252-b789-e4a1ddac300d", 1911 | "name": "Allowed Protocol Mapper Types", 1912 | "providerId": "allowed-protocol-mappers", 1913 | "subType": "anonymous", 1914 | "subComponents": {}, 1915 | "config": { 1916 | "allowed-protocol-mapper-types": [ 1917 | "oidc-full-name-mapper", 1918 | "oidc-sha256-pairwise-sub-mapper", 1919 | "oidc-usermodel-property-mapper", 1920 | "oidc-address-mapper", 1921 | "saml-role-list-mapper", 1922 | "saml-user-property-mapper", 1923 | "oidc-usermodel-attribute-mapper", 1924 | "saml-user-attribute-mapper" 1925 | ] 1926 | } 1927 | } 1928 | ], 1929 | "org.keycloak.keys.KeyProvider": [ 1930 | { 1931 | "id": "96a41e01-417a-4cf5-bfe3-093a7d3a8559", 1932 | "name": "rsa-generated", 1933 | "providerId": "rsa-generated", 1934 | "subComponents": {}, 1935 | "config": { 1936 | "priority": [ 1937 | "100" 1938 | ] 1939 | } 1940 | }, 1941 | { 1942 | "id": "36ec3865-6942-4e1b-9662-3bdfee095e99", 1943 | "name": "aes-generated", 1944 | "providerId": "aes-generated", 1945 | "subComponents": {}, 1946 | "config": { 1947 | "priority": [ 1948 | "100" 1949 | ] 1950 | } 1951 | }, 1952 | { 1953 | "id": "15f66081-923e-4870-bcaf-58dbec4e6134", 1954 | "name": "hmac-generated", 1955 | "providerId": "hmac-generated", 1956 | "subComponents": {}, 1957 | "config": { 1958 | "priority": [ 1959 | "100" 1960 | ], 1961 | "algorithm": [ 1962 | "HS256" 1963 | ] 1964 | } 1965 | } 1966 | ] 1967 | }, 1968 | "internationalizationEnabled": false, 1969 | "supportedLocales": [], 1970 | "authenticationFlows": [ 1971 | { 1972 | "id": "13aafc45-dbc3-47cf-bff8-885d3331ae68", 1973 | "alias": "Account verification options", 1974 | "description": "Method with which to verity the existing account", 1975 | "providerId": "basic-flow", 1976 | "topLevel": false, 1977 | "builtIn": true, 1978 | "authenticationExecutions": [ 1979 | { 1980 | "authenticator": "idp-email-verification", 1981 | "requirement": "ALTERNATIVE", 1982 | "priority": 10, 1983 | "userSetupAllowed": false, 1984 | "autheticatorFlow": false 1985 | }, 1986 | { 1987 | "requirement": "ALTERNATIVE", 1988 | "priority": 20, 1989 | "flowAlias": "Verify Existing Account by Re-authentication", 1990 | "userSetupAllowed": false, 1991 | "autheticatorFlow": true 1992 | } 1993 | ] 1994 | }, 1995 | { 1996 | "id": "a7af6637-d149-454d-ad0a-3500ec0b6787", 1997 | "alias": "Authentication Options", 1998 | "description": "Authentication options.", 1999 | "providerId": "basic-flow", 2000 | "topLevel": false, 2001 | "builtIn": true, 2002 | "authenticationExecutions": [ 2003 | { 2004 | "authenticator": "basic-auth", 2005 | "requirement": "REQUIRED", 2006 | "priority": 10, 2007 | "userSetupAllowed": false, 2008 | "autheticatorFlow": false 2009 | }, 2010 | { 2011 | "authenticator": "basic-auth-otp", 2012 | "requirement": "DISABLED", 2013 | "priority": 20, 2014 | "userSetupAllowed": false, 2015 | "autheticatorFlow": false 2016 | }, 2017 | { 2018 | "authenticator": "auth-spnego", 2019 | "requirement": "DISABLED", 2020 | "priority": 30, 2021 | "userSetupAllowed": false, 2022 | "autheticatorFlow": false 2023 | } 2024 | ] 2025 | }, 2026 | { 2027 | "id": "a4fd7808-f293-4f82-8add-d66af8bb5e7e", 2028 | "alias": "Browser - Conditional OTP", 2029 | "description": "Flow to determine if the OTP is required for the authentication", 2030 | "providerId": "basic-flow", 2031 | "topLevel": false, 2032 | "builtIn": true, 2033 | "authenticationExecutions": [ 2034 | { 2035 | "authenticator": "conditional-user-configured", 2036 | "requirement": "REQUIRED", 2037 | "priority": 10, 2038 | "userSetupAllowed": false, 2039 | "autheticatorFlow": false 2040 | }, 2041 | { 2042 | "authenticator": "auth-otp-form", 2043 | "requirement": "REQUIRED", 2044 | "priority": 20, 2045 | "userSetupAllowed": false, 2046 | "autheticatorFlow": false 2047 | } 2048 | ] 2049 | }, 2050 | { 2051 | "id": "c3d14f70-bab0-47dd-8ed3-6f3c895f6f3b", 2052 | "alias": "Direct Grant - Conditional OTP", 2053 | "description": "Flow to determine if the OTP is required for the authentication", 2054 | "providerId": "basic-flow", 2055 | "topLevel": false, 2056 | "builtIn": true, 2057 | "authenticationExecutions": [ 2058 | { 2059 | "authenticator": "conditional-user-configured", 2060 | "requirement": "REQUIRED", 2061 | "priority": 10, 2062 | "userSetupAllowed": false, 2063 | "autheticatorFlow": false 2064 | }, 2065 | { 2066 | "authenticator": "direct-grant-validate-otp", 2067 | "requirement": "REQUIRED", 2068 | "priority": 20, 2069 | "userSetupAllowed": false, 2070 | "autheticatorFlow": false 2071 | } 2072 | ] 2073 | }, 2074 | { 2075 | "id": "86b8c06f-1892-49e7-88a9-3649f83e7c8f", 2076 | "alias": "First broker login - Conditional OTP", 2077 | "description": "Flow to determine if the OTP is required for the authentication", 2078 | "providerId": "basic-flow", 2079 | "topLevel": false, 2080 | "builtIn": true, 2081 | "authenticationExecutions": [ 2082 | { 2083 | "authenticator": "conditional-user-configured", 2084 | "requirement": "REQUIRED", 2085 | "priority": 10, 2086 | "userSetupAllowed": false, 2087 | "autheticatorFlow": false 2088 | }, 2089 | { 2090 | "authenticator": "auth-otp-form", 2091 | "requirement": "REQUIRED", 2092 | "priority": 20, 2093 | "userSetupAllowed": false, 2094 | "autheticatorFlow": false 2095 | } 2096 | ] 2097 | }, 2098 | { 2099 | "id": "985e7cd5-6e7e-4937-a802-98ca73e24863", 2100 | "alias": "Handle Existing Account", 2101 | "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", 2102 | "providerId": "basic-flow", 2103 | "topLevel": false, 2104 | "builtIn": true, 2105 | "authenticationExecutions": [ 2106 | { 2107 | "authenticator": "idp-confirm-link", 2108 | "requirement": "REQUIRED", 2109 | "priority": 10, 2110 | "userSetupAllowed": false, 2111 | "autheticatorFlow": false 2112 | }, 2113 | { 2114 | "requirement": "REQUIRED", 2115 | "priority": 20, 2116 | "flowAlias": "Account verification options", 2117 | "userSetupAllowed": false, 2118 | "autheticatorFlow": true 2119 | } 2120 | ] 2121 | }, 2122 | { 2123 | "id": "4895660e-e189-479b-ab56-024f16b57084", 2124 | "alias": "Reset - Conditional OTP", 2125 | "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", 2126 | "providerId": "basic-flow", 2127 | "topLevel": false, 2128 | "builtIn": true, 2129 | "authenticationExecutions": [ 2130 | { 2131 | "authenticator": "conditional-user-configured", 2132 | "requirement": "REQUIRED", 2133 | "priority": 10, 2134 | "userSetupAllowed": false, 2135 | "autheticatorFlow": false 2136 | }, 2137 | { 2138 | "authenticator": "reset-otp", 2139 | "requirement": "REQUIRED", 2140 | "priority": 20, 2141 | "userSetupAllowed": false, 2142 | "autheticatorFlow": false 2143 | } 2144 | ] 2145 | }, 2146 | { 2147 | "id": "6d2b66f5-892c-4f1d-a06e-9efb36764512", 2148 | "alias": "User creation or linking", 2149 | "description": "Flow for the existing/non-existing user alternatives", 2150 | "providerId": "basic-flow", 2151 | "topLevel": false, 2152 | "builtIn": true, 2153 | "authenticationExecutions": [ 2154 | { 2155 | "authenticatorConfig": "create unique user config", 2156 | "authenticator": "idp-create-user-if-unique", 2157 | "requirement": "ALTERNATIVE", 2158 | "priority": 10, 2159 | "userSetupAllowed": false, 2160 | "autheticatorFlow": false 2161 | }, 2162 | { 2163 | "requirement": "ALTERNATIVE", 2164 | "priority": 20, 2165 | "flowAlias": "Handle Existing Account", 2166 | "userSetupAllowed": false, 2167 | "autheticatorFlow": true 2168 | } 2169 | ] 2170 | }, 2171 | { 2172 | "id": "2f89d3e4-f81d-43a1-a138-417c05b5f79c", 2173 | "alias": "Verify Existing Account by Re-authentication", 2174 | "description": "Reauthentication of existing account", 2175 | "providerId": "basic-flow", 2176 | "topLevel": false, 2177 | "builtIn": true, 2178 | "authenticationExecutions": [ 2179 | { 2180 | "authenticator": "idp-username-password-form", 2181 | "requirement": "REQUIRED", 2182 | "priority": 10, 2183 | "userSetupAllowed": false, 2184 | "autheticatorFlow": false 2185 | }, 2186 | { 2187 | "requirement": "CONDITIONAL", 2188 | "priority": 20, 2189 | "flowAlias": "First broker login - Conditional OTP", 2190 | "userSetupAllowed": false, 2191 | "autheticatorFlow": true 2192 | } 2193 | ] 2194 | }, 2195 | { 2196 | "id": "c5ec05f5-9019-44e4-abc2-5856edb12e23", 2197 | "alias": "browser", 2198 | "description": "browser based authentication", 2199 | "providerId": "basic-flow", 2200 | "topLevel": true, 2201 | "builtIn": true, 2202 | "authenticationExecutions": [ 2203 | { 2204 | "authenticator": "auth-cookie", 2205 | "requirement": "ALTERNATIVE", 2206 | "priority": 10, 2207 | "userSetupAllowed": false, 2208 | "autheticatorFlow": false 2209 | }, 2210 | { 2211 | "authenticator": "auth-spnego", 2212 | "requirement": "DISABLED", 2213 | "priority": 20, 2214 | "userSetupAllowed": false, 2215 | "autheticatorFlow": false 2216 | }, 2217 | { 2218 | "authenticator": "identity-provider-redirector", 2219 | "requirement": "ALTERNATIVE", 2220 | "priority": 25, 2221 | "userSetupAllowed": false, 2222 | "autheticatorFlow": false 2223 | }, 2224 | { 2225 | "requirement": "ALTERNATIVE", 2226 | "priority": 30, 2227 | "flowAlias": "forms", 2228 | "userSetupAllowed": false, 2229 | "autheticatorFlow": true 2230 | } 2231 | ] 2232 | }, 2233 | { 2234 | "id": "f07ee0da-9fa1-4047-ad0a-6c232eac90ba", 2235 | "alias": "clients", 2236 | "description": "Base authentication for clients", 2237 | "providerId": "client-flow", 2238 | "topLevel": true, 2239 | "builtIn": true, 2240 | "authenticationExecutions": [ 2241 | { 2242 | "authenticator": "client-secret", 2243 | "requirement": "ALTERNATIVE", 2244 | "priority": 10, 2245 | "userSetupAllowed": false, 2246 | "autheticatorFlow": false 2247 | }, 2248 | { 2249 | "authenticator": "client-jwt", 2250 | "requirement": "ALTERNATIVE", 2251 | "priority": 20, 2252 | "userSetupAllowed": false, 2253 | "autheticatorFlow": false 2254 | }, 2255 | { 2256 | "authenticator": "client-secret-jwt", 2257 | "requirement": "ALTERNATIVE", 2258 | "priority": 30, 2259 | "userSetupAllowed": false, 2260 | "autheticatorFlow": false 2261 | }, 2262 | { 2263 | "authenticator": "client-x509", 2264 | "requirement": "ALTERNATIVE", 2265 | "priority": 40, 2266 | "userSetupAllowed": false, 2267 | "autheticatorFlow": false 2268 | } 2269 | ] 2270 | }, 2271 | { 2272 | "id": "02f144da-ce4d-43e9-b062-41769dad22d1", 2273 | "alias": "direct grant", 2274 | "description": "OpenID Connect Resource Owner Grant", 2275 | "providerId": "basic-flow", 2276 | "topLevel": true, 2277 | "builtIn": true, 2278 | "authenticationExecutions": [ 2279 | { 2280 | "authenticator": "direct-grant-validate-username", 2281 | "requirement": "REQUIRED", 2282 | "priority": 10, 2283 | "userSetupAllowed": false, 2284 | "autheticatorFlow": false 2285 | }, 2286 | { 2287 | "authenticator": "direct-grant-validate-password", 2288 | "requirement": "REQUIRED", 2289 | "priority": 20, 2290 | "userSetupAllowed": false, 2291 | "autheticatorFlow": false 2292 | }, 2293 | { 2294 | "requirement": "CONDITIONAL", 2295 | "priority": 30, 2296 | "flowAlias": "Direct Grant - Conditional OTP", 2297 | "userSetupAllowed": false, 2298 | "autheticatorFlow": true 2299 | } 2300 | ] 2301 | }, 2302 | { 2303 | "id": "24b18b70-84df-4e50-aa78-7cb9ccbc5e4a", 2304 | "alias": "docker auth", 2305 | "description": "Used by Docker clients to authenticate against the IDP", 2306 | "providerId": "basic-flow", 2307 | "topLevel": true, 2308 | "builtIn": true, 2309 | "authenticationExecutions": [ 2310 | { 2311 | "authenticator": "docker-http-basic-authenticator", 2312 | "requirement": "REQUIRED", 2313 | "priority": 10, 2314 | "userSetupAllowed": false, 2315 | "autheticatorFlow": false 2316 | } 2317 | ] 2318 | }, 2319 | { 2320 | "id": "cc6e9bad-8e76-4502-9457-4de175970c6a", 2321 | "alias": "first broker login", 2322 | "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", 2323 | "providerId": "basic-flow", 2324 | "topLevel": true, 2325 | "builtIn": true, 2326 | "authenticationExecutions": [ 2327 | { 2328 | "authenticatorConfig": "review profile config", 2329 | "authenticator": "idp-review-profile", 2330 | "requirement": "REQUIRED", 2331 | "priority": 10, 2332 | "userSetupAllowed": false, 2333 | "autheticatorFlow": false 2334 | }, 2335 | { 2336 | "requirement": "REQUIRED", 2337 | "priority": 20, 2338 | "flowAlias": "User creation or linking", 2339 | "userSetupAllowed": false, 2340 | "autheticatorFlow": true 2341 | } 2342 | ] 2343 | }, 2344 | { 2345 | "id": "3785d361-3961-4f00-bb21-a5743812160a", 2346 | "alias": "forms", 2347 | "description": "Username, password, otp and other auth forms.", 2348 | "providerId": "basic-flow", 2349 | "topLevel": false, 2350 | "builtIn": true, 2351 | "authenticationExecutions": [ 2352 | { 2353 | "authenticator": "auth-username-password-form", 2354 | "requirement": "REQUIRED", 2355 | "priority": 10, 2356 | "userSetupAllowed": false, 2357 | "autheticatorFlow": false 2358 | }, 2359 | { 2360 | "requirement": "CONDITIONAL", 2361 | "priority": 20, 2362 | "flowAlias": "Browser - Conditional OTP", 2363 | "userSetupAllowed": false, 2364 | "autheticatorFlow": true 2365 | } 2366 | ] 2367 | }, 2368 | { 2369 | "id": "71f8a03b-24ee-44af-a9a2-3a5b7266d2d5", 2370 | "alias": "http challenge", 2371 | "description": "An authentication flow based on challenge-response HTTP Authentication Schemes", 2372 | "providerId": "basic-flow", 2373 | "topLevel": true, 2374 | "builtIn": true, 2375 | "authenticationExecutions": [ 2376 | { 2377 | "authenticator": "no-cookie-redirect", 2378 | "requirement": "REQUIRED", 2379 | "priority": 10, 2380 | "userSetupAllowed": false, 2381 | "autheticatorFlow": false 2382 | }, 2383 | { 2384 | "requirement": "REQUIRED", 2385 | "priority": 20, 2386 | "flowAlias": "Authentication Options", 2387 | "userSetupAllowed": false, 2388 | "autheticatorFlow": true 2389 | } 2390 | ] 2391 | }, 2392 | { 2393 | "id": "077dadba-a950-4c24-827e-61bc758a422a", 2394 | "alias": "registration", 2395 | "description": "registration flow", 2396 | "providerId": "basic-flow", 2397 | "topLevel": true, 2398 | "builtIn": true, 2399 | "authenticationExecutions": [ 2400 | { 2401 | "authenticator": "registration-page-form", 2402 | "requirement": "REQUIRED", 2403 | "priority": 10, 2404 | "flowAlias": "registration form", 2405 | "userSetupAllowed": false, 2406 | "autheticatorFlow": true 2407 | } 2408 | ] 2409 | }, 2410 | { 2411 | "id": "046b7a75-e976-4b62-8cd0-a87bdc90ff56", 2412 | "alias": "registration form", 2413 | "description": "registration form", 2414 | "providerId": "form-flow", 2415 | "topLevel": false, 2416 | "builtIn": true, 2417 | "authenticationExecutions": [ 2418 | { 2419 | "authenticator": "registration-user-creation", 2420 | "requirement": "REQUIRED", 2421 | "priority": 20, 2422 | "userSetupAllowed": false, 2423 | "autheticatorFlow": false 2424 | }, 2425 | { 2426 | "authenticator": "registration-profile-action", 2427 | "requirement": "REQUIRED", 2428 | "priority": 40, 2429 | "userSetupAllowed": false, 2430 | "autheticatorFlow": false 2431 | }, 2432 | { 2433 | "authenticator": "registration-password-action", 2434 | "requirement": "REQUIRED", 2435 | "priority": 50, 2436 | "userSetupAllowed": false, 2437 | "autheticatorFlow": false 2438 | }, 2439 | { 2440 | "authenticator": "registration-recaptcha-action", 2441 | "requirement": "DISABLED", 2442 | "priority": 60, 2443 | "userSetupAllowed": false, 2444 | "autheticatorFlow": false 2445 | } 2446 | ] 2447 | }, 2448 | { 2449 | "id": "1f4b5953-a0b8-4135-ac2b-d082f6764dfc", 2450 | "alias": "reset credentials", 2451 | "description": "Reset credentials for a user if they forgot their password or something", 2452 | "providerId": "basic-flow", 2453 | "topLevel": true, 2454 | "builtIn": true, 2455 | "authenticationExecutions": [ 2456 | { 2457 | "authenticator": "reset-credentials-choose-user", 2458 | "requirement": "REQUIRED", 2459 | "priority": 10, 2460 | "userSetupAllowed": false, 2461 | "autheticatorFlow": false 2462 | }, 2463 | { 2464 | "authenticator": "reset-credential-email", 2465 | "requirement": "REQUIRED", 2466 | "priority": 20, 2467 | "userSetupAllowed": false, 2468 | "autheticatorFlow": false 2469 | }, 2470 | { 2471 | "authenticator": "reset-password", 2472 | "requirement": "REQUIRED", 2473 | "priority": 30, 2474 | "userSetupAllowed": false, 2475 | "autheticatorFlow": false 2476 | }, 2477 | { 2478 | "requirement": "CONDITIONAL", 2479 | "priority": 40, 2480 | "flowAlias": "Reset - Conditional OTP", 2481 | "userSetupAllowed": false, 2482 | "autheticatorFlow": true 2483 | } 2484 | ] 2485 | }, 2486 | { 2487 | "id": "f44eba44-9168-4937-af32-0c08a4889a36", 2488 | "alias": "saml ecp", 2489 | "description": "SAML ECP Profile Authentication Flow", 2490 | "providerId": "basic-flow", 2491 | "topLevel": true, 2492 | "builtIn": true, 2493 | "authenticationExecutions": [ 2494 | { 2495 | "authenticator": "http-basic-authenticator", 2496 | "requirement": "REQUIRED", 2497 | "priority": 10, 2498 | "userSetupAllowed": false, 2499 | "autheticatorFlow": false 2500 | } 2501 | ] 2502 | } 2503 | ], 2504 | "authenticatorConfig": [ 2505 | { 2506 | "id": "037d693b-f09a-4eb0-b3d7-96a21dfc3f73", 2507 | "alias": "create unique user config", 2508 | "config": { 2509 | "require.password.update.after.registration": "false" 2510 | } 2511 | }, 2512 | { 2513 | "id": "7977ac55-aafc-4d6f-ad36-7a9c9f53ea43", 2514 | "alias": "review profile config", 2515 | "config": { 2516 | "update.profile.on.first.login": "missing" 2517 | } 2518 | } 2519 | ], 2520 | "requiredActions": [ 2521 | { 2522 | "alias": "CONFIGURE_TOTP", 2523 | "name": "Configure OTP", 2524 | "providerId": "CONFIGURE_TOTP", 2525 | "enabled": true, 2526 | "defaultAction": false, 2527 | "priority": 10, 2528 | "config": {} 2529 | }, 2530 | { 2531 | "alias": "terms_and_conditions", 2532 | "name": "Terms and Conditions", 2533 | "providerId": "terms_and_conditions", 2534 | "enabled": false, 2535 | "defaultAction": false, 2536 | "priority": 20, 2537 | "config": {} 2538 | }, 2539 | { 2540 | "alias": "UPDATE_PASSWORD", 2541 | "name": "Update Password", 2542 | "providerId": "UPDATE_PASSWORD", 2543 | "enabled": true, 2544 | "defaultAction": false, 2545 | "priority": 30, 2546 | "config": {} 2547 | }, 2548 | { 2549 | "alias": "UPDATE_PROFILE", 2550 | "name": "Update Profile", 2551 | "providerId": "UPDATE_PROFILE", 2552 | "enabled": true, 2553 | "defaultAction": false, 2554 | "priority": 40, 2555 | "config": {} 2556 | }, 2557 | { 2558 | "alias": "VERIFY_EMAIL", 2559 | "name": "Verify Email", 2560 | "providerId": "VERIFY_EMAIL", 2561 | "enabled": true, 2562 | "defaultAction": false, 2563 | "priority": 50, 2564 | "config": {} 2565 | }, 2566 | { 2567 | "alias": "update_user_locale", 2568 | "name": "Update User Locale", 2569 | "providerId": "update_user_locale", 2570 | "enabled": true, 2571 | "defaultAction": false, 2572 | "priority": 1000, 2573 | "config": {} 2574 | } 2575 | ], 2576 | "browserFlow": "browser", 2577 | "registrationFlow": "registration", 2578 | "directGrantFlow": "direct grant", 2579 | "resetCredentialsFlow": "reset credentials", 2580 | "clientAuthenticationFlow": "clients", 2581 | "dockerAuthenticationFlow": "docker auth", 2582 | "attributes": {}, 2583 | "keycloakVersion": "10.0.0", 2584 | "userManagedAccessAllowed": false 2585 | } -------------------------------------------------------------------------------- /charts/modules/keycloak/variable.tf: -------------------------------------------------------------------------------- 1 | variable "module_depends_on" { 2 | default = [] 3 | } 4 | 5 | variable "codecentric_keycloak_version" { 6 | type = string 7 | description = "Keycloak Version" 8 | } 9 | 10 | variable "domains" { 11 | description = "domain name for ingress" 12 | } -------------------------------------------------------------------------------- /charts/modules/logging/loki/main.tf: -------------------------------------------------------------------------------- 1 | #Loki chart repo 2 | resource "helm_release" "loki-stack" { 3 | 4 | name = "loki" 5 | repository = "https://grafana.github.io/loki/charts" 6 | chart = "loki-stack" 7 | version = "0.38.0" 8 | namespace = "monitor" 9 | 10 | wait = false 11 | 12 | create_namespace = true 13 | 14 | values = [ 15 | file("./modules/logging/loki/values/loki-stack.yaml"), 16 | ] 17 | 18 | depends_on = [ 19 | var.module_depends_on 20 | ] 21 | 22 | } -------------------------------------------------------------------------------- /charts/modules/logging/loki/values/loki-stack.yaml: -------------------------------------------------------------------------------- 1 | loki: 2 | enabled: true 3 | serviceMonitor: 4 | enabled: true 5 | additionalLabels: 6 | release: "prometheus" 7 | 8 | promtail: 9 | enabled: true 10 | 11 | fluent-bit: 12 | enabled: false 13 | 14 | grafana: 15 | enabled: false 16 | sidecar: 17 | datasources: 18 | enabled: true 19 | image: 20 | tag: 6.7.0 21 | 22 | prometheus: 23 | enabled: false -------------------------------------------------------------------------------- /charts/modules/logging/loki/variables.tf: -------------------------------------------------------------------------------- 1 | # For depends_on queqe 2 | variable "module_depends_on" { 3 | default = [] 4 | } -------------------------------------------------------------------------------- /charts/modules/monitoring/main.tf: -------------------------------------------------------------------------------- 1 | # monitor 2 | 3 | resource "helm_release" "grafana" { 4 | repository = "https://charts.helm.sh/stable" 5 | chart = "grafana" 6 | version = var.stable_grafana_version 7 | 8 | namespace = "monitor" 9 | name = "grafana" 10 | 11 | values = [ 12 | file("./modules/monitoring/values/grafana.yaml") 13 | ] 14 | 15 | wait = false 16 | 17 | create_namespace = true 18 | 19 | } 20 | 21 | resource "helm_release" "prometheus-adapter" { 22 | repository = "https://charts.helm.sh/stable" 23 | chart = "prometheus-adapter" 24 | version = var.stable_prometheus_adapter_version 25 | 26 | namespace = "monitor" 27 | name = "prometheus-adapter" 28 | 29 | values = [ 30 | file("./modules/monitoring/values/prometheus-adapter.yaml") 31 | ] 32 | 33 | wait = false 34 | 35 | create_namespace = true 36 | } 37 | 38 | resource "helm_release" "prometheus-operator" { 39 | repository = "https://charts.helm.sh/stable" 40 | chart = "prometheus-operator" 41 | version = var.stable_prometheus_operator_version 42 | 43 | namespace = "monitor" 44 | name = "prometheus-operator" 45 | 46 | values = [ 47 | file("./modules/monitoring/values/prometheus-operator.yaml") 48 | ] 49 | 50 | create_namespace = true 51 | 52 | } 53 | 54 | resource "helm_release" "prometheus-alert-rules" { 55 | repository = "https://charts.helm.sh/incubator" 56 | chart = "raw" 57 | 58 | namespace = "monitor" 59 | name = "prometheus-alert-rules" 60 | 61 | values = [ 62 | file("./modules/monitoring/values/prometheus-alert-rules.yaml") 63 | ] 64 | 65 | wait = false 66 | 67 | create_namespace = true 68 | 69 | depends_on = [ 70 | helm_release.prometheus-operator, 71 | ] 72 | } -------------------------------------------------------------------------------- /charts/modules/monitoring/outpit.tf: -------------------------------------------------------------------------------- 1 | output "prometheus-operator" { 2 | value = helm_release.prometheus-operator 3 | } -------------------------------------------------------------------------------- /charts/modules/monitoring/values/grafana.yaml: -------------------------------------------------------------------------------- 1 | 2 | nameOverride: grafana 3 | 4 | adminUser: "timur_galeev@outlook.com" 5 | 6 | podAnnotations: 7 | cluster-autoscaler.kubernetes.io/safe-to-evict: "false" 8 | 9 | ingress: 10 | enabled: true 11 | annotations: 12 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 13 | kubernetes.io/ingress.class: "nginx" 14 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 15 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 16 | hosts: 17 | - grafana.godapp.de 18 | tls: 19 | - secretName: prometheus-grafana-tls-secret 20 | hosts: 21 | - grafana.godapp.de 22 | 23 | # tolerations: 24 | # - key: node-role 25 | # operator: Equal 26 | # value: devops 27 | # effect: NoSchedule 28 | 29 | # affinity: 30 | # nodeAffinity: 31 | # # requiredDuringSchedulingIgnoredDuringExecution: 32 | # # nodeSelectorTerms: 33 | # # - matchExpressions: 34 | # # - key: node-role 35 | # # operator: In 36 | # # values: 37 | # # - ops 38 | # preferredDuringSchedulingIgnoredDuringExecution: 39 | # - weight: 1 40 | # preference: 41 | # matchExpressions: 42 | # - key: node-role 43 | # operator: In 44 | # values: 45 | # - devops 46 | 47 | grafana.ini: 48 | server: 49 | root_url: "https://grafana.godapp.de/" 50 | auth: 51 | disable_login_form: true 52 | auth.generic_oauth: 53 | enabled: true 54 | client_id: "grafana" 55 | client_secret: "df7d395f-e833-49b6-b19c-eea8a54fb06a" 56 | auth_url: "https://keycloak.godapp.de/auth/realms/demo/protocol/openid-connect/auth" 57 | token_url: "https://keycloak.godapp.de/auth/realms/demo/protocol/openid-connect/token" 58 | api_url: "https://keycloak.godapp.de/auth/realms/demo/protocol/openid-connect/userinfo" 59 | scopes: "openid email profile roles" 60 | allow_sign_up: "true" 61 | 62 | sidecar: 63 | dashboards: 64 | enabled: true 65 | 66 | persistence: 67 | enabled: true 68 | size: 5Gi 69 | 70 | datasources: 71 | datasources.yaml: 72 | apiVersion: 1 73 | datasources: 74 | - name: Prometheus 75 | type: prometheus 76 | url: "http://prometheus-operator-prometheus:9090" 77 | access: proxy 78 | isDefault: true 79 | - name: Loki 80 | type: loki 81 | url: "http://loki:3100/" 82 | access: proxy 83 | isDefault: false 84 | 85 | dashboardProviders: 86 | dashboardproviders.yaml: 87 | apiVersion: 1 88 | providers: 89 | - name: default 90 | orgId: 1 91 | folder: "" 92 | type: file 93 | disableDeletion: false 94 | editable: true 95 | options: 96 | path: /var/lib/grafana/dashboards/default 97 | 98 | dashboards: 99 | default: 100 | # https://grafana.com/grafana/dashboards/ 101 | kube-cluster: 102 | gnetId: 9797 103 | revision: 14 104 | datasource: Prometheus 105 | kube-deployment: 106 | gnetId: 9679 107 | revision: 9 108 | datasource: Prometheus 109 | jenkins-overview: 110 | gnetId: 12444 111 | revision: 1 112 | datasource: Prometheus 113 | jvm-overview: 114 | gnetId: 11526 115 | revision: 8 116 | datasource: Prometheus 117 | k8s-cluster-summary: 118 | gnetId: 8685 119 | revision: 1 120 | datasource: Prometheus 121 | node-exporter: 122 | gnetId: 11074 123 | revision: 2 124 | datasource: Prometheus 125 | nodejs-application: 126 | gnetId: 11159 127 | revision: 1 128 | datasource: Prometheus 129 | nginx-ingress: 130 | url: https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/grafana/dashboards/nginx.json 131 | datasource: Prometheus 132 | argo-cd: 133 | url: https://raw.githubusercontent.com/argoproj/argo-cd/master/examples/dashboard.json 134 | datasource: Prometheus 135 | argo-rollouts: 136 | url: https://raw.githubusercontent.com/argoproj/argo-rollouts/master/examples/dashboard.json 137 | datasource: Prometheus -------------------------------------------------------------------------------- /charts/modules/monitoring/values/prometheus-adapter.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: prometheus-adapter 2 | 3 | prometheus: 4 | url: "http://prometheus-operator-prometheus.monitor.svc" 5 | port: 9090 6 | 7 | rules: 8 | default: true 9 | custom: 10 | - seriesQuery: 'container_network_receive_bytes_total{namespace!="",pod!=""}' 11 | resources: 12 | overrides: 13 | namespace: { resource: "namespace" } 14 | pod: { resource: "pod" } 15 | name: 16 | matches: "^(.*)_total" 17 | as: "${1}" 18 | metricsQuery: "sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)" -------------------------------------------------------------------------------- /charts/modules/monitoring/values/prometheus-alert-rules.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - apiVersion: monitoring.coreos.com/v1 3 | kind: PrometheusRule 4 | metadata: 5 | labels: 6 | role: alert-rules 7 | name: prometheus-alert-rules 8 | spec: 9 | groups: 10 | - name: InstanceCountChanged 11 | rules: 12 | - alert: InstanceCountChanged 13 | expr: count(kube_node_labels{node=~"^.*$"}) - count(kube_node_labels{node=~"^.*$"} offset 2m) != 0 14 | labels: 15 | severity: Warning 16 | cluster: eks-demo 17 | annotations: 18 | summary: "Instance Count Changed" 19 | description: "The number of instances has changed. (delta: {{ $value }})" 20 | 21 | - name: InstanceDown 22 | rules: 23 | - alert: InstanceDown 24 | expr: up{job="kubernetes-nodes"} == 0 25 | labels: 26 | severity: Warning 27 | cluster: eks-demo 28 | annotations: 29 | summary: "Instance Down" 30 | description: "The instance({{ $labels.instance }}) is down." 31 | 32 | - name: HighCpuUsage 33 | rules: 34 | - alert: HighCpuUsage 35 | expr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{job="kubernetes-service-endpoints",mode="idle"}[5m])) * 100) > 70 36 | for: 5m 37 | labels: 38 | severity: Warning 39 | cluster: eks-demo 40 | annotations: 41 | summary: "High CPU Usage(> 70%)" 42 | description: "The CPU usage of the instance({{ $labels.instance }}) has exceeded 70 percent for more than 5 minutes." 43 | 44 | - name: HighMemoryUsage 45 | rules: 46 | - alert: HighMemoryUsage 47 | expr: (node_memory_MemTotal_bytes - node_memory_MemFree_bytes - node_memory_Buffers_bytes - node_memory_Cached_bytes) / node_memory_MemTotal_bytes * 100 > 90 48 | for: 5m 49 | labels: 50 | severity: Warning 51 | cluster: eks-demo 52 | annotations: 53 | summary: "High Memory Usage(> 90%)" 54 | description: "The memory usage of the instance({{ $labels.instance }}) has exceeds 90 percent for more than 5 minutes." 55 | 56 | - name: PodCrashingLooping 57 | rules: 58 | - alert: PodCrashingLooping 59 | expr: round(increase(kube_pod_container_status_restarts_total[30m])) > 0 60 | for: 5m 61 | labels: 62 | severity: Critical 63 | cluster: eks-demo 64 | annotations: 65 | summary: "Pod Crash Looping(> 30m)" 66 | description: "Namespace : {{ $labels.namespace }} Pod : {{ $labels.pod }} -- crash {{ $value }} times" 67 | 68 | - name: KubeNodeNotReady 69 | rules: 70 | - alert: KubeNodeNotReady 71 | expr: kube_node_status_condition{job="kubernetes-service-endpoints",condition="Ready",status="true"} == 0 72 | for: 5m 73 | labels: 74 | severity: Critical 75 | cluster: eks-demo 76 | annotations: 77 | summary: "Kube Node Fail : {{ $labels.condition }}" 78 | description: "Node {{ $labels.node }} is failed. Check node!!" 79 | 80 | - name: AvgResponseTime 81 | rules: 82 | - alert: AvgResponseTime 83 | expr: (sum(rate(nginx_ingress_controller_response_duration_seconds_sum[5m])) by (host) != 0) / (sum(rate(nginx_ingress_controller_response_duration_seconds_count[5m])) by (host) != 0) > 5 84 | for: 5m 85 | labels: 86 | severity: Warning 87 | cluster: eks-demo 88 | annotations: 89 | summary: "Average Response Time(> 5s)" 90 | description: "{{ $labels.host }}'s Average Response Time is over 5sec." 91 | 92 | - name: HPAMaxUsage 93 | rules: 94 | - alert: HPAMaxUsage 95 | expr: (kube_hpa_status_current_replicas) / (kube_hpa_spec_max_replicas != 1) == 1 96 | for: 5m 97 | labels: 98 | severity: Warning 99 | cluster: eks-demo 100 | annotations: 101 | summary: "HPA Max Usage" 102 | description: "{{ $labels.hpa }} is using HPA Max." -------------------------------------------------------------------------------- /charts/modules/monitoring/values/prometheus-operator.yaml: -------------------------------------------------------------------------------- 1 | fullnameOverride: prometheus-operator 2 | 3 | prometheusOperator: 4 | createCustomResource: false 5 | 6 | prometheus: 7 | prometheusSpec: 8 | scrapeInterval: 30s 9 | 10 | 11 | ruleSelector: 12 | matchLabels: 13 | role: alert-rules 14 | 15 | grafana: 16 | enabled: false 17 | 18 | kubeStateMetrics: 19 | enabled: true 20 | 21 | alertmanager: 22 | enabled: true 23 | 24 | # config: 25 | # global: 26 | # resolve_timeout: 5m 27 | # slack_api_url: "https://hooks.slack.com/services/XXXXX/XXXXX/XXXXX" 28 | # route: 29 | # # group_by: ["job"] 30 | # group_wait: 30s 31 | # group_interval: 5m 32 | # repeat_interval: 12h 33 | # # receiver: "slack" 34 | # routes: 35 | # - match: 36 | # alertname: Watchdog 37 | # receiver: "null" 38 | # - match: 39 | # receiver: "slack" 40 | # continue: false 41 | # receivers: 42 | # - name: "null" 43 | # - name: "slack" 44 | # slack_configs: 45 | # - channel: "#kube-alerts" 46 | # send_resolved: false 47 | # color: '{{ if eq .Status "firing" }}danger{{ else }}good{{ end }}' 48 | # title: '[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] Monitoring Event Notification' 49 | # text: >- 50 | # {{ range .Alerts }} 51 | # *Alert:* {{ .Annotations.summary }} - `{{ .Labels.severity }}` 52 | # *Description:* `{{ .Annotations.description }}` 53 | # *Details:* 54 | # {{ range .Labels.SortedPairs }} • *{{ .Name }}:* {{ .Value }} 55 | # {{ end }} 56 | # {{ end }} -------------------------------------------------------------------------------- /charts/modules/monitoring/variables.tf: -------------------------------------------------------------------------------- 1 | variable "domain" { 2 | type = string 3 | description = "Domain name for Extarnal DNS service" 4 | default = "set_domain" 5 | } 6 | 7 | variable "stable_grafana_version" { 8 | type = string 9 | description = "Grafana Version" 10 | } 11 | 12 | variable "stable_prometheus_adapter_version" { 13 | type = string 14 | description = "Prometheus Adapter Version" 15 | } 16 | 17 | variable "stable_prometheus_operator_version" { 18 | type = string 19 | description = "Prometheus Operator Version" 20 | } -------------------------------------------------------------------------------- /charts/modules/repository/main.tf: -------------------------------------------------------------------------------- 1 | resource "helm_release" "chartmuseum" { 2 | count = var.chartmuseum_count ? 1 : 0 3 | repository = "https://charts.helm.sh/stable" 4 | chart = "chartmuseum" 5 | version = var.stable_chartmuseum_version 6 | 7 | namespace = "repository" 8 | name = "chartmuseum" 9 | 10 | values = [ 11 | file("./modules/repository/values/chartmuseum.yaml") 12 | ] 13 | 14 | wait = false 15 | 16 | create_namespace = true 17 | } 18 | 19 | resource "helm_release" "archiva" { 20 | count = var.archiva_version ? 1 : 0 21 | repository = "https://xetus-oss.github.io/helm-charts/" 22 | chart = "xetusoss-archiva" 23 | 24 | namespace = "repository" 25 | name = "archiva" 26 | 27 | values = [ 28 | file("./modules/repository/values/archiva.yaml") 29 | ] 30 | 31 | wait = false 32 | 33 | create_namespace = true 34 | 35 | } 36 | 37 | resource "helm_release" "sonatype-nexus" { 38 | count = var.nexus_count ? 1 : 0 39 | repository = "https://oteemo.github.io/charts" 40 | chart = "sonatype-nexus" 41 | version = var.oteemo_sonatype_nexus_version 42 | 43 | namespace = "repository" 44 | name = "sonatype-nexus" 45 | 46 | values = [ 47 | file("./modules/repository/values/sonatype-nexus.yaml") 48 | ] 49 | 50 | wait = false 51 | 52 | } -------------------------------------------------------------------------------- /charts/modules/repository/values/archiva.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: archiva 2 | 3 | proxy: 4 | enabled: true 5 | hostname: "archiva.godapp.de" 6 | proto: https 7 | pathPrefix: / 8 | 9 | ingress: 10 | enabled: true 11 | annotations: 12 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 13 | ingress.kubernetes.io/proxy-body-size: "0" 14 | kubernetes.io/ingress.class: nginx 15 | nginx.ingress.kubernetes.io/proxy-body-size: "0" 16 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 17 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 18 | tls: 19 | enabled: true 20 | secret: archiva-tls 21 | 22 | persistence: 23 | enabled: true 24 | requestSize: 20Gi -------------------------------------------------------------------------------- /charts/modules/repository/values/chartmuseum.yaml: -------------------------------------------------------------------------------- 1 | fullnameOverride: chartmuseum 2 | 3 | replica: 4 | annotations: 5 | cluster-autoscaler.kubernetes.io/safe-to-evict: "false" 6 | iam.amazonaws.com/role: "eks-worker-bucket" 7 | 8 | env: 9 | open: 10 | DEBUG: false 11 | DISABLE_API: false 12 | DISABLE_METRICS: false 13 | ALLOW_OVERWRITE: true 14 | 15 | STORAGE: "amazon" 16 | STORAGE_AMAZON_BUCKET: "eks-chartmuseum-demo" 17 | STORAGE_AMAZON_PREFIX: "/" 18 | STORAGE_AMAZON_REGION: "eu-central-1" 19 | 20 | ingress: 21 | enabled: true 22 | annotations: 23 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 24 | ingress.kubernetes.io/proxy-body-size: "0" 25 | kubernetes.io/ingress.class: nginx 26 | nginx.ingress.kubernetes.io/proxy-body-size: "0" 27 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 28 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 29 | hosts: 30 | - name: "chartmuseum.godapp.de" 31 | path: / 32 | tls: true 33 | tlsSecret: chartmuseum-tls -------------------------------------------------------------------------------- /charts/modules/repository/values/sonatype-nexus.yaml: -------------------------------------------------------------------------------- 1 | fullnameOverride: sonatype-nexus 2 | 3 | statefulset: 4 | enabled: false 5 | 6 | nexus: 7 | service: 8 | type: ClusterIP 9 | 10 | resources: 11 | requests: 12 | cpu: 1000m 13 | memory: 2Gi 14 | limits: 15 | cpu: 1200m 16 | memory: 3Gi 17 | 18 | podAnnotations: 19 | cluster-autoscaler.kubernetes.io/safe-to-evict: "false" 20 | 21 | livenessProbe: 22 | initialDelaySeconds: 60 23 | periodSeconds: 30 24 | failureThreshold: 12 25 | path: / 26 | readinessProbe: 27 | initialDelaySeconds: 60 28 | periodSeconds: 30 29 | failureThreshold: 12 30 | path: / 31 | 32 | ingress: 33 | enabled: true 34 | annotations: 35 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 36 | ingress.kubernetes.io/proxy-body-size: "0" 37 | kubernetes.io/ingress.class: nginx 38 | nginx.ingress.kubernetes.io/proxy-body-size: "0" 39 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 40 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 41 | tls: 42 | enabled: true 43 | secretName: sonatype-nexus-tls 44 | 45 | nexusProxy: 46 | env: 47 | nexusHttpHost: "nexus.godapp.de" 48 | 49 | nexusBackup: 50 | enabled: false 51 | persistence: 52 | enabled: false 53 | storageClass: default 54 | storageSize: 20Gi 55 | 56 | persistence: 57 | enabled: true 58 | storageSize: 20Gi -------------------------------------------------------------------------------- /charts/modules/repository/variable.tf: -------------------------------------------------------------------------------- 1 | variable "stable_chartmuseum_version" { 2 | type = string 3 | description = "Chartmuseum Version" 4 | } 5 | 6 | variable "oteemo_sonatype_nexus_version" { 7 | type = string 8 | description = "Sonatype Nexus_version Version" 9 | } 10 | 11 | variable "chartmuseum_count" { 12 | default = [] 13 | } 14 | 15 | variable "nexus_count" { 16 | default = [] 17 | } 18 | 19 | variable "archiva_version" { 20 | default = [] 21 | } -------------------------------------------------------------------------------- /charts/modules/sonarqube/main.tf: -------------------------------------------------------------------------------- 1 | resource "helm_release" "sonarqube" { 2 | count = var.sonarqube_count ? 1 : 0 3 | repository = "https://oteemo.github.io/charts" 4 | chart = "sonarqube" 5 | version = var.sonarqube_version 6 | 7 | namespace = "repository" 8 | name = "sonarqube" 9 | 10 | values = [ 11 | file("./modules/sonarqube/values/sonarqube.yaml") 12 | ] 13 | 14 | wait = false 15 | 16 | } -------------------------------------------------------------------------------- /charts/modules/sonarqube/values/sonarqube.yaml: -------------------------------------------------------------------------------- 1 | fullnameOverride: sonarqube 2 | 3 | ingress: 4 | enabled: true 5 | annotations: 6 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 7 | ingress.kubernetes.io/proxy-body-size: "0" 8 | kubernetes.io/ingress.class: nginx 9 | nginx.ingress.kubernetes.io/proxy-body-size: "0" 10 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 11 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 12 | hosts: 13 | - name: "sonarqube.godapp.de" 14 | path: / 15 | tls: 16 | - secretName: sonarqube-tls 17 | hosts: 18 | - "sonarqube.godapp.de" 19 | 20 | annotations: 21 | cluster-autoscaler.kubernetes.io/safe-to-evict: "false" 22 | 23 | plugins: 24 | install: 25 | - "https://github.com/vaulttec/sonar-auth-oidc/releases/download/v2.0.0/sonar-auth-oidc-plugin-2.0.0.jar" 26 | 27 | sonarProperties: 28 | sonar.core.serverBaseURL: "https://sonarqube.godapp.de" 29 | # sonar.forceAuthentication: true 30 | sonar.auth.oidc.enabled: true 31 | sonar.auth.oidc.issuerUri: "https://keycloak.godapp.de/auth/realms/demo" 32 | sonar.auth.oidc.clientId.secured: "sonarqube" 33 | sonar.auth.oidc.clientSecret.secured: "5ad5e8a7-85f2-44cf-979c-dd8faf53e84c" 34 | # sonar.auth.oidc.scopes: "openid email profile" 35 | # sonar.auth.oidc.groupsSync.claimName: "groups" 36 | sonar.lf.enableGravatar: true 37 | 38 | # sonarSecretKey: "settings-encryption-secret" 39 | 40 | resources: 41 | requests: 42 | cpu: 1000m 43 | memory: 2Gi 44 | limits: 45 | cpu: 1200m 46 | memory: 3Gi 47 | 48 | persistence: 49 | enabled: true 50 | size: 20Gi 51 | 52 | postgresql: 53 | enabled: true 54 | persistence: 55 | enabled: true 56 | size: 8Gi -------------------------------------------------------------------------------- /charts/modules/sonarqube/variables.tf: -------------------------------------------------------------------------------- 1 | variable "module_depends_on" { 2 | default = [] 3 | } 4 | 5 | variable "sonarqube_version" { 6 | type = string 7 | description = "Sonarqube Version" 8 | } 9 | 10 | variable "sonarqube_count" { 11 | default = [] 12 | } -------------------------------------------------------------------------------- /charts/modules/weave/main.tf: -------------------------------------------------------------------------------- 1 | # weave-scope 2 | 3 | resource "helm_release" "weave-scope" { 4 | repository = "https://charts.helm.sh/stable" 5 | chart = "weave-scope" 6 | version = var.stable_weave_scope_version 7 | 8 | namespace = "weave" 9 | name = "weave-scope" 10 | 11 | values = [ 12 | file("./modules/weave/values/weave-scope.yaml") 13 | ] 14 | 15 | create_namespace = true 16 | } 17 | 18 | resource "helm_release" "weave-scope-gatekeeper" { 19 | repository = "https://gabibbo97.github.io/charts/" 20 | chart = "keycloak-gatekeeper" 21 | version = var.gabibbo97_keycloak_gatekeeper_version 22 | 23 | namespace = "weave" 24 | name = "weave-scope-gatekeeper" 25 | 26 | values = [ 27 | file("./modules/weave/values/weave-scope-gatekeeper.yaml") 28 | ] 29 | 30 | wait = false 31 | 32 | create_namespace = true 33 | 34 | depends_on = [ 35 | helm_release.weave-scope, 36 | var.module_depends_on 37 | ] 38 | } -------------------------------------------------------------------------------- /charts/modules/weave/values/weave-scope-gatekeeper.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: weave-scope-gatekeeper 2 | 3 | discoveryURL: https://keycloak.godapp.de/auth/realms/demo 4 | 5 | upstreamURL: http://weave-scope-weave-scope.weave.svc.cluster.local:80 6 | 7 | ClientID: weave-scope 8 | ClientSecret: 5b93b5c3-2337-4002-962a-c7770c770024 9 | 10 | ingress: 11 | enabled: true 12 | annotations: 13 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 14 | kubernetes.io/ingress.class: nginx 15 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 16 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 17 | hosts: 18 | - "weave-scope.godapp.de" 19 | tls: 20 | - secretName: weave-scope-tls 21 | hosts: 22 | - "weave-scope.godapp.de" -------------------------------------------------------------------------------- /charts/modules/weave/values/weave-scope.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: weave-scope 2 | 3 | weave-scope-frontend: 4 | ingress: 5 | enabled: false 6 | annotations: 7 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 8 | kubernetes.io/ingress.class: nginx 9 | nginx.ingress.kubernetes.io/ssl-redirect: "true" 10 | nginx.ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0" 11 | paths: 12 | - / 13 | hosts: 14 | - weave-scope.godapp.de 15 | tls: 16 | - secretName: weave-scope-tls 17 | hosts: 18 | - weave-scope.godapp.de -------------------------------------------------------------------------------- /charts/modules/weave/variable.tf: -------------------------------------------------------------------------------- 1 | variable "module_depends_on" { 2 | default = [] 3 | } 4 | 5 | variable "stable_weave_scope_version" { 6 | type = string 7 | description = "Weave Scope Version" 8 | } 9 | 10 | variable "gabibbo97_keycloak_gatekeeper_version" { 11 | type = string 12 | description = "Keycloak Gatekeeper Version" 13 | } -------------------------------------------------------------------------------- /eks-vpc/.terraform-version: -------------------------------------------------------------------------------- 1 | 0.12.29 -------------------------------------------------------------------------------- /eks-vpc/00-variables.tf: -------------------------------------------------------------------------------- 1 | variable "environment" { 2 | description = "Environment" 3 | default = "GOD-EKS" 4 | } 5 | 6 | variable "cluster_name" { 7 | description = "Name of cluster" 8 | default = "GOD-EKS" 9 | } 10 | 11 | variable "aws_region" { 12 | description = "Name the aws region (eu-central-1, us-central-1 and etc.)" 13 | default = "eu-central-1" 14 | } 15 | 16 | ################ VPC 17 | 18 | variable "vpc_cidr" { 19 | description = "CIDR block for VPC" 20 | type = string 21 | default = "10.40.0.0/16" 22 | } 23 | 24 | variable "availability_zones" { 25 | description = "A list of availability zones in which to create subnets" 26 | type = list(string) 27 | default = ["eu-central-1a", "eu-central-1b", "eu-central-1c"] 28 | } 29 | 30 | variable "public_subnets_cidr" { 31 | description = "subnet cidr details defined for private n/w" 32 | type = list(string) 33 | default = ["10.40.10.0/24", "10.40.11.0/24", "10.40.12.0/24"] 34 | } 35 | 36 | 37 | variable "private_subnets_cidr" { 38 | description = "subnet cidr details defined for private n/w" 39 | type = list(string) 40 | default = ["10.40.50.0/24", "10.40.51.0/24", "10.40.52.0/24"] 41 | } 42 | 43 | variable "vpc_enable_nat_gateway" { 44 | description = "Enable NAT gateway for VPC" 45 | type = bool 46 | default = true 47 | } 48 | 49 | ################ EKS 50 | 51 | variable "spot_max_cluster_size" { 52 | type = string 53 | description = "Number of max instances." 54 | default = "5" 55 | } 56 | 57 | variable "spot_min_cluster_size" { 58 | type = string 59 | description = "Number of min instances." 60 | default = "1" 61 | } 62 | 63 | variable "spot_desired_capacity" { 64 | type = string 65 | description = "Number of desired instances." 66 | default = "1" 67 | } 68 | 69 | variable "cluster_version" { 70 | type = string 71 | description = "Cluster version." 72 | default = "1.17" 73 | } 74 | 75 | variable "spot_instance_type" { 76 | type = list(string) 77 | description = "Worker EC2 Instance type" 78 | default = ["t3a.medium", "r5.2xlarge", "r4.2xlarge"] 79 | } 80 | 81 | variable "spot_instance_pools" { 82 | type = string 83 | description = "Number EC2 Instance type" 84 | default = "3" 85 | } 86 | 87 | variable "spot_price" { 88 | type = string 89 | default = "0.20" 90 | } -------------------------------------------------------------------------------- /eks-vpc/01-data.tf: -------------------------------------------------------------------------------- 1 | data "aws_region" "current" {} 2 | 3 | data "aws_caller_identity" "current" {} -------------------------------------------------------------------------------- /eks-vpc/03-locals.tf: -------------------------------------------------------------------------------- 1 | # locals 2 | 3 | locals { 4 | account_id = data.aws_caller_identity.current.account_id 5 | } 6 | 7 | locals { 8 | 9 | map_users = [ 10 | { 11 | userarn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:user/tgaleev" 12 | username = "tgaleev" 13 | groups = ["system:masters"] 14 | } 15 | ] 16 | 17 | map_roles = [] 18 | 19 | map_accounts = [] 20 | } -------------------------------------------------------------------------------- /eks-vpc/04-backend.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.14" 3 | backend "s3" { 4 | bucket = "tfstate-demo-infra" 5 | key = "terraform/states/eks.tfstate" 6 | region = "eu-central-1" 7 | encrypt = true 8 | dynamodb_table = "tfstate_god" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /eks-vpc/05-providers.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = var.aws_region 3 | version = "~>2.66" 4 | } 5 | 6 | provider "random" { 7 | version = "~> 2.1" 8 | } -------------------------------------------------------------------------------- /eks-vpc/10-vpc.tf: -------------------------------------------------------------------------------- 1 | module "vpc" { 2 | source = "./modules/vpc" 3 | environment = var.environment 4 | availability_zones = var.availability_zones 5 | cluster_name = var.cluster_name 6 | 7 | vpc_cidr = var.vpc_cidr 8 | public_subnets_cidr = var.public_subnets_cidr 9 | private_subnets_cidr = var.private_subnets_cidr 10 | 11 | vpc_enable_nat_gateway = var.vpc_enable_nat_gateway 12 | 13 | } -------------------------------------------------------------------------------- /eks-vpc/30-kubernetes.tf: -------------------------------------------------------------------------------- 1 | module "kubernetes" { 2 | source = "./modules/kubernetes" 3 | 4 | environment = var.environment 5 | cluster_name = var.cluster_name 6 | 7 | max_cluster_size = var.spot_max_cluster_size 8 | desired_capacity = var.spot_desired_capacity 9 | min_cluster_size = var.spot_min_cluster_size 10 | 11 | cluster_version = var.cluster_version 12 | 13 | instance_type = var.spot_instance_type 14 | instance_price = var.spot_price 15 | instance_pools = var.spot_instance_pools 16 | 17 | aws_region = data.aws_region.current.name 18 | vpc_id = module.vpc.vpc_id 19 | private_subnets = module.vpc.private_subnets 20 | 21 | map_users = local.map_users 22 | map_roles = local.map_roles 23 | map_accounts = local.map_accounts 24 | } -------------------------------------------------------------------------------- /eks-vpc/40-rds.tf: -------------------------------------------------------------------------------- 1 | # module "rds" { 2 | # source = "./modules/rds" 3 | # environment = var.environment 4 | # cluster_name = var.cluster_name 5 | # vpc_id = module.vpc.vpc_id 6 | 7 | # ### DB settings: 8 | # db_backup_retention = "30" 9 | # instance_class = "db.t2.micro" 10 | # allocated_storage = "5" 11 | # } -------------------------------------------------------------------------------- /eks-vpc/99-output.tf: -------------------------------------------------------------------------------- 1 | output "eks_name" { 2 | value = module.kubernetes.cluster_name 3 | } 4 | 5 | output "region" { 6 | value = var.aws_region 7 | } 8 | 9 | output "vpc_id" { 10 | value = module.vpc.vpc_id 11 | } 12 | -------------------------------------------------------------------------------- /eks-vpc/modules/kubernetes/data.tf: -------------------------------------------------------------------------------- 1 | data "aws_eks_cluster" "cluster" { 2 | name = module.eks.cluster_id 3 | } 4 | 5 | data "aws_eks_cluster_auth" "cluster" { 6 | name = module.eks.cluster_id 7 | } 8 | 9 | data "aws_caller_identity" "current" {} 10 | 11 | data "aws_availability_zones" "available" {} -------------------------------------------------------------------------------- /eks-vpc/modules/kubernetes/irsa.tf: -------------------------------------------------------------------------------- 1 | module "iam_assumable_role_admin" { 2 | source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc" 3 | version = "~> v4.17.0" 4 | create_role = true 5 | role_name = "cluster-autoscaler" 6 | provider_url = replace(module.eks.cluster_oidc_issuer_url, "https://", "") 7 | role_policy_arns = [aws_iam_policy.cluster_autoscaler.arn] 8 | oidc_fully_qualified_subjects = ["system:serviceaccount:kube-system:cluster-autoscaler-aws-cluster-autoscaler"] 9 | 10 | tags = { 11 | Owner = split("/", data.aws_caller_identity.current.arn)[1] 12 | AutoTag_Creator = data.aws_caller_identity.current.arn 13 | Project = "${var.cluster_name}project" 14 | } 15 | } 16 | 17 | resource "aws_iam_policy" "cluster_autoscaler" { 18 | name_prefix = "cluster-autoscaler" 19 | description = "EKS cluster-autoscaler policy for cluster ${module.eks.cluster_id}" 20 | policy = data.aws_iam_policy_document.cluster_autoscaler.json 21 | } 22 | 23 | data "aws_iam_policy_document" "cluster_autoscaler" { 24 | statement { 25 | sid = "clusterAutoscalerAll" 26 | effect = "Allow" 27 | 28 | actions = [ 29 | "autoscaling:DescribeAutoScalingGroups", 30 | "autoscaling:DescribeAutoScalingInstances", 31 | "autoscaling:DescribeLaunchConfigurations", 32 | "autoscaling:DescribeTags", 33 | "ec2:DescribeLaunchTemplateVersions", 34 | ] 35 | 36 | resources = ["*"] 37 | } 38 | 39 | statement { 40 | sid = "clusterAutoscalerOwn" 41 | effect = "Allow" 42 | 43 | actions = [ 44 | "autoscaling:SetDesiredCapacity", 45 | "autoscaling:TerminateInstanceInAutoScalingGroup", 46 | "autoscaling:UpdateAutoScalingGroup", 47 | ] 48 | 49 | resources = ["*"] 50 | 51 | condition { 52 | test = "StringEquals" 53 | variable = "autoscaling:ResourceTag/kubernetes.io/cluster/${module.eks.cluster_id}" 54 | values = ["owned"] 55 | } 56 | 57 | condition { 58 | test = "StringEquals" 59 | variable = "autoscaling:ResourceTag/k8s.io/cluster-autoscaler/enabled" 60 | values = ["true"] 61 | } 62 | } 63 | } 64 | 65 | resource "helm_release" "cluster-autoscaler" { 66 | 67 | repository = "https://charts.helm.sh/stable" 68 | chart = "cluster-autoscaler" 69 | version = "7.3.4" 70 | 71 | namespace = "kube-system" 72 | name = "cluster-autoscaler" 73 | 74 | # values = [ 75 | # file("./modules/kubernetes/values/cluster-autoscaler.yaml") 76 | # ] 77 | 78 | set { 79 | name = "awsRegion" 80 | value = var.aws_region 81 | } 82 | 83 | set { 84 | name = "cloud-provider" 85 | value = "aws" 86 | } 87 | 88 | set { 89 | name = "rbac.create" 90 | value = true 91 | } 92 | 93 | set { 94 | name = "autoDiscovery.enabled" 95 | value = true 96 | } 97 | 98 | set { 99 | name = "autoDiscovery.clusterName" 100 | value = var.cluster_name 101 | } 102 | 103 | set { 104 | name = "rbac.serviceAccountAnnotations.eks\\.amazonaws\\.com/role-arn" 105 | value = module.iam_assumable_role_admin.this_iam_role_arn 106 | } 107 | 108 | wait = false 109 | 110 | depends_on = [ 111 | ] 112 | } 113 | 114 | resource "helm_release" "k8s-spot-termination-handler" { 115 | repository = "https://charts.helm.sh/stable" 116 | chart = "k8s-spot-termination-handler" 117 | version = "1.4.9" 118 | 119 | namespace = "kube-system" 120 | name = "k8s-spot-termination-handler" 121 | 122 | values = [ 123 | file("./modules/kubernetes/values/k8s-spot-termination-handler.yaml") 124 | ] 125 | 126 | set { 127 | name = "clusterName" 128 | value = var.cluster_name 129 | } 130 | 131 | set { 132 | name = "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn" 133 | value = module.iam_assumable_role_admin.this_iam_role_arn 134 | } 135 | 136 | wait = false 137 | } -------------------------------------------------------------------------------- /eks-vpc/modules/kubernetes/main.tf: -------------------------------------------------------------------------------- 1 | module "eks" { 2 | 3 | source = "terraform-aws-modules/eks/aws" 4 | version = "18.15.0" 5 | cluster_name = var.cluster_name 6 | cluster_version = var.cluster_version 7 | subnets = var.private_subnets 8 | vpc_id = var.vpc_id 9 | enable_irsa = true 10 | 11 | map_roles = var.map_roles 12 | map_users = var.map_users 13 | map_accounts = var.map_accounts 14 | 15 | # cluster_endpoint_private_access = true 16 | # cluster_endpoint_public_access = false 17 | cluster_log_retention_in_days = 30 18 | cluster_enabled_log_types = [ 19 | "api", 20 | "audit", 21 | "authenticator", 22 | "controllerManager", 23 | "scheduler" 24 | ] 25 | 26 | write_kubeconfig = true 27 | manage_aws_auth = true 28 | # config_output_path = "./kube/config" 29 | 30 | tags = { 31 | Owner = split("/", data.aws_caller_identity.current.arn)[1] 32 | AutoTag_Creator = data.aws_caller_identity.current.arn 33 | Project = "${var.cluster_name}project" 34 | } 35 | 36 | worker_groups = [ 37 | 38 | ] 39 | 40 | worker_groups_launch_template = [ 41 | { 42 | name = "worker-spot" 43 | override_instance_types = var.instance_type 44 | spot_instance_pools = var.instance_pools 45 | asg_max_size = var.max_cluster_size 46 | asg_min_size = var.min_cluster_size 47 | asg_desired_capacity = var.desired_capacity 48 | suspended_processes = ["AZRebalance"] 49 | root_volume_size = "50" 50 | spot_allocation_strategy = "lowest-price" 51 | # spot_price = var.instance_price 52 | 53 | # Use this to set labels / taints 54 | kubelet_extra_args = "--node-labels=node.kubernetes.io/lifecycle=spot" 55 | 56 | tags = [ 57 | { 58 | "key" = "k8s.io/cluster-autoscaler/enabled" 59 | "propagate_at_launch" = "false" 60 | "value" = "true" 61 | }, 62 | { 63 | "key" = "k8s.io/cluster-autoscaler/${var.cluster_name}" 64 | "propagate_at_launch" = "false" 65 | "value" = "true" 66 | } 67 | ] 68 | } 69 | ] 70 | } 71 | 72 | # This makes it possible to use helm later in the installation. 73 | resource "null_resource" "kubectl_config_provisioner" { 74 | depends_on = [module.eks] 75 | triggers = { 76 | kubectl_config = module.eks.kubeconfig 77 | } 78 | provisioner "local-exec" { 79 | command = <