diff --git a/README.md b/README.md index 7962f04..0b53382 100644 --- a/README.md +++ b/README.md @@ -347,6 +347,10 @@ Namespace: default ``` +#### Additional examples + +More examples are available in the [examples](./examples) directory + ## Development After checking out the repo, run `bundle` to install dependencies. Then, run diff --git a/examples/deployment/README.md b/examples/deployment/README.md new file mode 100644 index 0000000..ac8154e --- /dev/null +++ b/examples/deployment/README.md @@ -0,0 +1,86 @@ +# Using kubetruth to deploy + +This example uses kubetruth to apply a kubernetes deployment whenever dependent parameters change (e.g. `image_version`) + +It provides 2 variants: + + * `values-simple.yaml`: + The deployment templates are fairly simple and hosted within the cloudtruth + templating system (`deploy.yaml.tmpl`). Sharing of templates across multiple + projects has not yet been implemented in the cloudtruth engine, so this + method is not very modular and you'll have to fully define the deployment + template for each project. However, it is a lot easier to grok + * `values-modular.yaml`: + The deployment templates are defined within kubetruth and as such can be + reused across multiple projects, as well as setting up the metadata to make + use of the kubetruth ability to apply to multiple namespaces/environments + within the same cluster + +If you set this up within your own infrastructure, then you can easily deploy +from CI after test/build by running the [cloudtruth cli to set the new version](#trigger-a-deploy). + +## Setup CloudTruth Credentials + +Login to CloudTruth, and create an api key, then add it to your environment + +``` +export CLOUDTRUTH_API_KEY=your_api_key +``` + +## Setup a project to configure the deploy + +``` +cloudtruth projects set deploytest + +cloudtruth --project deploytest parameter set --value nginx app_name +cloudtruth --project deploytest parameter set --value 80 app_port +cloudtruth --project deploytest parameter set --value nginx image_name +cloudtruth --project deploytest parameter set --value 1.20 image_version + +# Only needed when using the values-simple.yaml variant +cloudtruth --project deploytest template set --body examples/deployment/deploy.yaml.tmpl deployment +``` + +## (Optional) Setup [minikube](https://minikube.sigs.k8s.io/docs/start/) to test locally +``` +minikube start +``` + +## Setup kubetruth to apply a deployment resource for that project + +To try the simple variant, install kubetruth with the following settings: +``` +helm install --values examples/deployment/values-simple.yaml --set appSettings.apiKey=$CLOUDTRUTH_API_KEY kubetruth cloudtruth/kubetruth +``` + +OR to try the modular variant, install kubetruth like: +``` +helm install --values examples/deployment/values-complete.yaml --set appSettings.apiKey=$CLOUDTRUTH_API_KEY kubetruth cloudtruth/kubetruth +``` + +## Check kubetruth is up + +``` +kubectl describe deployment kubetruth +kubectl logs deployment/kubetruth +``` + +## Check service is up, note version + +``` +kubectl describe deployment nginx | grep -i image +minikube service nginx # force a 404 to see nginx version string +``` + +## Trigger a deploy + +``` +cloudtruth --project deploytest parameter set --value 1.21 image_version +``` + +## Check service is up, note version + +``` +kubectl describe deployment nginx | grep -i image +minikube service nginx # force a 404 to see nginx version string +``` diff --git a/examples/deployment/deploy.yaml.tmpl b/examples/deployment/deploy.yaml.tmpl new file mode 100644 index 0000000..1df0f6e --- /dev/null +++ b/examples/deployment/deploy.yaml.tmpl @@ -0,0 +1,37 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{app_name}} + labels: + app: {{app_name}} +spec: + replicas: 1 + selector: + matchLabels: + app: {{app_name}} + template: + metadata: + labels: + app: {{app_name}} + spec: + containers: + - name: {{image_name}} + image: {{image_name}}:{{image_version}} + ports: + - containerPort: {{app_port}} + envFrom: + - configMapRef: + name: deploytest +--- +apiVersion: v1 +kind: Service +metadata: + name: {{app_name}} +spec: + selector: + app: {{app_name}} + type: NodePort + ports: + - protocol: TCP + port: {{app_port}} + targetPort: {{app_port}} diff --git a/examples/deployment/values-modular.yaml b/examples/deployment/values-modular.yaml new file mode 100644 index 0000000..029cadc --- /dev/null +++ b/examples/deployment/values-modular.yaml @@ -0,0 +1,84 @@ +# Applying deployment resources requires additional permissions +rbac: + additionalRoleRules: + - apiGroups: ["", "extensions", "apps"] + resources: ["deployments", "replicasets", "pods", "services"] + verbs: ["*"] + +# Setup the kubetruth CRD to ignore all projects except for the one named deploytest +# For the deploytest project, get the resource template from the cloudtruth template named deployment +projectMappings: + + # Define the root project mapping, skipping all projects except for the + # example we care about + root: + scope: "root" + environment: default + skip: true + + # Define an override project mapping to enable processing of a single project + # for this example. This will also gain the default `resource_templates` for + # generating configmap and secret resource, but if not desired, those can be + # skipped by setting them to an empty string. + deploytest: + scope: "override" + skip: false + project_selector: "^deploytest$" + resource_templates: + # Uncomment below to skip the default templates, but note that you'll get + # an error unless you remove the configmap reference from the deployment + # template + # + # configmap: "" + # secret: "" + + # The deployment template that is only applied if there is an app_name + # parameter defined + deployment: | + {%- if parameters contains "app_name" %} + apiVersion: apps/v1 + kind: Deployment + metadata: + name: "{{ parameters.app_name }}" + namespace: "{{ context.resource_namespace }}" + labels: + version: "{{ parameters.image_version }}" + app: "{{ parameters.app_name }}" + spec: + replicas: 1 + selector: + matchLabels: + app: "{{ parameters.app_name }}" + template: + metadata: + labels: + app: "{{ parameters.app_name }}" + spec: + containers: + - name: "{{ parameters.image_name }}" + image: "{{parameters.image_name}}:{{parameters.image_version}}" + ports: + - containerPort: {{parameters.app_port}} + envFrom: + - configMapRef: + name: "{{ context.resource_name }}" + {%- endif %} + + # The service template that is only applied if an app_port is defined, + # thereby indicating this is a network service that needs a port exposed + service: | + {%- if parameters contains "app_port" %} + apiVersion: v1 + kind: Service + metadata: + name: "{{ parameters.app_name | dns_safe }}" + namespace: "{{ context.resource_namespace }}" + spec: + selector: + app: {{parameters.app_name}} + type: NodePort + ports: + - protocol: TCP + port: {{parameters.app_port}} + targetPort: {{parameters.app_port}} + {%- endif %} diff --git a/examples/deployment/values-simple.yaml b/examples/deployment/values-simple.yaml new file mode 100644 index 0000000..315e2c0 --- /dev/null +++ b/examples/deployment/values-simple.yaml @@ -0,0 +1,37 @@ +# Applying deployment resources requires additional permissions +rbac: + additionalRoleRules: + - apiGroups: ["", "extensions", "apps"] + resources: ["deployments", "replicasets", "pods", "services"] + verbs: ["*"] + +# Setup the kubetruth CRD to ignore all projects except for the one named deploytest +# For the deploytest project, get the resource template from the cloudtruth template named deployment +projectMappings: + + # Define the root project mapping, skipping all projects except for the + # example we care about + root: + scope: "root" + environment: default + skip: true + + # Define an override project mapping to enable processing of a single project + # for this example. This will also gain the default `resource_templates` for + # generating configmap and secret resource, but if not desired, those can be + # skipped by setting them to an empty string. + deploytest: + scope: "override" + skip: false + project_selector: "^deploytest$" + resource_templates: + # Uncomment below to skip the default templates, but note that you'll get + # an error unless you remove the configmap reference from the deployment + # template + # + # configmap: "" + # secret: "" + + # The kubetruth deployment template is a fetch of the generated cloudtruth + # template named deployment + deployment: "{{ templates.deployment }}"