diff --git a/docs/learn/1007-kubernetes.md b/docs/learn/1007-kubernetes.md index 3e101250..46edd96c 100644 --- a/docs/learn/1007-kubernetes.md +++ b/docs/learn/1007-kubernetes.md @@ -752,96 +752,17 @@ of the language features. ### Convert Kubernetes objects to CUE -First, let's create re-usable definitions for the `deployment` and the `service` to remove a lot of boilerplate -and repetition. +First, let's create re-usable definitions for the `deployment` and the `service` to remove a lot of boilerplate and +repetition. Let's define a re-usable `#Deployment` definition in `kube/deployment.cue`. -```cue title="todoapp/kube/deployment.cue" -package main - -// Deployment template containing all the common boilerplate shared by -// deployments of this application. -#Deployment: { - // Name of the deployment. This will be used to label resources automatically - // and generate selectors. - name: string - - // Container image. - image: string - - // 80 is the default port. - port: *80 | int - - // 1 is the default, but we allow any number. - replicas: *1 | int - - // Deployment manifest. Uses the name, image, port and replicas above to - // generate the resource manifest. - manifest: { - apiVersion: "apps/v1" - kind: "Deployment" - metadata: { - "name": name - labels: app: name - } - spec: { - "replicas": replicas - selector: matchLabels: app: name - template: { - metadata: labels: app: name - spec: containers: [{ - "name": name - "image": image - ports: [{ - containerPort: port - }] - }] - } - } - } -} +```cue file=tests/kube-kind/cue-manifest/deployment.cue title="todoapp/kube/deployment.cue" ``` Indeed, let's also define a re-usable `#Service` definition in `kube/service.cue`. -```cue title="todoapp/kube/service.cue" -package main - -// Service template containing all the common boilerplate shared by -// services of this application. -#Service: { - // Name of the service. This will be used to label resources automatically - // and generate selector. - name: string - - // NodePort is the default service type. - type: *"NodePort" | "LoadBalancer" | "ClusterIP" | "ExternalName" - - // Ports where the service should listen - ports: [string]: number - - // Service manifest. Uses the name, type and ports above to - // generate the resource manifest. - manifest: { - apiVersion: "v1" - kind: "Service" - metadata: { - "name": "\(name)-service" - labels: app: name - } - spec: { - "type": type - "ports": [ - for k, v in ports { - "name": k - port: v - }, - ] - selector: app: name - } - } -} +```cue file=tests/kube-kind/cue-manifest/service.cue title="todoapp/kube/service.cue" ``` ### Generate Kubernetes manifest @@ -851,36 +772,7 @@ without having boilerplate nor repetition. Create a new definition named `#AppManifest` that will generate the YAML in `kube/manifest.cue`. -```cue title="todoapp/kube/manifest.cue" -package main - -import ( - "encoding/yaml" -) - -// Define and generate kubernetes deployment to deploy to kubernetes cluster -#AppManifest: { - // Name of the application - name: string - - // Image to deploy to - image: string - - // Define a kubernetes deployment object - deployment: #Deployment & { - "name": name - "image": image - } - - // Define a kubernetes service object - service: #Service & { - "name": name - ports: "http": deployment.port - } - - // Merge definitions and convert them back from CUE to YAML - manifest: yaml.MarshalStream([deployment.manifest, service.manifest]) -} +```cue file=tests/kube-kind/cue-manifest/manifest.cue title="todoapp/kube/manifest.cue" ``` ### Update manifest @@ -892,7 +784,8 @@ You can now remove the `manifest` input in `kube/todoapp.cue` and instead use th - removal of unused imported `encoding/yaml` and `kustomize` packages. - removal of `manifest` input that is doesn't need anymore. - removal of `kustomization` to replace it with `#AppManifest` definition. -- Update `kubeSrc` to use `manifest` field instead of `source` because we don't send Kubernetes manifest of `dagger.#Artifact` type anymore. +- Update `kubeSrc` to use `manifest` field instead of `source` because we don't send Kubernetes manifest + of `dagger.#Artifact` type anymore. -```cue title="todoapp/kube/todoapp.cue" -package main - -import ( - "alpha.dagger.io/dagger" - "alpha.dagger.io/docker" - "alpha.dagger.io/kubernetes" -) - -// input: source code repository, must contain a Dockerfile -// set with `dagger input dir repository . -e kube` -repository: dagger.#Artifact & dagger.#Input - -// Registry to push images to -registry: string & dagger.#Input -tag: "test-kind" - -// Todoapp deployment pipeline -todoApp: { - // Build the image from repositoru artifact - image: docker.#Build & { - source: repository - } - - // Push image to registry - remoteImage: docker.#Push & { - target: "\(registry):\(tag)" - source: image - } - - // Generate deployment manifest - deployment: #AppManifest & { - name: "todoapp" - image: remoteImage.ref - } - - // Deploy the customized manifest to a kubernetes cluster - kubeSrc: kubernetes.#Resources & { - "kubeconfig": kubeconfig - manifest: deployment.manifest - } -} +```cue file=tests/kube-kind/cue-manifest/todoapp.cue title="todoapp/kube/todoapp.cue" ``` diff --git a/docs/learn/tests/.dagger/env/kube-kind-cue-manifest/.gitignore b/docs/learn/tests/.dagger/env/kube-kind-cue-manifest/.gitignore new file mode 100644 index 00000000..01ec19b0 --- /dev/null +++ b/docs/learn/tests/.dagger/env/kube-kind-cue-manifest/.gitignore @@ -0,0 +1,2 @@ +# dagger state +state/** diff --git a/docs/learn/tests/.dagger/env/kube-kind-cue-manifest/values.yaml b/docs/learn/tests/.dagger/env/kube-kind-cue-manifest/values.yaml new file mode 100644 index 00000000..db84bd57 --- /dev/null +++ b/docs/learn/tests/.dagger/env/kube-kind-cue-manifest/values.yaml @@ -0,0 +1,26 @@ +plan: + package: ./kube-kind/cue-manifest +name: kube-kind-cue-manifest +inputs: + registry: + text: localhost:5000/kind +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0cks5RUFvcGZseFZUYkVT + azFieWVQZEhORFFFLysvVkJJMUZlZ3FxVFZVClRZSHNiMC91RGtWUjVDOEJlTisz + WjdmVW5Rc0wrbjYyZlNkMVE2Wkg5SzAKLS0tIFFmZFdSUFViR2tYTG9UMHYwNzNL + WkdkcFZvM2NtRUhtVzhxUWRZT1FCUEUKzUdfMTXsr2sdrG5B9qvdGrSMuvvJG2qB + eZWf3QbQBIk9OWcU14E1j+xUrR+tME7ABA2UD3/VpLxSEUI2Cp2VpA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2021-08-13T17:07:17Z" + mac: ENC[AES256_GCM,data:E00oUv3prQDGBxTysz71/lu0Y0uYPI7L6gRSz3uMmXsl2y/HPxt7F29vOuxj8BwkBiwFzq7aV3ql7S+EKLAFgCiN81PCAE51ObBceoZmAJNyTCRUzG+o8fIjCsIGfdMSOpoCvVIwQuB0YytICN0+zA/75JNzGvPAgStB7ZI9TPM=,iv:vN944S2hd1Is3UByevNXNB1oUmvMvx0f4LgxkId6vjI=,tag:aYbNEuz1Xs3Lpfjhb91BBA==,type:str] + pgp: [] + encrypted_suffix: secret + version: 3.7.1 diff --git a/docs/learn/tests/doc.bats b/docs/learn/tests/doc.bats index 8c3d9384..fbebeb08 100644 --- a/docs/learn/tests/doc.bats +++ b/docs/learn/tests/doc.bats @@ -95,8 +95,8 @@ setup() { # Clean kubectl delete deployments --all - #################### DEPLOYMENT #################### - copy_to_sandbox kube-kind-deployment kube-kind + #################### DEPLOYMENT #################### + copy_to_sandbox kube-kind-deployment kube-kind # Add kubeconfig dagger -w "$DAGGER_SANDBOX" -e kube-kind-deployment input text kubeconfig -f "$HOME"/.kube/config @@ -109,6 +109,21 @@ setup() { # Clean kubectl delete deployments --all + + #################### CUE MANIFEST #################### + copy_to_sandbox kube-kind-cue-manifest kube-kind + + # Add kubeconfig + dagger -w "$DAGGER_SANDBOX" -e kube-kind-cue-manifest input text kubeconfig -f "$HOME"/.kube/config + + # Up deployment + dagger -w "$DAGGER_SANDBOX" -e kube-kind-cue-manifest up + + # Check deployment + kubectl describe deployment todoapp | grep 'True' + + # Clean + kubectl delete deployments --all } @test "doc-1008-aws-cloudformation" { diff --git a/docs/learn/tests/kube-kind/basic/manifest.cue b/docs/learn/tests/kube-kind/basic/input.cue similarity index 100% rename from docs/learn/tests/kube-kind/basic/manifest.cue rename to docs/learn/tests/kube-kind/basic/input.cue diff --git a/docs/learn/tests/kube-kind/cue-manifest/deployment.cue b/docs/learn/tests/kube-kind/cue-manifest/deployment.cue new file mode 100644 index 00000000..88d7b800 --- /dev/null +++ b/docs/learn/tests/kube-kind/cue-manifest/deployment.cue @@ -0,0 +1,43 @@ +package main + +// Deployment template containing all the common boilerplate shared by +// deployments of this application. +#Deployment: { + // Name of the deployment. This will be used to label resources automatically + // and generate selectors. + name: string + + // Container image. + image: string + + // 80 is the default port. + port: *80 | int + + // 1 is the default, but we allow any number. + replicas: *1 | int + + // Deployment manifest. Uses the name, image, port and replicas above to + // generate the resource manifest. + manifest: { + apiVersion: "apps/v1" + kind: "Deployment" + metadata: { + "name": name + labels: app: name + } + spec: { + "replicas": replicas + selector: matchLabels: app: name + template: { + metadata: labels: app: name + spec: containers: [{ + "name": name + "image": image + ports: [{ + containerPort: port + }] + }] + } + } + } +} diff --git a/docs/learn/tests/kube-kind/cue-manifest/input.cue b/docs/learn/tests/kube-kind/cue-manifest/input.cue new file mode 100644 index 00000000..c7249135 --- /dev/null +++ b/docs/learn/tests/kube-kind/cue-manifest/input.cue @@ -0,0 +1,11 @@ +package main + +import ( + "alpha.dagger.io/git" +) + +repository: git.#Repository & { + remote: "https://github.com/dagger/examples.git" + ref: "main" + subdir: "todoapp" +} diff --git a/docs/learn/tests/kube-kind/cue-manifest/manifest.cue b/docs/learn/tests/kube-kind/cue-manifest/manifest.cue new file mode 100644 index 00000000..df4ff0d9 --- /dev/null +++ b/docs/learn/tests/kube-kind/cue-manifest/manifest.cue @@ -0,0 +1,29 @@ +package main + +import ( + "encoding/yaml" +) + +// Define and generate kubernetes deployment to deploy to kubernetes cluster +#AppManifest: { + // Name of the application + name: string + + // Image to deploy to + image: string + + // Define a kubernetes deployment object + deployment: #Deployment & { + "name": name + "image": image + } + + // Define a kubernetes service object + service: #Service & { + "name": name + ports: http: deployment.port + } + + // Merge definitions and convert them back from CUE to YAML + manifest: yaml.MarshalStream([deployment.manifest, service.manifest]) +} diff --git a/docs/learn/tests/kube-kind/cue-manifest/service.cue b/docs/learn/tests/kube-kind/cue-manifest/service.cue new file mode 100644 index 00000000..8c5dc957 --- /dev/null +++ b/docs/learn/tests/kube-kind/cue-manifest/service.cue @@ -0,0 +1,36 @@ +package main + +// Service template containing all the common boilerplate shared by +// services of this application. +#Service: { + // Name of the service. This will be used to label resources automatically + // and generate selector. + name: string + + // NodePort is the default service type. + type: *"NodePort" | "LoadBalancer" | "ClusterIP" | "ExternalName" + + // Ports where the service should listen + ports: [string]: number + + // Service manifest. Uses the name, type and ports above to + // generate the resource manifest. + manifest: { + apiVersion: "v1" + kind: "Service" + metadata: { + "name": "\(name)-service" + labels: app: name + } + spec: { + "type": type + "ports": [ + for k, v in ports { + name: k + port: v + }, + ] + selector: app: name + } + } +} diff --git a/docs/learn/tests/kube-kind/cue-manifest/todoapp.cue b/docs/learn/tests/kube-kind/cue-manifest/todoapp.cue new file mode 100644 index 00000000..9ffdbe33 --- /dev/null +++ b/docs/learn/tests/kube-kind/cue-manifest/todoapp.cue @@ -0,0 +1,41 @@ +package main + +import ( + "alpha.dagger.io/dagger" + "alpha.dagger.io/docker" + "alpha.dagger.io/kubernetes" +) + +// input: source code repository, must contain a Dockerfile +// set with `dagger input dir repository . -e kube` +repository: dagger.#Artifact & dagger.#Input + +// Registry to push images to +registry: string & dagger.#Input +tag: "test-kind" + +// Todoapp deployment pipeline +todoApp: { + // Build the image from repositoru artifact + image: docker.#Build & { + source: repository + } + + // Push image to registry + remoteImage: docker.#Push & { + target: "\(registry):\(tag)" + source: image + } + + // Generate deployment manifest + deployment: #AppManifest & { + name: "todoapp" + image: remoteImage.ref + } + + // Deploy the customized manifest to a kubernetes cluster + kubeSrc: kubernetes.#Resources & { + "kubeconfig": kubeconfig + manifest: deployment.manifest + } +} diff --git a/docs/learn/tests/kube-kind/deployment/manifest.cue b/docs/learn/tests/kube-kind/deployment/input.cue similarity index 100% rename from docs/learn/tests/kube-kind/deployment/manifest.cue rename to docs/learn/tests/kube-kind/deployment/input.cue