Get Started with Infralib
Describe your platform in one config.yaml, run the Infralib agent, and get a network, a Kubernetes cluster and ArgoCD in your own cloud account. No Entigo Portal needed.
Infralib runs on AWS, Google Cloud, Oracle Cloud and Azure. This guide shows all four.
- An empty cloud account with full access: administrator on AWS, a service account with owner access on Google Cloud, an empty compartment and an administrator API key on Oracle Cloud, an empty subscription and a service principal with Owner on Azure
- A public DNS zone in your cloud account. Your environment gets a subdomain under it.
- Docker,
kubectland your cloud's CLI (aws,gcloud,ociorazwithkubelogin)
- 1Write the configuration
- 2Run the Infralib agent
- 3Check the result
- 4Add the platform APIs
- 5Keep it up to date
1. Write the configuration
The whole platform is described in one config.yaml:
prefixnames everything that gets created.- Each step becomes a pipeline.
- Each module comes from the Infralib release and is wired to the others automatically.
Pick your cloud and copy the example. The choice applies to every step on this page.
- AWS
- Google Cloud
- Oracle Cloud
- Azure
Show the minimal config.yaml for AWS
sources:
- url: oci://public.ecr.aws/entigolabs/entigo-infralib-release
prefix: dev
steps:
- name: net
type: terraform
modules:
- name: main
source: aws/vpc
inputs:
vpc_cidr: 10.112.0.0/16
one_nat_gateway_per_az: false
elasticache_subnets: |
[]
intra_subnets: |
[]
- name: dns
source: aws/route53
inputs:
create_private: false
create_public: true
parent_zone_id: REPLACEME
public_subdomain_name: "{{ .config.prefix }}"
- name: infra
type: terraform
vpc:
attach: true
modules:
- name: eks
source: aws/eks
inputs:
# Gives you admin access to the cluster. Use the role you sign in to AWS with,
# or replace this line with: aws_auth_user: <your IAM user name>
iam_admin_role: AWSReservedSSO_AWSAdministratorAccess_.*
eks_cluster_public: true
eks_main_min_size: 1
eks_main_max_size: 3
eks_main_volume_size: 100
eks_tools_desired_size: 1
eks_mon_max_size: 0
cluster_enabled_log_types: |
[]
- name: crossplane
source: aws/crossplane
- name: apps
type: argocd-apps
modules:
- name: argocd
source: argocd
inputs:
argocd:
server:
ingress:
annotations:
alb.ingress.kubernetes.io/group.name: external
alb.ingress.kubernetes.io/scheme: internet-facing
- name: aws-alb-{{ .config.prefix }}
source: aws-alb
- name: crossplane-system
source: crossplane-core
- name: crossplane-aws
source: crossplane-aws
- name: external-dns-{{ .config.prefix }}
source: external-dns
- name: istio-base
source: istio-base
- name: istio-system
source: istio-istiod
- name: aws-storageclass
source: aws-storageclass
- name: metrics-server
source: metrics-server
- name: external-secrets-{{ .config.prefix }}
source: external-secrets
- Replace
REPLACEMEwith the ID of your public Route 53 zone. - Set
iam_admin_roleto the role you sign in with, oraws_auth_userto your IAM user. Without it, you cannot access the cluster.
Show the minimal config.yaml for Google Cloud
sources:
- url: https://github.com/entigolabs/entigo-infralib-release
prefix: dev
steps:
- name: net
type: terraform
modules:
- name: main
source: google/vpc
inputs:
vpc_cidr: "10.0.0.0/16"
- name: infra
type: terraform
vpc:
attach: true
modules:
- name: dns
source: google/dns
inputs:
parent_zone_id: REPLACEME
- name: crossplane
source: google/crossplane
- name: gke
source: google/gke
inputs:
dns_allow_external_traffic: true
- name: applications
type: argocd-apps
modules:
- name: argocd
source: argocd
inputs:
argocd:
global:
domain: |
argocd.{{ .toutput.dns.pub_domain }}
server:
httproute:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: google-gateway-external
namespace: google-gateway
sectionName: https
hostnames:
- argocd.{{ .toutput.dns.pub_domain }}
- name: crossplane-system
source: crossplane-core
- name: crossplane-google
source: crossplane-google
- name: external-dns
source: external-dns
- name: google-gateway
source: google-gateway
- name: istio-base
source: istio-base
- name: istio-system
source: istio-istiod
- name: istio-gateway
source: istio-gateway
- Replace
REPLACEMEwith the ID of your public DNS zone.
Show the minimal config.yaml for Oracle Cloud
sources:
- url: oci://public.ecr.aws/entigolabs/entigo-infralib-release
prefix: dev
steps:
- name: net
type: terraform
modules:
- name: vpc
source: oracle/vpc
- name: kms
source: oracle/kms
- name: pca
source: oracle/pca
- name: dns
source: oracle/dns
inputs:
domains: |
{
"public" = {
domain_name = "dev.example.com"
parent_zone_id = "REPLACEME"
}
}
- name: infra
type: terraform
modules:
- name: oke
source: oracle/oke
inputs:
is_public_ip_enabled: true
oke_api_access_cidrs: |
["0.0.0.0/0"]
oke_main_node_count: 1
- name: apps
type: argocd-apps
modules:
- name: argocd
source: argocd
- name: crossplane-system
source: crossplane-core
- name: crossplane-oracle
source: crossplane-oracle
- name: oci-ingress
source: oci-native-ingress-controller
- name: istio-base
source: istio-base
- name: istio-system
source: istio-istiod
- name: oracle-gateway
source: oracle-gateway
inputs:
global:
internalGateway: external
- name: external-dns
source: external-dns
- name: metrics-server
source: metrics-server
- Replace
dev.example.comwith a subdomain of your public OCI DNS zone, andREPLACEMEwith that zone's OCID. - The certificates come from a private CA that
oracle/pcacreates, so browsers warn on ArgoCD until you trust that CA.
Show the minimal config.yaml for Azure
sources:
- url: oci://public.ecr.aws/entigolabs/entigo-infralib-release
prefix: dev
steps:
- name: net
type: terraform
modules:
- name: vpc
source: azure/vpc
inputs:
vpc_cidr: "10.0.0.0/16"
- name: dns
source: azure/dns
inputs:
domains: |
{
"public" = {
domain_name = "dev.example.com"
parent_zone_id = "REPLACEME"
}
}
- name: acr-proxy
source: azure/acr-proxy
- name: kms
source: azure/kms
- name: infra
type: terraform
vpc:
attach: true
modules:
- name: aks
source: azure/aks
inputs:
private_cluster_enabled: false
api_server_authorized_ip_ranges: |
[]
- name: crossplane
source: azure/crossplane
- name: agc-internal
source: azure/agc
- name: apps
type: argocd-apps
modules:
- name: argocd
source: argocd
inputs:
argocd:
global:
domain: |
argocd.{{ .toutput.dns.pub_domain }}
server:
httproute:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: external
namespace: azure-gateway
sectionName: https
hostnames:
- argocd.{{ .toutput.dns.pub_domain }}
- name: crossplane-system
source: crossplane-core
- name: crossplane-azure
source: crossplane-azure
- name: cert-manager
source: cert-manager
- name: external-dns
source: external-dns
- name: azure-gateway
source: azure-gateway
- name: istio-base
source: istio-base
- name: istio-system
source: istio-istiod
- Replace
dev.example.comwith a subdomain of your public Azure DNS zone, andREPLACEMEinparent_zone_idwith that zone's resource ID. A parent zone in another subscription gets no NS records automatically: delegate the subdomain by hand.
Create the service principal the agent signs in with. Its Owner role must not carry the condition that restricts assigning privileged roles, because the agent and the modules create role assignments.
az ad sp create-for-rbac --name infralib-agent --role Owner --scopes /subscriptions/$AZURE_SUBSCRIPTION_ID
The appId, password and tenant it prints are your AZURE_CLIENT_ID, AZURE_CLIENT_SECRET and AZURE_TENANT_ID.
2. Run the Infralib agent
Run it from the directory that contains config.yaml:
- AWS
- Google Cloud
- Oracle Cloud
- Azure
docker run -it --pull always --rm -v "$(pwd)":"/conf" \
-e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN -e AWS_REGION \
entigolabs/entigo-infralib-agent ei-agent run -c /conf/config.yaml
Set PROJECT_ID, LOCATION and ZONE first. Your gcloud credentials are mounted into the container.
docker run -it --pull always --rm -v "$(pwd)":"/conf" \
-v ~/.config/gcloud:/root/.config/gcloud \
-e PROJECT_ID -e LOCATION -e ZONE \
entigolabs/entigo-infralib-agent ei-agent run -c /conf/config.yaml
Set OCI_REGION and OCI_COMPARTMENT_ID first. Your ~/.oci credentials are mounted into the container at the same path, so the key path in ~/.oci/config resolves.
docker run -it --pull always --rm -v "$(pwd)":"/conf" \
-v "$HOME/.oci:$HOME/.oci:ro" -e OCI_CONFIG_FILE="$HOME/.oci/config" \
-e OCI_REGION -e OCI_COMPARTMENT_ID \
entigolabs/entigo-infralib-agent ei-agent run -c /conf/config.yaml
Set AZURE_SUBSCRIPTION_ID, AZURE_LOCATION and the service principal's AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET first.
docker run -it --pull always --rm -v "$(pwd)":"/conf" \
-e AZURE_TENANT_ID -e AZURE_CLIENT_ID -e AZURE_CLIENT_SECRET \
-e AZURE_SUBSCRIPTION_ID -e AZURE_LOCATION \
entigolabs/entigo-infralib-agent ei-agent run -c /conf/config.yaml
Or use your own az login session. The agent image has no az CLI, so this mounts the agent into the Azure CLI image and runs bootstrap, which starts the run in your subscription:
docker pull -q entigolabs/entigo-infralib-agent && \
docker run -it --pull always --rm -v "$(pwd)":/conf -v "$HOME/.azure:/root/.azure" \
--mount type=image,source=entigolabs/entigo-infralib-agent,image-subpath=usr/bin/ei-agent,target=/usr/local/bin/ei-agent \
-e AZURE_SUBSCRIPTION_ID -e AZURE_LOCATION \
mcr.microsoft.com/azure-cli ei-agent bootstrap -c /conf/config.yaml
The first run takes about 30 to 60 minutes. This is what happens:
- Prepare
Creates a bucket for its state, and one pipeline per step.
- Network
The network. On AWS also the DNS zone and TLS certificate. On Oracle Cloud also the encryption keys, a private CA, the DNS zone and TLS certificate.
- Kubernetes cluster
The cluster and its node groups.
- Applications
ArgoCD and the core services, installed through ArgoCD.
To run it in your cloud account instead of on your machine, use the bootstrap command.
3. Check the result
You now have:
- NetworkVPC and subnets
- DNS + TLSdev.<your domain>
- KubernetesEKS, GKE, OKE or AKS cluster
- ArgoCDWith the core services
Connect to your new cluster:
- AWS
- Google Cloud
- Oracle Cloud
- Azure
aws eks update-kubeconfig --region $AWS_REGION --name dev-infra-eks
kubectl get nodes
Find the cluster name in the Google Cloud console, then connect through its DNS endpoint. The IP endpoint is private; the DNS endpoint lets in only callers with IAM access to the cluster:
gcloud container clusters get-credentials <cluster-name> --project $PROJECT_ID --location $LOCATION --dns-endpoint
kubectl get nodes
The cluster is dev-infra-oke. create-kubeconfig needs its OCID, which the first command looks up:
CLUSTER_ID=$(oci ce cluster list --compartment-id $OCI_COMPARTMENT_ID --name dev-infra-oke \
--lifecycle-state ACTIVE --query 'data[0].id' --raw-output)
oci ce cluster create-kubeconfig --cluster-id $CLUSTER_ID --region $OCI_REGION \
--token-version 2.0.0 --kube-endpoint PUBLIC_ENDPOINT
kubectl get nodes
The cluster is dev-infra-aks in the resource group dev-<location> that the agent created. It signs you in with Entra ID through kubelogin, as the user whose object ID you put in admin_object_ids:
az login
az aks get-credentials --subscription $AZURE_SUBSCRIPTION_ID --resource-group dev-$AZURE_LOCATION --name dev-infra-aks
kubelogin convert-kubeconfig -l azurecli
kubectl get nodes
Sign in to ArgoCD as admin with the initial password:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d
4. Add the platform APIs
To create Zones, databases and everything else in the Guides, add the platform APIs to the apps step and run the Infralib agent again. The platform APIs currently run on AWS only.
Show the changes to the apps step
- name: apps
type: argocd-apps
modules:
# ...modules from step 1...
- name: crossplane-aws
source: crossplane-aws
inputs:
global:
createObservers: true
createNamespacedObservers: true
- name: external-secrets-{{ .config.prefix }}
source: external-secrets
inputs:
global:
createClusterSecretStore: true
- name: kyverno
source: kyverno
- name: crossplane-sql
source: crossplane-sql
- name: platform-apis
source: platform-apis
Change the existing crossplane-aws and external-secrets entries rather than adding second ones.
This unlocks:
5. Keep it up to date
Infralib releases tested updates several times a week. Apply them with the update command:
- AWS
- Google Cloud
- Oracle Cloud
- Azure
docker run -it --pull always --rm -v "$(pwd)":"/conf" \
-e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN -e AWS_REGION \
entigolabs/entigo-infralib-agent ei-agent update -c /conf/config.yaml
docker run -it --pull always --rm -v "$(pwd)":"/conf" \
-v ~/.config/gcloud:/root/.config/gcloud \
-e PROJECT_ID -e LOCATION -e ZONE \
entigolabs/entigo-infralib-agent ei-agent update -c /conf/config.yaml
docker run -it --pull always --rm -v "$(pwd)":"/conf" \
-v "$HOME/.oci:$HOME/.oci:ro" -e OCI_CONFIG_FILE="$HOME/.oci/config" \
-e OCI_REGION -e OCI_COMPARTMENT_ID \
entigolabs/entigo-infralib-agent ei-agent update -c /conf/config.yaml
docker run -it --pull always --rm -v "$(pwd)":"/conf" \
-e AZURE_TENANT_ID -e AZURE_CLIENT_ID -e AZURE_CLIENT_SECRET \
-e AZURE_SUBSCRIPTION_ID -e AZURE_LOCATION \
entigolabs/entigo-infralib-agent ei-agent update -c /conf/config.yaml
Or with your own az login session:
docker pull -q entigolabs/entigo-infralib-agent && \
docker run -it --pull always --rm -v "$(pwd)":/conf -v "$HOME/.azure:/root/.azure" \
--mount type=image,source=entigolabs/entigo-infralib-agent,image-subpath=usr/bin/ei-agent,target=/usr/local/bin/ei-agent \
-e AZURE_SUBSCRIPTION_ID -e AZURE_LOCATION \
mcr.microsoft.com/azure-cli ei-agent update -c /conf/config.yaml
By default:
- Updates that remove resources wait for your approval in the pipeline.
- All other updates apply automatically.
Breaking changes are announced in the Infralib release notes. Check them before updating, especially after skipping a few releases.
Next steps
- Create a Zone for your first application.
- Create a PostgreSQL Instance and the other Guides.
- The Infralib Quickstart for a deeper hands-on tour.