From ff29fd6988fedfc226ae91219a6d7237e1cacb5a Mon Sep 17 00:00:00 2001 From: Serg Shalavin Date: Wed, 2 Jul 2025 13:57:23 +0200 Subject: [PATCH 1/6] fix: tf s3, aws provider modules version lock --- platform/terraform/modules/cloud_aws/s3.tf | 2 ++ platform/terraform/modules/cloud_aws/versions.tf | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/terraform/modules/cloud_aws/s3.tf b/platform/terraform/modules/cloud_aws/s3.tf index fa58206c..89afaa18 100644 --- a/platform/terraform/modules/cloud_aws/s3.tf +++ b/platform/terraform/modules/cloud_aws/s3.tf @@ -8,6 +8,7 @@ resource "random_string" "random_suffix" { module "artifacts_repository" { source = "terraform-aws-modules/s3-bucket/aws" + version = "4.11.0" bucket = "${local.name}-artifacts-repository-${random_string.random_suffix.id}" acl = "private" @@ -35,6 +36,7 @@ module "artifacts_repository" { module "backups_repository" { source = "terraform-aws-modules/s3-bucket/aws" + version = "4.11.0" bucket = "${local.name}-backups-repository-${random_string.random_suffix.id}" acl = "private" diff --git a/platform/terraform/modules/cloud_aws/versions.tf b/platform/terraform/modules/cloud_aws/versions.tf index aeb892f3..bfc181fb 100644 --- a/platform/terraform/modules/cloud_aws/versions.tf +++ b/platform/terraform/modules/cloud_aws/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 4.47" + version = ">= 4.47, < 6.0" } kubernetes = { source = "hashicorp/kubernetes" From e5c0504988ce0d22a9da2f0c27e0519a8f56a9ed Mon Sep 17 00:00:00 2001 From: Alex Ulyanov Date: Fri, 25 Jul 2025 13:57:50 +0200 Subject: [PATCH 2/6] fix: aws s3 bucket provisioning fails in us-east-1 --- platform/terraform/modules/secrets_vault/secrets.tf | 2 ++ tools/cli/services/cloud/aws/aws_sdk.py | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/platform/terraform/modules/secrets_vault/secrets.tf b/platform/terraform/modules/secrets_vault/secrets.tf index 7e015b14..39feabc9 100644 --- a/platform/terraform/modules/secrets_vault/secrets.tf +++ b/platform/terraform/modules/secrets_vault/secrets.tf @@ -240,6 +240,8 @@ resource "vault_generic_secret" "gitlab_agent_token" { token = var.vcs_k8s_agent_token } ) + + depends_on = [vault_mount.secret] } resource "vault_generic_secret" "perfectscale_secret" { diff --git a/tools/cli/services/cloud/aws/aws_sdk.py b/tools/cli/services/cloud/aws/aws_sdk.py index 550f9ccb..9b1c14d8 100644 --- a/tools/cli/services/cloud/aws/aws_sdk.py +++ b/tools/cli/services/cloud/aws/aws_sdk.py @@ -105,11 +105,13 @@ def create_bucket(self, bucket_name, region=None) -> str: s3_client = self._session_manager.session.client('s3', region_name=region) location = {'LocationConstraint': region} - bucket = s3_client.create_bucket(Bucket=bucket_name, - CreateBucketConfiguration=location) + if region != "us-east-1": + bucket = s3_client.create_bucket(Bucket=bucket_name, CreateBucketConfiguration=location) + else: + bucket = s3_client.create_bucket(Bucket=bucket_name) except ClientError as e: logger.error(e) - return False + raise e return bucket_name def enable_bucket_versioning(self, bucket_name, region=None): From aa3ec60d12a60d33dc567b009747ff3524226220 Mon Sep 17 00:00:00 2001 From: Aleksei Lysenko Date: Wed, 3 Sep 2025 16:24:57 +0200 Subject: [PATCH 3/6] Fix gitlab runners code and pipelines * fix gitlab default repo being master * fix gitlab runners * docs update * fix s3 bucket indent in tf * revert eks module upgrade * rename iac role param * Fix gitlab runners and pipelines * Terraform fmt * Remove commented terraform in branch protection --------- Co-authored-by: Alex Ulyanov --- QUICKSTART.md | 122 ++++++++++++------ .../agents/cc-cluster-agent/config.yaml | 3 - .../core-services/65-gitlab-agent.yaml | 31 ----- .../promote-cwft.yaml | 2 +- .../version-changer-cwft.yaml | 2 +- .../gitlab/gitlab-agent/application.yaml | 52 -------- .../gitlab/gitlab-agent/externalsecret.yaml | 18 --- .../runners/gitlab/gitlab-agent/wait.yaml | 22 ---- .../gitlab/gitlab-runner/application.yaml | 3 +- platform/terraform/hosting_provider/output.tf | 2 +- platform/terraform/modules/cloud_aws/eks.tf | 31 +---- .../terraform/modules/cloud_aws/outputs.tf | 5 - .../terraform/modules/cloud_aws/versions.tf | 2 +- .../modules/secrets_vault/oidc-provider.tf | 6 +- .../modules/secrets_vault/secrets.tf | 52 +++----- .../modules/secrets_vault/variables.tf | 8 +- .../terraform/modules/vcs_github/output.tf | 8 +- .../modules/vcs_github/repository/main.tf | 14 +- .../modules/vcs_github/repository/variable.tf | 4 +- .../modules/vcs_github/runner_group.tf | 6 +- .../terraform/modules/vcs_github/variable.tf | 8 +- .../modules/vcs_github/workload_repos.tf | 2 +- .../terraform/modules/vcs_gitlab/k8s_agent.tf | 30 ----- .../terraform/modules/vcs_gitlab/output.tf | 7 +- .../modules/vcs_gitlab/repository/main.tf | 19 +-- platform/terraform/secrets/main.tf | 1 - platform/terraform/secrets/variable.tf | 6 - platform/terraform/vcs/output.tf | 7 +- tools/cli/commands/README.md | 2 +- tools/cli/commands/destroy.py | 2 - tools/cli/commands/setup.py | 11 +- tools/cli/commands/workload/README.md | 9 +- tools/cli/commands/workload/bootstrap.py | 11 +- tools/cli/commands/workload/create.py | 9 +- tools/cli/commands/workload/delete.py | 6 +- tools/cli/common/const/const.py | 8 +- .../common/utils/optional_services_manager.py | 2 +- tools/cli/services/cloud/aws/aws_manager.py | 2 +- tools/cli/services/platform_gitops.py | 18 ++- .../cli/services/platform_template_manager.py | 9 +- .../cli/services/vcs/git_provider_manager.py | 12 ++ .../cli/services/vcs/github/github_manager.py | 11 ++ .../cli/services/vcs/gitlab/gitlab_manager.py | 13 +- tools/cli/services/wl_template_manager.py | 33 +++-- 44 files changed, 260 insertions(+), 371 deletions(-) delete mode 100644 platform/gitlab/agents/cc-cluster-agent/config.yaml delete mode 100644 platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/65-gitlab-agent.yaml delete mode 100644 platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-agent/application.yaml delete mode 100644 platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-agent/externalsecret.yaml delete mode 100644 platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-agent/wait.yaml delete mode 100644 platform/terraform/modules/vcs_gitlab/k8s_agent.tf diff --git a/QUICKSTART.md b/QUICKSTART.md index ccfb2fb0..ff22464c 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -16,7 +16,7 @@ deploying the application in production, the following platforms are currently s ### Git Providers - GitHub - Supported -- GitLab - Will be added to a future release +- GitLab - Supported - Bitbucket - Will be added to a future release ### Cloud Providers @@ -34,18 +34,18 @@ Before you begin the installation process, ensure you have the following prerequ You should have: 1. A user account for the Git platform you're working with. This account will be used to create and manage repositories, - make commits, manage users, and perform other tasks, such as executing Terraform scripts. For Github, you can create + make commits, manage users, and perform other tasks, such as executing Terraform scripts. For GitHub, you can create one following [this guide](https://docs.github.com/en/get-started/signing-up-for-github/signing-up-for-a-new-github-account) to sign up for a GitHub account. -3. A GitHub Organization. Organizations are used to group repositories, and CGDevX will create a new repo within a +2. A GitHub Organization. Organizations are used to group repositories, and CG DevX will create a new repo within a specific - organization so that it's easy to find and manage later should you decide to stop using CGDevX. you don't have one, + organization so that it's easy to find and manage later should you decide to stop using CG DevX. you don't have one, please follow [this guide](https://docs.github.com/en/organizations/collaborating-with-groups-in-organizations/creating-a-new-organization-from-scratch) to create a new organization from scratch. to create one. The user from step 1 should be part of this organization. -5. A personal access token for the account from step 1. This token will enable CGDevX to take action on the user's +3. A personal access token for the account from step 1. This token will enable CG DevX to take action on the user's behalf, creating and managing repos, and so on. To get a personal access token, also known as a "developer token", please follow the steps as described @@ -56,34 +56,84 @@ You should have: deleting repositories, groups, and other users. To provide permission for these actions, make sure you select the following set of scopes: - - [x] **repo** Full control of private repositories - - [x] **repo:status** Access commit status - - [x] **repo_deployment** Access deployment status - - [x] **public_repo** Access public repositories - - [x] **repo:invite** Access repository invitations - - [x] **security_events** Read and write security events - - [x] **workflow** Update GitHub Action workflows - - [x] **write:packages** Upload packages to GitHub Package Registry - - [x] **read:packages** Download packages from GitHub Package Registry - - [x] **admin:org** Full control of orgs and teams, read and write org projects - - [x] **write:org** Read and write org and team membership, read and write org projects - - [x] **read:org** Read org and team membership, read org projects - - [x] **manage_runners:org** Manage org runners and runner groups - - [x] **admin:public_key** Full control of user public keys - - [x] **write:public_key** Write user public keys - - [x] **read:public_key** Read user public keys - - [x] **admin:repo_hook** Full control of repository hooks - - [x] **write:repo_hook** Write repository hooks - - [x] **read:repo_hook** Read repository hooks - - [x] **admin:org_hook** Full control of organization hooks - - [x] **user** Update ALL user data - - [x] **read:user** Read ALL user profile data - - [x] **user:email** Access user email addresses (read-only) - - [x] **user:follow** Follow and unfollow users - - [x] **delete_repo** Delete repositories - - [x] **admin:ssh_signing_key** Full control of public user SSH signing keys - - [x] **write:ssh_signing_key** Write public user SSH signing keys - - [x] **read:ssh_signing_key** Read public user SSH signing keys +- [x] **repo** Full control of private repositories + - [x] **repo:status** Access commit status + - [x] **repo_deployment** Access deployment status + - [x] **public_repo** Access public repositories + - [x] **repo:invite** Access repository invitations + - [x] **security_events** Read and write security events +- [x] **workflow** Update GitHub Action workflows +- [x] **write:packages** Upload packages to GitHub Package Registry + - [x] **read:packages** Download packages from GitHub Package Registry +- [x] **admin:org** Full control of orgs and teams, read and write org projects + - [x] **write:org** Read and write org and team membership, read and write org projects + - [x] **read:org** Read org and team membership, read org projects + - [x] **manage_runners:org** Manage org runners and runner groups +- [x] **admin:public_key** Full control of user public keys + - [x] **write:public_key** Write user public keys + - [x] **read:public_key** Read user public keys +- [x] **admin:repo_hook** Full control of repository hooks + - [x] **write:repo_hook** Write repository hooks + - [x] **read:repo_hook** Read repository hooks +- [x] **admin:org_hook** Full control of organization hooks +- [x] **user** Update ALL user data + - [x] **read:user** Read ALL user profile data + - [x] **user:email** Access user email addresses (read-only) + - [x] **user:follow** Follow and unfollow users +- [x] **delete_repo** Delete repositories +- [x] **admin:ssh_signing_key** Full control of public user SSH signing keys + - [x] **write:ssh_signing_key** Write public user SSH signing keys + - [x] **read:ssh_signing_key** Read public user SSH signing keys + +### GitLab Setup Requirements + +You should have: + +1. A user account for the Git platform you're working with. This account will be used to create and manage repositories, + make commits, manage users, and perform other tasks, such as executing Terraform scripts. For Github, you can create + one + following [this guide](https://docs.gitlab.com/user/profile/account/create_accounts/#create-a-user-on-the-sign-in-page) + to sign up for a GitHub account. +2. A GitLab Organization. Organizations are used to group repositories, and CG DevX will create a new repo within a + specific + organization so that it's easy to find and manage later should you decide to stop using CG DevX. you don't have one, + please + follow [this guide](https://docs.gitlab.com/user/organization/#create-an-organization) + to create a new organization from scratch. + to create one. The user from step 1 should have access to this organization. +3. A personal access token for the account from step 1. This token will enable CG DevX to take action on the user's + behalf, + creating and managing repos, and so on. To get a personal access token, also known as a "developer token", please + follow the steps as described + in [this guide](https://docs.gitlab.com/user/profile/personal_access_tokens/#create-a-personal-access-token) + to managing personal access tokens. + + The GitLab token will be used to authenticate with the GitLab API and perform various actions such as creating and + deleting repositories, groups, and other users. To provide permission for these actions, make sure you select the + following set of scopes: + +- [ ] **read_user**: Grants read-only access to your profile through the /user API endpoint, which includes username, + public email, and full name. Also grants access to read-only API endpoints under /users. +- [ ] **read_repository**: Grants read-only access to repositories on private projects using Git-over-HTTP or the + Repository Files API. +- [ ] **read_virtual_registry**: Grants read-only access to container images through the dependency proxy in private + projects and virtual registries. +- [ ] **read_registry**: Grants read-only access to container registry images on private projects. +- [ ] **read_api**: Grants read access to the API, including all groups and projects, the container registry, and the + package registry. +- [ ] **self_rotate**: Grants permission for token to rotate itself. +- [ ] **write_repository**: Grants read-write access to repositories on private projects using Git-over-HTTP (not using + the API). +- [ ] **write_virtual_registry**: Grants read, write, and delete access to container images through the dependency proxy + in private projects. +- [ ] **write_registry**: Grants write access to container registry images on private projects. You need both read and + write access to push images. +- [x] **api**: Grants complete read/write access to the API, including all groups and projects, the container registry, + the dependency proxy, and the package registry. +- [ ] **ai_features**: Grants access to GitLab Duo related API endpoints. +- [ ] **create_runner**: Grants create access to the runners. +- [ ] **manage_runner**: Grants access to manage the runners. +- [ ] **k8s_proxy**: Grants permission to perform Kubernetes API calls using the agent for Kubernetes. ### Cloud account @@ -102,7 +152,7 @@ Before deploying to AWS, ensure that you have: to set up an IAM account, and [this guide](https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html) to grant it `AdministratorAccess`. -4. The security credentials for this account, which enables CGDevX to use it. +4. The security credentials for this account, which enables CG DevX to use it. Use [this guide](https://docs.aws.amazon.com/IAM/latest/UserGuide/security-creds.html#access-keys-and-secret-access-keys) to get your access keys. @@ -115,7 +165,7 @@ Before deploying to AWS, ensure that you have: Before deploying to Azure, ensure that you have: 1. An Azure account with billing enabled. Subscription ID will be used - as cloud-profile during setup. + as cloud-profile during setup. (Remember, deploying clusters will incur charges. Make sure to destroy resources when you're finished with them!) 2. A public DNS zone hosted in Azure DNS. @@ -155,7 +205,7 @@ Before deploying to Google Compute Platform, ensure that you have: ## Installation process -Once you have the prerequisites installed and configured, you are ready to install the CGDevX CLI. +Once you have the prerequisites installed and configured, you are ready to install the CG DevX CLI. Follow the instructions in the [CLI tool readme](tools/README.md). Once installed the CLI, diff --git a/platform/gitlab/agents/cc-cluster-agent/config.yaml b/platform/gitlab/agents/cc-cluster-agent/config.yaml deleted file mode 100644 index 6eb07399..00000000 --- a/platform/gitlab/agents/cc-cluster-agent/config.yaml +++ /dev/null @@ -1,3 +0,0 @@ -ci_access: - groups: - - id: diff --git a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/65-gitlab-agent.yaml b/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/65-gitlab-agent.yaml deleted file mode 100644 index 876c5d64..00000000 --- a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/65-gitlab-agent.yaml +++ /dev/null @@ -1,31 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: gitlab-agent-components - namespace: argocd - annotations: - argocd.argoproj.io/sync-wave: '65' -spec: - project: core - source: - repoURL: - path: gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-agent - targetRevision: HEAD - destination: - server: https://kubernetes.default.svc - namespace: gitlab-agent - syncPolicy: - automated: - prune: true - selfHeal: true - syncOptions: - - CreateNamespace=true - - ApplyOutOfSyncOnly=true - - Replace=true - - PruneLast=true - retry: - limit: 5 - backoff: - duration: 5s - maxDuration: 5m0s - factor: 2 diff --git a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/argo-workflows/cluster-workflow-templates/promote-cwft.yaml b/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/argo-workflows/cluster-workflow-templates/promote-cwft.yaml index 9fc48634..c74122cb 100644 --- a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/argo-workflows/cluster-workflow-templates/promote-cwft.yaml +++ b/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/argo-workflows/cluster-workflow-templates/promote-cwft.yaml @@ -45,7 +45,7 @@ spec: [[ $PROMOTE_SETTINGS == 'true' ]] && cp -v "${ENV_PATH}/${SOURCE_ENV}/settings.yaml" "${ENV_PATH}/${TARGET_ENV}" [[ $PROMOTE_CONFIGMAPS == 'true' ]] && cp -v "${ENV_PATH}/${SOURCE_ENV}/cm.yaml" "${ENV_PATH}/${TARGET_ENV}" mkdir ~/.ssh - ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts + ssh-keyscan -t rsa >> ~/.ssh/known_hosts cp /etc/ssh-key/SSH_PRIVATE_KEY ~/.ssh/id_rsa ssh-keygen -f ~/.ssh/id_rsa -y > ~/.ssh/id_rsa.pub git config --global user.email "" diff --git a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/argo-workflows/cluster-workflow-templates/version-changer-cwft.yaml b/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/argo-workflows/cluster-workflow-templates/version-changer-cwft.yaml index 0e9bb66d..d6a964ea 100644 --- a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/argo-workflows/cluster-workflow-templates/version-changer-cwft.yaml +++ b/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/argo-workflows/cluster-workflow-templates/version-changer-cwft.yaml @@ -48,7 +48,7 @@ spec: done cat version.yaml mkdir ~/.ssh - ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts + ssh-keyscan -t rsa >> ~/.ssh/known_hosts cp /etc/ssh-key/SSH_PRIVATE_KEY ~/.ssh/id_rsa ssh-keygen -f ~/.ssh/id_rsa -y > ~/.ssh/id_rsa.pub ls -l ~/.ssh diff --git a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-agent/application.yaml b/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-agent/application.yaml deleted file mode 100644 index 64ea8f20..00000000 --- a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-agent/application.yaml +++ /dev/null @@ -1,52 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: gitlab-agent - namespace: argocd - finalizers: - - resources-finalizer.argocd.argoproj.io - annotations: - argocd.argoproj.io/sync-wave: '10' -spec: - destination: - server: https://kubernetes.default.svc - namespace: gitlab-agent - project: default - source: - repoURL: 'https://charts.gitlab.io/' - targetRevision: v2.11.0 - helm: - values: |- - serviceAccount: - name: gitlab-agent - config: - kasAddress: wss://kas.gitlab.com - secretName: gitlab-agent - additionalLabels: - cg-devx.cost-allocation.cost-center: platform - cg-devx.metadata.owner: -admin - cg-devx.metadata.service: vsc.runner - cg-devx.metadata.chart-version: v2.11.0 - cg-devx.metadata.version: 0.27.6 - chart: gitlab-agent - syncPolicy: - automated: - prune: true - selfHeal: true - syncOptions: - - CreateNamespace=true ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: gitlab-agent-argo-workflows-admin - annotations: - argocd.argoproj.io/sync-wave: '2' -subjects: - - kind: ServiceAccount - name: gitlab-agent - namespace: gitlab-agent -roleRef: - kind: ClusterRole - name: argo-admin - apiGroup: rbac.authorization.k8s.io diff --git a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-agent/externalsecret.yaml b/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-agent/externalsecret.yaml deleted file mode 100644 index 7b3ac62a..00000000 --- a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-agent/externalsecret.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: 'external-secrets.io/v1beta1' -kind: ExternalSecret -metadata: - name: gitlab-agent - annotations: - argocd.argoproj.io/sync-wave: '0' -spec: - target: - name: gitlab-agent - secretStoreRef: - kind: ClusterSecretStore - name: vault-kv-secret - refreshInterval: 10s - data: - - remoteRef: - key: gitlab-agent - property: token - secretKey: token diff --git a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-agent/wait.yaml b/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-agent/wait.yaml deleted file mode 100644 index 5d21d1f0..00000000 --- a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-agent/wait.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: batch/v1 -kind: Job -metadata: - name: gitlab-agent-wait - namespace: argocd - annotations: - argocd.argoproj.io/sync-wave: '20' -spec: - template: - spec: - serviceAccountName: argocd-server - containers: - - name: gitlab-agent-wait - image: argoproj/argocd:v2.4.2 - command: - - /bin/sh - - -c - - | - argocd login argocd.argocd-server.svc.cluster.local --core - argocd app wait gitlab-agent - restartPolicy: Never - backoffLimit: 1 diff --git a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-runner/application.yaml b/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-runner/application.yaml index ead3bb8c..1664f56a 100644 --- a/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-runner/application.yaml +++ b/platform/gitops-pipelines/delivery/clusters/cc-cluster/core-services/components/runners/gitlab/gitlab-runner/application.yaml @@ -33,7 +33,8 @@ spec: [[runners]] [runners.kubernetes] image = "ubuntu:24.04" - privileged = true + privileged = false + service_account = "gitlab-runner" [[runners.kubernetes.volumes.empty_dir]] name = "docker-certs" mount_path = "/certs/client" diff --git a/platform/terraform/hosting_provider/output.tf b/platform/terraform/hosting_provider/output.tf index 36de52f3..14630791 100644 --- a/platform/terraform/hosting_provider/output.tf +++ b/platform/terraform/hosting_provider/output.tf @@ -9,7 +9,7 @@ output "network_id" { ################################################################################ # IAM roles ################################################################################ -output "iam_ci_role" { +output "ci_role" { value = module.hosting-provider.iam_ci_irsa_role description = "Continuous Integration IAM role for K8s service account" } diff --git a/platform/terraform/modules/cloud_aws/eks.tf b/platform/terraform/modules/cloud_aws/eks.tf index 22293e3e..3cad83ac 100644 --- a/platform/terraform/modules/cloud_aws/eks.tf +++ b/platform/terraform/modules/cloud_aws/eks.tf @@ -53,7 +53,7 @@ module "eks" { create_aws_auth_configmap = (local.node_group_type == "SELF") ? true : false manage_aws_auth_configmap = (local.node_group_type == "SELF") ? true : false - # + create_node_security_group = false eks_managed_node_group_defaults = { # ami_type = "AL2_x86_64" @@ -66,33 +66,6 @@ module "eks" { } eks_managed_node_groups = (local.node_group_type == "EKS") ? local.eks_node_groups : [] - - # - self_managed_node_group_defaults = { - # enable discovery of autoscaling groups by cluster-autoscaler - autoscaling_group_tags = { - "k8s.io/cluster-autoscaler/enabled" : true, - "k8s.io/cluster-autoscaler/${local.name}" : "owned", - } - subnet_ids = module.vpc.private_subnets - launch_template_os = "amazonlinux2eks" - k8s_taints = [{ key = "ondemandInstance", value = "true", effect = "NO_SCHEDULE" }] - # - create_iam_role = true - iam_role_name = "${local.name}-sm-ng-iam-role" - iam_role_use_name_prefix = true - iam_role_description = "Def role" - iam_role_tags = { - Purpose = "Protector of the kubelet" - } - capacity_rebalance = true - node_group_name = "${local.name}-node-group" - launch_template_name = "${local.name}-lt-def" - - } - #Still commented out for the safety of stable version - #self_managed_node_groups = local.node_groups - } # key-pair for custom launch template @@ -104,4 +77,4 @@ module "eks" { #resource "aws_launch_template" "eks_node_with_keypair" { # instance_type = coalesce(first(local.eks_node_groups[0].instance_types), "t3.medium") # key_name = aws_key_pair.eks_nodes.key_name -#} \ No newline at end of file +#} diff --git a/platform/terraform/modules/cloud_aws/outputs.tf b/platform/terraform/modules/cloud_aws/outputs.tf index 7f4aa5f8..9b9341d6 100644 --- a/platform/terraform/modules/cloud_aws/outputs.tf +++ b/platform/terraform/modules/cloud_aws/outputs.tf @@ -272,11 +272,6 @@ output "eks_managed_node_groups_autoscaling_group_names" { ################################################################################ # Additional ################################################################################ - -output "aws_auth_configmap_yaml" { - description = "Formatted yaml output for base aws-auth configmap containing roles used in cluster node groups/fargate profiles" - value = module.eks.aws_auth_configmap_yaml -} output "igw_arn" { description = "IGW ARN Generated by VPC module" value = module.vpc.igw_arn diff --git a/platform/terraform/modules/cloud_aws/versions.tf b/platform/terraform/modules/cloud_aws/versions.tf index bfc181fb..b24dbb47 100644 --- a/platform/terraform/modules/cloud_aws/versions.tf +++ b/platform/terraform/modules/cloud_aws/versions.tf @@ -1,5 +1,5 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.5, < 2.0" required_providers { aws = { diff --git a/platform/terraform/modules/secrets_vault/oidc-provider.tf b/platform/terraform/modules/secrets_vault/oidc-provider.tf index 946eedf7..bc7db962 100644 --- a/platform/terraform/modules/secrets_vault/oidc-provider.tf +++ b/platform/terraform/modules/secrets_vault/oidc-provider.tf @@ -5,9 +5,9 @@ resource "vault_identity_oidc_key" "key" { } resource "vault_identity_oidc_provider" "cgdevx" { - name = "cgdevx" - https_enabled = true - issuer_host = "" + name = "cgdevx" + https_enabled = true + issuer_host = "" allowed_client_ids = [ "*" # todo make explicit list of client ids ] diff --git a/platform/terraform/modules/secrets_vault/secrets.tf b/platform/terraform/modules/secrets_vault/secrets.tf index 39feabc9..8456d7ee 100644 --- a/platform/terraform/modules/secrets_vault/secrets.tf +++ b/platform/terraform/modules/secrets_vault/secrets.tf @@ -1,19 +1,19 @@ locals { - b64_docker_auth = base64encode("robot@main-robot:${random_password.harbor_main_robot_password.result}") + b64_docker_auth = base64encode("robot@main-robot:${random_password.harbor_main_robot_password.result}") harbor_admin_user = "admin" grafana_admin_user = "admin" atlantis_admin_user = "admin" sonarqube_admin_user = "admin" - image_registry_auth = tomap({ for key, value in var.image_registry_auth == null ? {} : var.image_registry_auth: key => {"auth": base64encode("${value.login}:${value.token}") } }) + image_registry_auth = tomap({ for key, value in var.image_registry_auth == null ? {} : var.image_registry_auth : key => { "auth" : base64encode("${value.login}:${value.token}") } }) } resource "vault_generic_secret" "docker_config" { - path = "secret/dockerconfigjson" + path = "secret/dockerconfigjson" data_json = jsonencode( { dockerconfig = jsonencode({ "auths" : merge( - { "" : { "auth" : "${local.b64_docker_auth}" }}, + { "" : { "auth" : "${local.b64_docker_auth}" } }, local.image_registry_auth) }) } @@ -41,7 +41,7 @@ resource "vault_generic_secret" "cd_secrets" { data_json = jsonencode( { - cd_webhook_secret = var.cd_webhook_secret, + cd_webhook_secret = var.cd_webhook_secret, } ) @@ -56,7 +56,7 @@ resource "vault_generic_secret" "atlantis_secrets" { data_json = jsonencode( { - ARGO_SERVER_URL = "argo.argo.svc.cluster.local:2746", + ARGO_SERVER_URL = "argo.argo.svc.cluster.local:2746", # TF_VAR_atlantis_repo_webhook_secret = var.atlantis_repo_webhook_secret, TF_VAR_atlantis_repo_webhook_url = var.atlantis_repo_webhook_url, @@ -65,23 +65,23 @@ resource "vault_generic_secret" "atlantis_secrets" { TF_VAR_tf_backend_storage_access_key = var.tf_backend_storage_access_key, TF_VAR_cluster_ssh_public_key = var.cluster_ssh_public_key, # - TF_VAR_hosted_zone_name = "", - TF_VAR_vcs_bot_ssh_public_key = var.vcs_bot_ssh_public_key, - TF_VAR_vcs_bot_ssh_private_key = var.vcs_bot_ssh_private_key, + TF_VAR_hosted_zone_name = "", + TF_VAR_vcs_bot_ssh_public_key = var.vcs_bot_ssh_public_key, + TF_VAR_vcs_bot_ssh_private_key = var.vcs_bot_ssh_private_key, # harbor specific section - TF_VAR_registry_oidc_client_id = module.harbor.vault_oidc_client_id, - TF_VAR_registry_oidc_client_secret = module.harbor.vault_oidc_client_secret, - TF_VAR_registry_main_robot_password = random_password.harbor_main_robot_password.result, - HARBOR_URL = "https://", - HARBOR_USERNAME = local.harbor_admin_user, - HARBOR_PASSWORD = random_password.harbor_password.result, + TF_VAR_registry_oidc_client_id = module.harbor.vault_oidc_client_id, + TF_VAR_registry_oidc_client_secret = module.harbor.vault_oidc_client_secret, + TF_VAR_registry_main_robot_password = random_password.harbor_main_robot_password.result, + HARBOR_URL = "https://", + HARBOR_USERNAME = local.harbor_admin_user, + HARBOR_PASSWORD = random_password.harbor_password.result, # ---- # vault specific section - TF_VAR_vault_addr = "http://vault.vault.svc.cluster.local:8200/", - TF_VAR_vault_token = var.vault_token, - VAULT_ADDR = "http://vault.vault.svc.cluster.local:8200/", - VAULT_TOKEN = var.vault_token, + TF_VAR_vault_addr = "http://vault.vault.svc.cluster.local:8200/", + TF_VAR_vault_token = var.vault_token, + VAULT_ADDR = "http://vault.vault.svc.cluster.local:8200/", + VAULT_TOKEN = var.vault_token, # code quality specific section TF_VAR_code_quality_oidc_client_id = module.sonarqube.vault_oidc_client_id, TF_VAR_code_quality_oidc_client_secret = module.sonarqube.vault_oidc_client_secret, @@ -232,24 +232,12 @@ resource "vault_generic_secret" "runner_token" { depends_on = [vault_mount.secret] } -resource "vault_generic_secret" "gitlab_agent_token" { - path = "secret/gitlab-agent" - - data_json = jsonencode( - { - token = var.vcs_k8s_agent_token - } - ) - - depends_on = [vault_mount.secret] -} - resource "vault_generic_secret" "perfectscale_secret" { path = "secret/perfectscale-secret" data_json = jsonencode( { - clientId = "", + clientId = "", clientSecret = "", } ) diff --git a/platform/terraform/modules/secrets_vault/variables.tf b/platform/terraform/modules/secrets_vault/variables.tf index d90ee02f..65381db2 100644 --- a/platform/terraform/modules/secrets_vault/variables.tf +++ b/platform/terraform/modules/secrets_vault/variables.tf @@ -89,14 +89,8 @@ variable "cloud_binary_artifacts_store_access_key" { default = "" } -variable "vcs_k8s_agent_token" { - description = "VCS kubernetes agent token for GitLab" - type = string - default = "" -} - variable "image_registry_auth" { description = "Specifies the access keys for image registries" - type = map(object({login = string, token = string})) + type = map(object({ login = string, token = string })) default = {} } diff --git a/platform/terraform/modules/vcs_github/output.tf b/platform/terraform/modules/vcs_github/output.tf index 31392ef1..ab71d005 100644 --- a/platform/terraform/modules/vcs_github/output.tf +++ b/platform/terraform/modules/vcs_github/output.tf @@ -13,12 +13,6 @@ output "gitops_repo_ssh_clone_url" { output "vcs_runner_token" { #This output is empty. It's here for vcs_gitlab module compatibility. - value = "" - sensitive = true -} - -output "vcs_k8s_agent_token" { - #This output is empty. It's here for vcs_gitlab module compatibility. - value = "" + value = "" sensitive = true } diff --git a/platform/terraform/modules/vcs_github/repository/main.tf b/platform/terraform/modules/vcs_github/repository/main.tf index a4bf58ea..b37f0cc7 100644 --- a/platform/terraform/modules/vcs_github/repository/main.tf +++ b/platform/terraform/modules/vcs_github/repository/main.tf @@ -27,18 +27,18 @@ resource "github_repository" "repo" { } -# Protect the main branch of the repository. Additionally, require +# Protect the main branch of the repository. Additionally, require # only allow the engineers team merge to the branch. resource "github_branch_protection" "this" { - count = var.branch_protection && var.vcs_subscription_plan ? 1 : 0 + count = var.branch_protection && var.vcs_subscription_plan ? 1 : 0 repository_id = github_repository.repo.node_id - pattern = "main" - enforce_admins = true - allows_deletions = false - allows_force_pushes = false - required_linear_history = true + pattern = var.default_branch_name + enforce_admins = true + allows_deletions = false + allows_force_pushes = false + required_linear_history = true require_conversation_resolution = true # required_status_checks { diff --git a/platform/terraform/modules/vcs_github/repository/variable.tf b/platform/terraform/modules/vcs_github/repository/variable.tf index 34626964..517510d1 100644 --- a/platform/terraform/modules/vcs_github/repository/variable.tf +++ b/platform/terraform/modules/vcs_github/repository/variable.tf @@ -82,6 +82,6 @@ variable "cd_webhook_url" { variable "vcs_subscription_plan" { description = "True for advanced github/gitlab plan. False for free tier" - type = bool - default = false + type = bool + default = false } diff --git a/platform/terraform/modules/vcs_github/runner_group.tf b/platform/terraform/modules/vcs_github/runner_group.tf index c8661a71..51677e8f 100644 --- a/platform/terraform/modules/vcs_github/runner_group.tf +++ b/platform/terraform/modules/vcs_github/runner_group.tf @@ -1,13 +1,13 @@ locals { self_hosted_runners_repos = concat( - [for workload in module.workload_repos : workload.repo_id], + [for workload in module.workload_repos : workload.repo_id], [module.gitops-repo.repo_id] ) } resource "github_actions_runner_group" "this" { - depends_on = [module.workload_repos] - count = var.vcs_subscription_plan ? 1 : 0 + depends_on = [module.workload_repos] + count = var.vcs_subscription_plan ? 1 : 0 name = var.cluster_name visibility = "selected" selected_repository_ids = local.self_hosted_runners_repos diff --git a/platform/terraform/modules/vcs_github/variable.tf b/platform/terraform/modules/vcs_github/variable.tf index 7a75c71a..e2dc5737 100644 --- a/platform/terraform/modules/vcs_github/variable.tf +++ b/platform/terraform/modules/vcs_github/variable.tf @@ -32,8 +32,8 @@ variable "vcs_bot_ssh_public_key" { variable "vcs_subscription_plan" { description = "True for advanced github/gitlab plan. False for free tier" - type = bool - default = false + type = bool + default = false } variable "vcs_owner" { @@ -48,9 +48,9 @@ variable "cluster_name" { variable "workloads" { description = "workloads configuration" - type = map(object({ + type = map(object({ description = optional(string, "") - repos = map(object({ + repos = map(object({ description = optional(string, "") visibility = optional(string, "private") auto_init = optional(bool, false) diff --git a/platform/terraform/modules/vcs_github/workload_repos.tf b/platform/terraform/modules/vcs_github/workload_repos.tf index 83fb631c..53df67b5 100644 --- a/platform/terraform/modules/vcs_github/workload_repos.tf +++ b/platform/terraform/modules/vcs_github/workload_repos.tf @@ -1,5 +1,5 @@ module "workload_repos" { - source = "./repository" + source = "./repository" for_each = { for r in flatten([ for wl in var.workloads : diff --git a/platform/terraform/modules/vcs_gitlab/k8s_agent.tf b/platform/terraform/modules/vcs_gitlab/k8s_agent.tf deleted file mode 100644 index 0fc1a339..00000000 --- a/platform/terraform/modules/vcs_gitlab/k8s_agent.tf +++ /dev/null @@ -1,30 +0,0 @@ -resource "gitlab_cluster_agent" "gitops" { - project = module.gitops-repo.repo_id - name = "cc-cluster-agent" - - depends_on = [module.gitops-repo] -} - -resource "gitlab_cluster_agent_token" "gitops" { - project = gitlab_cluster_agent.gitops.project - agent_id = gitlab_cluster_agent.gitops.agent_id - name = "cc-cluster-agent-token" - description = "Token for the cc-cluster-agent" - - depends_on = [gitlab_cluster_agent.gitops] -} - -# // Optionally, configure the agent as described in -# // https://docs.gitlab.com/ee/user/clusters/agent/install/index.html#create-an-agent-configuration-file -# resource "gitlab_repository_file" "gitops_agent_config" { -# project = module.gitops-repo.repo_id -# branch = "main" -# file_path = ".gitlab/agents/${var.cluster_name}/config.yaml" -# content = base64encode(<"] = vcs_out["gitops_repo_ssh_clone_url"] p.parameters[""] = vcs_out["gitops_repo_html_url"] p.internals["VCS_RUNNER_TOKEN"] = vcs_out["vcs_runner_token"] - p.internals["VCS_K8S_AGENT_TOKEN"] = vcs_out["vcs_k8s_agent_token"] # unset envs as no longer needed unset_envs(vcs_tf_env_vars) @@ -372,7 +371,7 @@ def setup( # network p.parameters[""] = hp_out["network_id"] # roles - p.parameters[""] = hp_out["iam_ci_role"] + p.parameters[""] = hp_out["ci_role"] p.parameters[""] = hp_out["iac_pr_automation_role"] p.parameters[""] = hp_out["cert_manager_role"] p.parameters[""] = hp_out["external_dns_role"] @@ -771,7 +770,6 @@ def setup( "vault_token": p.internals["VAULT_ROOT_TOKEN"], "cluster_endpoint": p.internals["CC_CLUSTER_ENDPOINT"], "vcs_runner_token": p.internals["VCS_RUNNER_TOKEN"], - "vcs_k8s_agent_token": p.internals["VCS_K8S_AGENT_TOKEN"], } if "" in p.parameters: sec_man_tf_params["cluster_ssh_public_key"] = p.parameters[""] @@ -1002,9 +1000,9 @@ def get_git_provider_specific_optional_services(git_provider: GitProviders) -> l # TODO: unify and restructure services switching logic after GitLab integration if git_provider == GitProviders.GitHub: - return [OptionalServices.GitHub] + return [OptionalServices.GitHub.value] elif git_provider == GitProviders.GitLab: - return [OptionalServices.GitLab] + return [OptionalServices.GitLab.value] def get_cloud_provider_specific_optional_services(cloud_provider: str) -> list[str]: @@ -1044,6 +1042,7 @@ def prepare_parameters(p, git_man): p.parameters[""] = p.get_input_param(DOMAIN_NAME).lower() p.parameters[""] = KUBECTL_VERSION p.parameters[""] = TERRAFORM_VERSION + p.parameters[""] = git_man.get_repository_hostname() # set IaC webhook secret if "" not in p.parameters: diff --git a/tools/cli/commands/workload/README.md b/tools/cli/commands/workload/README.md index 01f61b21..992e1a2e 100644 --- a/tools/cli/commands/workload/README.md +++ b/tools/cli/commands/workload/README.md @@ -47,7 +47,7 @@ created by the [create command](#create). Templates used: -Workload repository: [CG DevX Workload GitOps template](https://github.com/CloudGeometry/cg-devx-wl-gitops-template) +Workload repository: [CG DevX Workload template](https://github.com/CloudGeometry/cg-devx-wl-template) Workload GitOps repository: [CG DevX Workload GitOps template](https://github.com/CloudGeometry/cg-devx-wl-gitops-template) @@ -58,6 +58,13 @@ definitions. You can fork and customize these templates and specify custom URLs and branches during execution. +Example of custom template + +- Cloud Native Application Starter Kit (CNASK) + - Workload repository: [CNASK template](https://github.com/CloudGeometry/cg-devx-wl-cnask) + - Workload GitOps + repository: [CNASK GitOps template](https://github.com/CloudGeometry/cg-devx-wl-cnask-gitops) + ### Usage This command can be executed using command-line arguments or environment variables. diff --git a/tools/cli/commands/workload/bootstrap.py b/tools/cli/commands/workload/bootstrap.py index 79d018c2..94c969a1 100644 --- a/tools/cli/commands/workload/bootstrap.py +++ b/tools/cli/commands/workload/bootstrap.py @@ -91,8 +91,8 @@ help='Set the verbosity level (DEBUG, INFO, WARNING, ERROR, CRITICAL)' ) def bootstrap( - wl_name: str, wl_repo_name: str, wl_gitops_repo_name: str, wl_template_url: str, wl_template_branch: str, - wl_gitops_template_url: str, wl_gitops_template_branch: str, wl_svc_name: str, wl_svc_port: int, verbosity: str + wl_name: str, wl_repo_name: str, wl_gitops_repo_name: str, wl_template_url: str, wl_template_branch: str, + wl_gitops_template_url: str, wl_gitops_template_branch: str, wl_svc_name: str, wl_svc_port: int, verbosity: str ): """ Bootstrap a new workload environment by setting up the necessary repositories and configurations. @@ -298,8 +298,11 @@ def bootstrap( author_email=state_store.internals["GIT_USER_EMAIL"]) wl_gitops_manager.switch_to_branch() - pr_url = git_man.create_pr(wl_gitops_repo_name, branch_name, "main", - f"Execute IaC changes for {wl_name}", "Setup default secrets.") + pr_url = git_man.create_pr(wl_gitops_repo_name, + branch_name, + wl_gitops_manager.default_branch, + f"Execute IaC changes for {wl_name}", + "Setup default secrets.") webbrowser.open(pr_url, autoraise=False) click.echo("10/11: Created PR for GitOps repository.") diff --git a/tools/cli/commands/workload/create.py b/tools/cli/commands/workload/create.py index 3281a857..9b27910c 100644 --- a/tools/cli/commands/workload/create.py +++ b/tools/cli/commands/workload/create.py @@ -3,7 +3,7 @@ import click from git import InvalidGitRepositoryError -from common.const.const import GITOPS_REPOSITORY_MAIN_BRANCH, WL_PR_BRANCH_NAME_PREFIX +from common.const.const import WL_PR_BRANCH_NAME_PREFIX from common.custom_excpetions import GitBranchAlreadyExists, PullRequestCreationError from common.logging_config import configure_logging, logger from common.state_store import StateStore @@ -62,6 +62,7 @@ def create(wl_name: str, wl_repo_name: str, wl_gitops_repo_name: str, verbosity: click.echo("2/7: Workload names processed.") try: git_man, gor = initialize_gitops_repository(state_store=state_store, logger=logger) + except InvalidGitRepositoryError: raise click.ClickException("GitOps repo does not exist") click.echo("3/7: GitOps repository initialized.") @@ -88,7 +89,7 @@ def create(wl_name: str, wl_repo_name: str, wl_gitops_repo_name: str, verbosity: title=f"Introduce {wl_name}", body="Add default secrets, groups and default repository structure.", branch_name=branch_name, - main_branch=GITOPS_REPOSITORY_MAIN_BRANCH, + main_branch=gor.default_branch, logger=logger ) except PullRequestCreationError as e: @@ -96,9 +97,9 @@ def create(wl_name: str, wl_repo_name: str, wl_gitops_repo_name: str, verbosity: click.echo(f"6/7: Pull request for branch '{branch_name}' created and opened in the web browser.") - gor.switch_to_branch(branch_name=GITOPS_REPOSITORY_MAIN_BRANCH) + gor.switch_to_branch(branch_name=gor.default_branch) gor.delete_branch(branch_name) - click.echo(f"7/7: Switched to branch '{GITOPS_REPOSITORY_MAIN_BRANCH}'.") + click.echo(f"7/7: Switched to branch '{gor.default_branch}'.") click.echo(f"Workload GitOps code creation completed in {time.time() - func_start_time:.2f} seconds.") diff --git a/tools/cli/commands/workload/delete.py b/tools/cli/commands/workload/delete.py index b61505c5..ff376183 100644 --- a/tools/cli/commands/workload/delete.py +++ b/tools/cli/commands/workload/delete.py @@ -8,7 +8,7 @@ from git import InvalidGitRepositoryError from common.const.common_path import LOCAL_WORKLOAD_TEMP_FOLDER -from common.const.const import GITOPS_REPOSITORY_MAIN_BRANCH, WL_PR_BRANCH_NAME_PREFIX +from common.const.const import WL_PR_BRANCH_NAME_PREFIX from common.const.parameter_names import GIT_ACCESS_TOKEN, GIT_ORGANIZATION_NAME from common.custom_excpetions import GitBranchAlreadyExists, PullRequestCreationError from common.logging_config import configure_logging, logger @@ -163,7 +163,7 @@ def delete( title=f"Remove {wl_names}", body="Remove default secrets, groups and repository structure.", branch_name=branch_name, - main_branch=GITOPS_REPOSITORY_MAIN_BRANCH, + main_branch=gor.default_branch, logger=logger ) except PullRequestCreationError as e: @@ -171,7 +171,7 @@ def delete( click.echo(f"{6 if destroy_resources else 5}/{logging_total_steps}: Pull request created and opened.") - gor.switch_to_branch() + gor.switch_to_branch(gor.default_branch) gor.delete_branch(branch_name) click.echo(f"Deleting workloads GitOps code completed in {time.time() - func_start_time:.2f} seconds.") diff --git a/tools/cli/common/const/const.py b/tools/cli/common/const/const.py index 65db9ec7..83708582 100644 --- a/tools/cli/common/const/const.py +++ b/tools/cli/common/const/const.py @@ -1,5 +1,6 @@ DEFAULT_ENUM_VALUE = "unknown" GITOPS_REPOSITORY_URL = "https://github.com/CloudGeometry/cg-devx-core.git" +GITOPS_REPOSITORY_MAIN_BRANCH = "main" GITOPS_REPOSITORY_BRANCH = "main" STATE_INPUT_PARAMS = "input" STATE_INTERNAL_PARAMS = "internal" @@ -12,12 +13,11 @@ ARGOCD_REGISTRY_APP_PATH = "gitops-pipelines/delivery/clusters/cc-cluster/core-services" KUBECTL_VERSION = "1.33.1" TERRAFORM_VERSION = "1.6.4" -GITLAB_TF_REQUIRED_PROVIDER_VERSION = "17.3.1" +GITLAB_TF_REQUIRED_PROVIDER_VERSION = "18.2.0" GITHUB_TF_REQUIRED_PROVIDER_VERSION = "5.42.0" -GITOPS_REPOSITORY_MAIN_BRANCH = "main" -WL_REPOSITORY_URL = "git@github.com:CloudGeometry/cg-devx-wl-template.git" +WL_REPOSITORY_URL = "https://github.com/CloudGeometry/cg-devx-wl-template.git" WL_REPOSITORY_BRANCH = "main" WL_PR_BRANCH_NAME_PREFIX = "feature/" -WL_GITOPS_REPOSITORY_URL = "git@github.com:CloudGeometry/cg-devx-wl-gitops-template.git" +WL_GITOPS_REPOSITORY_URL = "https://github.com/CloudGeometry/cg-devx-wl-gitops-template.git" WL_GITOPS_REPOSITORY_BRANCH = "main" WL_SERVICE_NAME = "default-service" diff --git a/tools/cli/common/utils/optional_services_manager.py b/tools/cli/common/utils/optional_services_manager.py index ad85caac..a5575cfb 100644 --- a/tools/cli/common/utils/optional_services_manager.py +++ b/tools/cli/common/utils/optional_services_manager.py @@ -2,7 +2,7 @@ OPTIONAL_SERVICES_MAP = { OptionalServices.GitHub: ["50-actions-runner-controller.yaml", "60-github-runner.yaml"], - OptionalServices.GitLab: ["60-gitlab-runner.yaml", "65-gitlab-agent.yaml"], + OptionalServices.GitLab: ["60-gitlab-runner.yaml"], OptionalServices.NvidiaGpuOperator: ["180-nvidia-gpu-operator.yaml"], OptionalServices.KEDA: ["180-keda.yaml"], OptionalServices.KubeVirt: ["180-kubevirt.yaml"], diff --git a/tools/cli/services/cloud/aws/aws_manager.py b/tools/cli/services/cloud/aws/aws_manager.py index fb5b1d26..2e064cd4 100644 --- a/tools/cli/services/cloud/aws/aws_manager.py +++ b/tools/cli/services/cloud/aws/aws_manager.py @@ -97,7 +97,7 @@ def create_iac_backend_snippet(self, location: str, service: str, **kwargs: dict region = kwargs["region"] return textwrap.dedent('''\ - backend "s3" {{ + backend "s3" {{ bucket = "{bucket}" key = "terraform/{service}/terraform.tfstate" region = "{region}" diff --git a/tools/cli/services/platform_gitops.py b/tools/cli/services/platform_gitops.py index e16a2c56..8700c661 100644 --- a/tools/cli/services/platform_gitops.py +++ b/tools/cli/services/platform_gitops.py @@ -1,5 +1,6 @@ import json import os +import re import shutil from typing import Optional, List @@ -30,6 +31,16 @@ def __init__( self._author_name = author_name self._author_email = author_email + @property + def default_branch(self) -> str | None : + remote_info = self._repo.git.remote("show", "origin") + + # Parse the "HEAD branch" line + match = re.search(r"HEAD branch: (.+)", remote_info) + if match: + return match.group(1) + return None + @trace() def _initialize_repo(self, repo_remote_url: Optional[str]) -> Repo: """ @@ -71,9 +82,11 @@ def update(self): with self._repo.git.custom_environment(GIT_SSH_COMMAND=self._ssh_cmd): # clean stale branches self._repo.remotes.origin.fetch(prune=True) - self._repo.heads.main.checkout() + self._repo.active_branch.checkout() self._repo.remotes.origin.pull(self._repo.active_branch) + return self._repo.active_branch.name + @trace() def branch_exist(self, branch_name: str) -> bool: """ @@ -107,7 +120,7 @@ def upload_changes(self, message: Optional[str] = "initial") -> None: self._repo.remotes.origin.push(self._repo.active_branch.name) @trace() - def switch_to_branch(self, branch_name: str = "main"): + def switch_to_branch(self, branch_name: str): """ Switch to an existing branch in the platform GitOps repository @@ -143,6 +156,7 @@ def create_pr(self, repo_name: str, head_branch: str, base_branch: str, title: s :param title: PR/MR title :param body: PR/MR body """ + # self._repo.active_branch.name return self._git_man.create_pr(repo_name, head_branch, base_branch, title, body) @trace() diff --git a/tools/cli/services/platform_template_manager.py b/tools/cli/services/platform_template_manager.py index 8aac993e..8ba6d34c 100644 --- a/tools/cli/services/platform_template_manager.py +++ b/tools/cli/services/platform_template_manager.py @@ -10,6 +10,7 @@ from common.const.common_path import LOCAL_TF_FOLDER, LOCAL_GITOPS_FOLDER from common.const.const import GITOPS_REPOSITORY_URL, GITOPS_REPOSITORY_BRANCH +from common.enums.git_providers import GitProviders from common.state_store import StateStore from common.tracing_decorator import trace @@ -80,7 +81,7 @@ def upload(path: str, key_path: str, git_user_name: str, git_user_email: str): try: ssh_cmd = f'ssh -o StrictHostKeyChecking=no -i {key_path}' - repo = Repo.init(LOCAL_GITOPS_FOLDER) + repo = Repo.init(LOCAL_GITOPS_FOLDER, **{"initial-branch": "main"}) with repo.git.custom_environment(GIT_SSH_COMMAND=ssh_cmd): if not any(repo.remotes): @@ -97,7 +98,7 @@ def upload(path: str, key_path: str, git_user_name: str, git_user_email: str): @staticmethod @trace() - def build_repo_from_template(): + def build_repo_from_template(git_provider: GitProviders): temp_folder = LOCAL_GITOPS_FOLDER / ".tmp" os.makedirs(LOCAL_GITOPS_FOLDER, exist_ok=True) @@ -112,12 +113,8 @@ def build_repo_from_template(): if os.path.isdir(path): os.rmdir(path) - # restructure gitops platform/.gitlab shutil.copytree(temp_folder / "platform" / "terraform", LOCAL_GITOPS_FOLDER / "terraform") shutil.copytree(temp_folder / "platform" / "gitops-pipelines", LOCAL_GITOPS_FOLDER / "gitops-pipelines") - shutil.copytree(temp_folder / "platform" / "gitlab", LOCAL_GITOPS_FOLDER / ".gitlab") - for src_file in Path(temp_folder / "platform").glob('*.*'): - shutil.copy(src_file, LOCAL_GITOPS_FOLDER) # drop all non template readme files for root, dirs, files in os.walk(LOCAL_GITOPS_FOLDER): diff --git a/tools/cli/services/vcs/git_provider_manager.py b/tools/cli/services/vcs/git_provider_manager.py index a744a54a..2aaad30c 100644 --- a/tools/cli/services/vcs/git_provider_manager.py +++ b/tools/cli/services/vcs/git_provider_manager.py @@ -113,3 +113,15 @@ def get_repository_url(http://github.com/self,%20org_name:%20str,%20repo_name:%20str) -> str: :raises HTTPError: If there is an issue with the API request. """ pass + + @abstractmethod + def get_repository_hostname(self) -> str: + """ + Retrieves the hostname for Git repository. + + This method returns the Git repo hostname. + + :return: The Git repo hostname. + :rtype: str + """ + pass diff --git a/tools/cli/services/vcs/github/github_manager.py b/tools/cli/services/vcs/github/github_manager.py index c72bef24..acb1221b 100644 --- a/tools/cli/services/vcs/github/github_manager.py +++ b/tools/cli/services/vcs/github/github_manager.py @@ -207,3 +207,14 @@ def get_repository_url(http://github.com/self,%20org_name:%20str,%20repo_name:%20str) -> str: :raises HTTPError: If there is an issue with the API request. """ return GHRepo(owner=org_name, name=repo_name).ssh_url + + def get_repository_hostname(self) -> str: + """ + Retrieves the hostname for GitHub repository. + + This method returns the GitHub repo hostname. + + :return: The GitHub repo hostname. + :rtype: str + """ + return "github.com" diff --git a/tools/cli/services/vcs/gitlab/gitlab_manager.py b/tools/cli/services/vcs/gitlab/gitlab_manager.py index 27231c5b..b322a83d 100644 --- a/tools/cli/services/vcs/gitlab/gitlab_manager.py +++ b/tools/cli/services/vcs/gitlab/gitlab_manager.py @@ -245,7 +245,7 @@ def create_pr(self, repo_name: str, head_branch: str, base_branch: str, title: s def create_iac_pr_automation_config_snippet(self): """ - Creates GitHub specific configuration section for Atlantis + Creates GitLab specific configuration section for Atlantis :return: Atlantis configuration section """ return textwrap.dedent("""# gitlab specific section @@ -301,3 +301,14 @@ def get_repository_url(http://github.com/self,%20org_name:%20str,%20repo_name:%20str) -> str: except (KeyError, requests.RequestException) as e: logger.error(f"Error retrieving repository URL: {e}") raise + + def get_repository_hostname(self) -> str: + """ + Retrieves the hostname for GitLab repository. + + This method returns the GitLab repo hostname. + + :return: The GitLab repo hostname. + :rtype: str + """ + return "gitlab.com" diff --git a/tools/cli/services/wl_template_manager.py b/tools/cli/services/wl_template_manager.py index 5639d12b..94fa6b28 100644 --- a/tools/cli/services/wl_template_manager.py +++ b/tools/cli/services/wl_template_manager.py @@ -1,7 +1,8 @@ import os +import re import shutil from pathlib import Path -from typing import Optional, Union, List, Dict +from typing import Optional, Union, List, Dict, Any from urllib.parse import urlparse from git import Repo, GitError, Actor @@ -18,13 +19,13 @@ class WorkloadManager: """CG DevX Workload templates manager.""" def __init__( - self, - org_name: str, - wl_repo_name: str, - ssh_pkey_path: str, - repo_manager: GitProviderManager, - template_url: Optional[str] = WL_REPOSITORY_URL, - template_branch: Optional[str] = WL_REPOSITORY_BRANCH + self, + org_name: str, + wl_repo_name: str, + ssh_pkey_path: str, + repo_manager: GitProviderManager, + template_url: Optional[str] = WL_REPOSITORY_URL, + template_branch: Optional[str] = WL_REPOSITORY_BRANCH ): self._template_url = template_url self._branch = template_branch @@ -37,6 +38,16 @@ def __init__( self.wl_repo = None self.template_repo = None + @property + def default_branch(self) -> str | None: + remote_info = self.wl_repo.git.remote("show", "origin") + + # Parse the "HEAD branch" line + match = re.search(r"HEAD branch: (.+)", remote_info) + if match: + return match.group(1) + return None + @trace() def clone_template(self) -> str: """ @@ -150,12 +161,14 @@ def update(self): if not self.wl_repo: self.wl_repo = Repo(self.wl_repo_folder) with self.wl_repo.git.custom_environment( - GIT_SSH_COMMAND=f"ssh -o StrictHostKeyChecking=no -i {self.ssh_pkey_path}"): + GIT_SSH_COMMAND=f"ssh -o StrictHostKeyChecking=no -i {self.ssh_pkey_path}"): # clean stale branches self.wl_repo.remotes.origin.fetch(prune=True) - self.wl_repo.heads.main.checkout() + self.wl_repo.active_branch.checkout() self.wl_repo.remotes.origin.pull(self.wl_repo.active_branch) + return self.wl_repo.active_branch.name + @trace() def branch_exist(self, branch_name): return branch_name in self.wl_repo.branches From 9d88e4adca9edc40ad8136938a0ab4759e9ba720 Mon Sep 17 00:00:00 2001 From: Alex Ulyanov Date: Thu, 4 Sep 2025 15:25:05 +0200 Subject: [PATCH 4/6] fix: pin aws iam tf module version --- platform/terraform/modules/cloud_aws/iam.tf | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/platform/terraform/modules/cloud_aws/iam.tf b/platform/terraform/modules/cloud_aws/iam.tf index 55531854..f6eb52c6 100644 --- a/platform/terraform/modules/cloud_aws/iam.tf +++ b/platform/terraform/modules/cloud_aws/iam.tf @@ -5,6 +5,7 @@ # CNI module "vpc_cni_irsa" { source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~>5.58.0" role_name = "${local.name}-vpc-cni-role" attach_vpc_cni_policy = true @@ -22,6 +23,7 @@ module "vpc_cni_irsa" { # CSI module "ebs_csi_irsa_role" { source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~>5.58.0" role_name = "${local.name}-ebs-csi-role" attach_ebs_csi_policy = true @@ -37,6 +39,7 @@ module "ebs_csi_irsa_role" { module "efs_csi_irsa_role" { source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~>5.58.0" role_name = "${local.name}-efs-csi-role" attach_efs_csi_policy = true @@ -60,6 +63,8 @@ locals { # Cloud Native CI module "iam_ci_role" { source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~>5.58.0" + role_name = "${local.name}-ci-role" role_policy_arns = { @@ -78,6 +83,8 @@ module "iam_ci_role" { # IaC PR automation module "iac_pr_automation_irsa_role" { source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~>5.58.0" + role_name = "${local.name}-iac_pr_automation-role" oidc_providers = { main = { @@ -95,6 +102,8 @@ module "iac_pr_automation_irsa_role" { # cert manager module "cert_manager_irsa_role" { source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~>5.58.0" + role_name = "${local.name}-cert-manager-role" attach_cert_manager_policy = true # cert_manager_hosted_zone_arns = ["arn:aws:route53:::hostedzone/*"] @@ -110,6 +119,8 @@ module "cert_manager_irsa_role" { # external DNS module "external_dns_irsa_role" { source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~>5.58.0" + role_name = "${local.name}-external-dns-role" attach_external_dns_policy = true # external_dns_hosted_zone_arns = ["arn:aws:route53:::hostedzone/*"] @@ -125,6 +136,8 @@ module "external_dns_irsa_role" { # secret_manager module "secret_manager_irsa_role" { source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~>5.58.0" + role_name = "${local.name}-secret_manager-role" oidc_providers = { main = { @@ -141,6 +154,7 @@ module "secret_manager_irsa_role" { # Cluster Autoscaler module "cluster_autoscaler_irsa_role" { source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~>5.58.0" role_name = "${local.name}-cluster-autoscaler" attach_cluster_autoscaler_policy = true @@ -157,6 +171,8 @@ module "cluster_autoscaler_irsa_role" { # Cluster Backups Manager module "backups_manager_irsa_role" { source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~>5.58.0" + role_name = "${local.name}-backups-manager-role" role_policy_arns = { From 4dc5a9c060ae081cf57dd2016ff2ea275bd2290a Mon Sep 17 00:00:00 2001 From: Alex Ulyanov Date: Thu, 4 Sep 2025 15:25:56 +0200 Subject: [PATCH 5/6] fix: gitlab runner registration token wiped out on tf secrets module update --- platform/terraform/modules/secrets_vault/secrets.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/terraform/modules/secrets_vault/secrets.tf b/platform/terraform/modules/secrets_vault/secrets.tf index 8456d7ee..0c06642b 100644 --- a/platform/terraform/modules/secrets_vault/secrets.tf +++ b/platform/terraform/modules/secrets_vault/secrets.tf @@ -61,6 +61,7 @@ resource "vault_generic_secret" "atlantis_secrets" { TF_VAR_atlantis_repo_webhook_secret = var.atlantis_repo_webhook_secret, TF_VAR_atlantis_repo_webhook_url = var.atlantis_repo_webhook_url, TF_VAR_vcs_token = var.vcs_token, + TF_VAR_vcs_runner_token = var.vcs_runner_token, TF_VAR_cluster_endpoint = var.cluster_endpoint, TF_VAR_tf_backend_storage_access_key = var.tf_backend_storage_access_key, TF_VAR_cluster_ssh_public_key = var.cluster_ssh_public_key, From eaa528a752c785da02188561d26e1e7832186068 Mon Sep 17 00:00:00 2001 From: Alex Ulyanov Date: Thu, 4 Sep 2025 15:26:49 +0200 Subject: [PATCH 6/6] fix: missing platform gitops repo files --- tools/cli/services/platform_template_manager.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/cli/services/platform_template_manager.py b/tools/cli/services/platform_template_manager.py index 8ba6d34c..e5fcb555 100644 --- a/tools/cli/services/platform_template_manager.py +++ b/tools/cli/services/platform_template_manager.py @@ -115,6 +115,8 @@ def build_repo_from_template(git_provider: GitProviders): shutil.copytree(temp_folder / "platform" / "terraform", LOCAL_GITOPS_FOLDER / "terraform") shutil.copytree(temp_folder / "platform" / "gitops-pipelines", LOCAL_GITOPS_FOLDER / "gitops-pipelines") + for src_file in Path(temp_folder / "platform").glob('*.*'): + shutil.copy(src_file, LOCAL_GITOPS_FOLDER) # drop all non template readme files for root, dirs, files in os.walk(LOCAL_GITOPS_FOLDER):