Spinnaker Stage Bake (Manifest): Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
No edit summary
 
(32 intermediate revisions by the same user not shown)
Line 3: Line 3:
=Internal=
=Internal=
* [[Spinnaker_Concepts#Bake_.28Manifest.29|Spinnaker Concepts]]
* [[Spinnaker_Concepts#Bake_.28Manifest.29|Spinnaker Concepts]]
* [[Spinnaker_Create_a_Deployment_Pipeline#Render_Helm|Create a Deployment Pipeline]]
* [[Spinnaker_Create_a_Deployment_Pipeline_from_UI#Render_Helm|Create a Deployment Pipeline]]
* [[Spinnaker_Stage_Deploy_(Manifest)#Overview|Deploy (Manifest)]]
* [[Spinnaker_Stage_Deploy_(Manifest)#Overview|Deploy (Manifest)]]


Line 20: Line 20:
===Helm Options===
===Helm Options===
====Name====
====Name====
The Helm release name for the chart: "myapp". <font color=darkkhaki>It determines the name of the artifact produced by this stage</font>. This name will override the "'''Match Artifact/Name'''" specified in the [[#Produces_Artifact|Produces Artifact]] section.
A name that represents the artifact produced by this stage. It is logically equivalent to Helm <code>[[Helm_Chart_Chart.yaml#Overview|Chart.yaml]]</code> <code>[[Helm_Chart_Chart.yaml#name|.Chart.Name]]</code>.
 
The most obvious choice is to use the same value as the one carried by <code>Chart.yaml</code>. If a different value is used, the behavior depends on the chart implementation.
 
The value is referred in several places in the internal representation of the stage, and it is used in the definition of the externally exported artifact, defined in the [[#Produces_Artifact|Produces Artifacts]] section. It also surfaces in the name of the Kubernetes resources created after chart deployment.


====Namespace====
====Namespace====
The target namespace to release into. If not specified, "default" will be used. ⚠️ There were (yet not elucidated) situations when even if a specific namespace was configured here, the deployment went to "default". That was fixed by [[Spinnaker_Stage_Deploy_(Manifest)#Override_Namespace|overriding the namespace]] in the Deploy (Manifest) stage.
The target namespace to release into.  
 
Spinnaker takes the value declared here and replaces all <code>&#123;{  .Release.Namespace }}</code> references throughout all rendered manifests. Note that <code>&#123;{  .Release.Namespace }}</code> may appear in the <code>.metadata.namespace</code> configuration element of the manifest, which determines which namespace the specific manifest will be sent to, and other constructs as well. All occurrences will be replaced.
 
To ensure that the manifest will be sent to the namespace configured as Bake (Manifest) → Helm Options → Namespace , make sure that the manifest explicitly contains:
 
<syntaxhighlight lang='yaml'>
metadata:
  namespace: {{ .Release.Namespace }}
</syntaxhighlight>
 
Note that the value configured here can be overwritten by the Deploy (Manifest) → Basic Settings → Override Namespace option. For more details, see:
 
{{Internal|Spinnaker_Stage_Deploy_(Manifest)#Override_Namespace|Deploy (Manifest) → Basic Settings → Override Namespace}}
 
If the manifest does not contain the explicit <code>.metadata.namespace</code> setting to <code>&#123;{  .Release.Namespace }}</code>, explicitly configuring a namespace to Bake (Manifest) → Helm Options → Namespace  leads to the unintuitive behavior of a "default" namespace deployment. So, if the manifest does not contain <code>.metadata.namespace: &#123;{  .Release.Namespace }}</code>, and you want to deploy into a specific namespace, use "will-be-overridden-by-subsequent-stages" here, and then configure the namespace to be deployed into in Deploy (Manifest) → Basic Settings → Override Namespace.
 
If Bake (Manifest) → Helm Options → Namespace is left empty, all  <code>&#123;{  .Release.Namespace }}</code> are replaced with "spinnaker".


===Template Artifact===
===Template Artifact===
Line 44: Line 65:


====Helm Repository====
====Helm Repository====
<font color=darkkhaki>TODO</font>
The Helm Repository must have been already "onboarded" and should be selected by name. Once selected, it should allow browsing the charts and their version from the dropdown box.
 
Alternatively, the chart can be also pulled from a straight HTTP repository, where the helm chart version is provided as a [[Spinnaker_Concepts#Parameter|pipeline parameter]].
 
[[File:Helm_Chart_via_HTTP.png|1200px]]


===Overrides===
===Overrides===
Line 57: Line 82:


Commit/Branch: <code>develop</code>
Commit/Branch: <code>develop</code>
Alternatively, the full override can be specified in-line as: Expected Artifact → Artifact from execution context → embedded-artifact. Name: "in-line overlay"


====Overrides====
====Overrides====
Line 64: Line 92:
! Value
! Value
|-
|-
| <tt>image.tag</tt> || <tt>${trigger['tag']}</tt>
| <tt>image.tag</tt> || <tt>${trigger['tag']}</tt> or <tt>${myapp_image_tag}</tt> (depending on how the tag is specified)
|-
|-
|}
|}
Line 71: Line 99:
====Raw Overrides====
====Raw Overrides====
Use <code>--set</code> instead of <code>--set-string</code> when injecting override values. Values injected using <code>--set</code> will be converted to primitive types by Helm.
Use <code>--set</code> instead of <code>--set-string</code> when injecting override values. Values injected using <code>--set</code> will be converted to primitive types by Helm.
Not usually something that is selected.
====Expression Evaluation====
====Expression Evaluation====
'''Evaluate SpEL expressions in overrides at bake time'''
'''Evaluate SpEL expressions in overrides at bake time'''
Line 76: Line 107:
Explicitly evaluate SpEL expressions in overrides just prior to manifest baking. Can be paired with the "Skip SpEL evaluation" option in the Deploy Manifest stage when baking a third-party manifest artifact with expressions not meant for Spinnaker to evaluate as SpEL.
Explicitly evaluate SpEL expressions in overrides just prior to manifest baking. Can be paired with the "Skip SpEL evaluation" option in the Deploy Manifest stage when baking a third-party manifest artifact with expressions not meant for Spinnaker to evaluate as SpEL.


Turn it on if the image tag is generated dynamically from <code>${trigger['tag']}</code>.
Turn it on if the image tag is generated dynamically from <code>${trigger['tag']}</code> or from <code>${myapp_image_tag}</code>.


==Execution Options==
==Execution Options==
Line 83: Line 114:
By default, Spinnaker automatically creates an <code>embedded/base64</code> artifact that is bound when the stage completes, representing the full manifest set to be deployed downstream.
By default, Spinnaker automatically creates an <code>embedded/base64</code> artifact that is bound when the stage completes, representing the full manifest set to be deployed downstream.


⚠️ It is a good idea to change the name from automatically generated ("nervous-lionfish-4") to something more intuitive ("rendered-helm-chart")
⚠️ It is a good idea to change the name from automatically generated ("nervous-lionfish-4") to something more intuitive ("rendered_helm_chart"). The produced artifact is linked to the rendered Helm chart by the value of [[#Name|Helm Options → Name]].
 
<br>
<br>
:::[[File:Spinnaker_Bake_Manifest_Produces_Artifact.png|700px]]


==Comments==
==Comments==

Latest revision as of 03:33, 31 May 2023

External

Internal

Overview

This stage renders the final form of a manifest or a multi-document manifest set, using a template renderer such as Helm.

Configuration

Add stage → Type: Bake (Manifest)

Type: Bake (Manifest)

Stage Name: Render Helm Chart

Bake (Manifest) Configuration

Template Renderer

Render Engine: HELM3

Helm Options

Name

A name that represents the artifact produced by this stage. It is logically equivalent to Helm Chart.yaml .Chart.Name.

The most obvious choice is to use the same value as the one carried by Chart.yaml. If a different value is used, the behavior depends on the chart implementation.

The value is referred in several places in the internal representation of the stage, and it is used in the definition of the externally exported artifact, defined in the Produces Artifacts section. It also surfaces in the name of the Kubernetes resources created after chart deployment.

Namespace

The target namespace to release into.

Spinnaker takes the value declared here and replaces all {{ .Release.Namespace }} references throughout all rendered manifests. Note that {{ .Release.Namespace }} may appear in the .metadata.namespace configuration element of the manifest, which determines which namespace the specific manifest will be sent to, and other constructs as well. All occurrences will be replaced.

To ensure that the manifest will be sent to the namespace configured as Bake (Manifest) → Helm Options → Namespace , make sure that the manifest explicitly contains:

metadata:
  namespace: {{ .Release.Namespace }}

Note that the value configured here can be overwritten by the Deploy (Manifest) → Basic Settings → Override Namespace option. For more details, see:

Deploy (Manifest) → Basic Settings → Override Namespace

If the manifest does not contain the explicit .metadata.namespace setting to {{ .Release.Namespace }}, explicitly configuring a namespace to Bake (Manifest) → Helm Options → Namespace leads to the unintuitive behavior of a "default" namespace deployment. So, if the manifest does not contain .metadata.namespace: {{ .Release.Namespace }}, and you want to deploy into a specific namespace, use "will-be-overridden-by-subsequent-stages" here, and then configure the namespace to be deployed into in Deploy (Manifest) → Basic Settings → Override Namespace.

If Bake (Manifest) → Helm Options → Namespace is left empty, all {{ .Release.Namespace }} are replaced with "spinnaker".

Template Artifact

Expected Artifact → Define Artifact → "Artifact from execution context".

To define the helm chart to render, there are two choices: Helm repository or GitHub repository. In both cases, the chart to be deployed must be stored remotely as a .tar.gz archive.

GitHub Repository for Helm Chart

Account: GitHub

Content URL: https://github.domain.com/api/v3/repos/<organization>/<repository>/contents/<path-inside-repository>. The branch will be specified at the next step. Example: https://github.domain.com/api/v3/repos/ovidiuf/smoke/contents/tmp/smoke-1.0.0.tgz

Commit/Branch: develop

Note that the GitHub repository must be configured for Spinnaker access.

The documentation seems to suggest that the chart can be stored in the GitHub repository in an exploded format, and the path to the Chart.yaml is sufficient, either the path to the file itself or the path to the directory containing Chart.yaml., but that is not actually the case. An attempt to use an exploded chart ended in:

Status: 500, URL: http://clouddriver.spinnaker:8000/artifacts/fetch/, Message: Cannot deserialize instance of  com.netflix.spinnaker.clouddriver.artifacts.github.GitHubArtifactCredentials$ContentMetadata out of START_ARRAY token at [Source: (String)"[{"name":"Chart.yaml","path":"src/main/helm/spinnaker-  smoke/Chart.yaml","sha":"2cf3c0f610396ed86b3da9f02391a3471c71003f","size":51,"url":"https://github.example.com/api/v3/repos/my-org/smoke/contents/src/main/helm/spinnaker-smoke/Chart.yaml?ref=spinnakerization","html_url":"https://github.example.com/my-org/smoke/blob/spinnakerization/src/main/helm/spinnaker-smoke/Chart.yaml","git_url":"https://github.example.com/api/v3/repos/my-org/smoke/git/blobs/2cf3c0f610396ed86"[truncated 3758 chars]; line: 1, column: 1]

Helm Repository

The Helm Repository must have been already "onboarded" and should be selected by name. Once selected, it should allow browsing the charts and their version from the dropdown box.

Alternatively, the chart can be also pulled from a straight HTTP repository, where the helm chart version is provided as a pipeline parameter.

Helm Chart via HTTP.png

Overrides

Expected Artifact

The files passed to --values parameter must be added as "Overrides/value artifact".

This is where a configuration file exposed in a configuration repository can be added. The configuration should be: Overrides → Add value artifact → Expected Artifact → Define a new artifact → Artifact from execution context

Account: github

Content URL: https://github.example.com/api/v3/repos/ovidiuf/configuration-repo/contents/environments/my-env/my-app/config.yaml

Commit/Branch: develop


Alternatively, the full override can be specified in-line as: Expected Artifact → Artifact from execution context → embedded-artifact. Name: "in-line overlay"

Overrides

Individually specified overrides can also be set in form of key/value pairs. Example of how to update the image tag based on tag read by the Docker trigger:

Key Value
image.tag ${trigger['tag']} or ${myapp_image_tag} (depending on how the tag is specified)

If expressions are evaluated when the manifest is rendered, make sure to turn Expression Evaluation Evaluate SpEL expressions in overrides at bake time on.

Raw Overrides

Use --set instead of --set-string when injecting override values. Values injected using --set will be converted to primitive types by Helm.

Not usually something that is selected.

Expression Evaluation

Evaluate SpEL expressions in overrides at bake time

Explicitly evaluate SpEL expressions in overrides just prior to manifest baking. Can be paired with the "Skip SpEL evaluation" option in the Deploy Manifest stage when baking a third-party manifest artifact with expressions not meant for Spinnaker to evaluate as SpEL.

Turn it on if the image tag is generated dynamically from ${trigger['tag']} or from ${myapp_image_tag}.

Execution Options

Notifications

Produces Artifact

By default, Spinnaker automatically creates an embedded/base64 artifact that is bound when the stage completes, representing the full manifest set to be deployed downstream.

⚠️ It is a good idea to change the name from automatically generated ("nervous-lionfish-4") to something more intuitive ("rendered_helm_chart"). The produced artifact is linked to the rendered Helm chart by the value of Helm Options → Name.



Spinnaker Bake Manifest Produces Artifact.png

Comments

Example of Configured Stage

{
  "expectedArtifacts": [
    {
      "defaultArtifact": {
        "customKind": true,
        "id": "a3b15bdc-8f73-4265-ba38-9be06cd6b4f2"
      },
      "displayName": "rendered-helm-chart",
      "id": "c7202ead-c6f9-497a-9120-1957688ed2d8",
      "matchArtifact": {
        "artifactAccount": "embedded-artifact",
        "customKind": false,
        "id": "22a48f2b-2b62-46bd-9964-68b406a3c1c8",
        "type": "embedded/base64"
      },
      "useDefaultArtifact": false,
      "usePriorArtifact": false
    }
  ],
  "inputArtifacts": [
    {
      "account": "github",
      "artifact": {
        "artifactAccount": "github",
        "id": "75ebe7b2-b04a-4fcd-a712-c7eacb06c348",
        "name": "tmp/smoke-0.1.0.tgz",
        "reference": "https://github.example.com/api/v3/repos/ovidiuf/smoke/contents/tmp/smoke-0.1.0.tgz",
        "type": "github/file",
        "version": "develop"
      }
    }
  ],
  "name": "Render Helm",
  "namespace": "of",
  "outputName": "smoke",
  "overrides": {},
  "templateRenderer": "HELM3",
  "type": "bakeManifest"
}