Set up Host project's Git repo

Org Admin Duration: 10 min | Persona: Org Admin

In this section, you will set up the primary Git repository of the Config Controller instance in order to have in place a GitOps approach to deploy your infrastructure in Google Cloud. You will also configure a Cloud NAT to this Config Controller instance to give it access to the Internet (GitHub repositories) in Egress. Finally, you will enable the cloudbilling API in the Host project, which will allow the assignment of the Billing Account Id to any Google Cloud project Config Controller will create.

Define variables:

source ${WORK_DIR}
echo "export HOST_PROJECT_DIR_NAME=acm-workshop-org-repo" >> ${WORK_DIR}
source ${WORK_DIR}

Set up Cloud NAT

Open Config Controller’s egress to the Internet (GitHub access):

gcloud compute routers create $CONFIG_CONTROLLER_NAT_ROUTER_NAME \
gcloud compute routers nats create $CONFIG_CONTROLLER_NAT_CONFIG_NAME \
    --router-region $CONFIG_CONTROLLER_LOCATION \
    --nat-all-subnet-ip-ranges \

Customize Policy Controller

Customize setup for the Config Controller’s Config Management component:

cat << EOF | kubectl apply -f -
kind: ConfigManagement
  name: config-management
  enableMultiRepo: true
    enabled: true
    logDeniesEnabled: true
    referentialRulesEnabled: true
    templateLibraryInstalled: true

We explicitly set the Policy Controller’s referentialRulesEnabled field to true and logDeniesEnabled field to true, the others are enabled by default.

Define the Host project’s Git repository

Create a dedicated private GitHub repository to store any Kubernetes manifests associated to the Host project:

cd ${WORK_DIR}
gh auth login
gh repo create $HOST_PROJECT_DIR_NAME --private --clone --template
git pull
git checkout main
ORG_REPO_URL=$(gh repo view --json sshUrl --jq .sshUrl)
ORG_REPO_NAME_WITH_OWNER=$(gh repo view --json nameWithOwner --jq .nameWithOwner)

Generate SSH key pair in order to get a read access to the private Git repository:

mkdir tmp
ssh-keygen -t rsa -b 4096 \
    -C "${ORG_REPO_NAME_WITH_OWNER}@github" \
    -N '' \
    -f ./tmp/github-org-repo
kubectl create secret generic git-creds \
    -n config-management-system \
    --from-file ssh=./tmp/github-org-repo
gh repo deploy-key add ./tmp/
rm -r tmp

Deploy a RootSync linking this GitHub repository to the Config Controller instance as the main/root GitOps configuration:

cat << EOF | kubectl apply -f -
kind: RootSync
  name: root-sync
  namespace: config-management-system
  sourceFormat: unstructured
    repo: ${ORG_REPO_URL}
    revision: HEAD
    branch: main
    dir: .
    auth: ssh
      name: git-creds

The GitHub repository is private in order to demonstrate how to allow read access to Config Sync when you use a private Git repository.

Since you started this workshop, you just ran 6 kubectl commands. For your information, moving forward you won’t run any other kubectl commands because the design and intent of this workshop is to only deploy any Kubernetes resources via GitOps with Config Sync. You will also use some handy gcloud commands when appropriate.

Define API

In order to have Config Controller’s Config Sync linking a Billing Account to GCP projects later in this workshop, we need to define the Cloud Billing API Service resource for Config Controller’s GCP project:

cat <<EOF > ${WORK_DIR}$HOST_PROJECT_DIR_NAME/cloudbilling-service.yaml
kind: Service
  annotations: "abandon" "false"
  namespace: config-control

Deploy Kubernetes manifests

git add . && git commit -m "Billing API in Host project" && git push origin main

Because it’s the first git commit of this workshop, if you don’t have your own environment set up with git, you may be prompted to properly set up git config --global "" and git config --global "Your Name".

Check deployments

List the GitHub runs for the Host project configs repository:

cd ${WORK_DIR}$HOST_PROJECT_DIR_NAME && gh run list

List the Kubernetes resources managed by Config Sync in Config Controller for the Host project configs repository:

gcloud alpha anthos config sync repo describe \
    --project $HOST_PROJECT_ID \
    --managed-resources all \
    --sync-name root-sync \
    --sync-namespace config-management-system

Wait and re-run this command above until you see "status": "SYNCED". All the managed_resources listed should have STATUS: Current as well.