Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(helm-chart): support adding providers/plugins #310

Merged
merged 1 commit into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 26 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@
- [Testing the Deployment](#testing-the-deployment)

## Introduction

This chart creates a single pod in a StatefulSet running Atlantis. Atlantis persists Terraform [plan files](https://www.terraform.io/docs/commands/plan.html) and [lockfiles](https://www.terraform.io/docs/state/locking.html) to disk for the duration of a Pull/Merge Request. These files are stored in a PersistentVolumeClaim to survive Pod failures.

## Prerequisites

- Kubernetes 1.9+
- PersistentVolume support

## Required Configuration

In order for Atlantis to start and run successfully:

1. At least one of the following sets of credentials must be defined:
- `github`
- `gitlab`
Expand Down Expand Up @@ -53,6 +57,7 @@ extraManifests:
```

## Customization

The following options are supported. See [values.yaml](/charts/atlantis/values.yaml) for more detailed documentation and examples:

| Parameter | Description | Default |
Expand Down Expand Up @@ -132,6 +137,7 @@ The following options are supported. See [values.yaml](/charts/atlantis/values.y
| `ingress.path` | Path to use in the `Ingress`. Should be set to `/*` if using gce-ingress in Google Cloud. | `/` |
| `ingress.tls` | Kubernetes tls block. See [Kubernetes docs](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls) for details. | `[]` |
| `initContainers` | Containers used to initialize context for Atlantis pods | `[]` |
| `initConfig` | Init container used to install plugins/providers shared with Atlantis pods | n/a |
| `lifecycle` | Configure pod container lifecycle hooks. See [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/) for details. | `{}` |
| `loadEnvFromConfigMaps` | Array of Kubernetes `ConfigMap`s to set all key-value pairs as environment variables. See `values.yaml` for example. | `[]` |
| `loadEnvFromSecrets` | Array of Kubernetes secrets to set all key-value pairs as environment variables. See `values.yaml` for example. | `[]` |
Expand Down Expand Up @@ -189,20 +195,22 @@ The following options are supported. See [values.yaml](/charts/atlantis/values.y
## Upgrading

### From `4.0.*` to `4.1.*`
* The following value are deprecated:
* `dataStorage`
* `storageClassName`
* In favor of the new working way:
* `volumeClaim.enabled`
* `volumeClaim.dataStorage`
* `volumeClaim.storageClassName`

- The following value are deprecated:
- `dataStorage`
- `storageClassName`

- In favor of the new working way:
- `volumeClaim.enabled`
- `volumeClaim.dataStorage`
- `volumeClaim.storageClassName`

### From `2.*` to `3.*`

* The following value names have been removed. They are replaced by [Server-side Repository Configuration](https://www.runatlantis.io/docs/server-side-repo-config.html)
* `requireApproval`
* `requireMergeable`
* `allowRepoConfig`
- The following value names have been removed. They are replaced by [Server-side Repository Configuration](https://www.runatlantis.io/docs/server-side-repo-config.html)
- `requireApproval`
- `requireMergeable`
- `allowRepoConfig`

To replicate your previous configuration, run Atlantis locally with your previous flags and Atlantis will print out the equivalent repo-config, for example:

Expand Down Expand Up @@ -234,14 +242,15 @@ repoConfig: |
```

### From `1.*` to `2.*`
* The following value names have changed:
* `allow_repo_config` => `allowRepoConfig`
* `atlantis_data_storage` => `dataStorage` **NOTE: more than just a snake_case change**
* `atlantis_data_storageClass` => `storageClassName` **NOTE: more than just a snake_case change**
* `bitbucket.base_url` => `bitbucket.baseURL`

- The following value names have changed:
- `allow_repo_config` => `allowRepoConfig`
- `atlantis_data_storage` => `dataStorage` **NOTE: more than just a snake_case change**
- `atlantis_data_storageClass` => `storageClassName` **NOTE: more than just a snake_case change**
- `bitbucket.base_url` => `bitbucket.baseURL`

## Testing the Deployment

To perform a smoke test of the deployment (i.e. ensure that the Atlantis UI is up and running):

1. Install the chart. Supply your own values file or use `test-values.yaml`, which has a minimal set of values required in order for Atlantis to start.
Expand All @@ -252,6 +261,7 @@ To perform a smoke test of the deployment (i.e. ensure that the Atlantis UI is u
```

1. Run the tests:

```bash
helm test my-atlantis
```
2 changes: 1 addition & 1 deletion charts/atlantis/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: v1
appVersion: v0.26.0
description: A Helm chart for Atlantis https://www.runatlantis.io
name: atlantis
version: 4.17.5
version: 4.18.0
keywords:
- terraform
home: https://www.runatlantis.io
Expand Down
22 changes: 22 additions & 0 deletions charts/atlantis/ci/ci-init-config-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
github:
user: foo
token: bar
secret: baz

service:
type: ClusterIP

ingress:
enabled: true
ingressClassName: nginx
host: atlantis.localdev.me
path: /
webhook_ingress:
enabled: true
ingressClassName: nginx
host: atlantis-webook.localdev.me
path: /events

initConfig:
enabled: true
11 changes: 11 additions & 0 deletions charts/atlantis/templates/configmap-init-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{- if .Values.initConfig.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "atlantis.fullname" . }}-init-config
labels:
{{- include "atlantis.labels" . | nindent 4 }}
data:
init-config.sh: |
{{- .Values.initConfig.script | nindent 4 }}
{{- end -}}
73 changes: 60 additions & 13 deletions charts/atlantis/templates/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ spec:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap-config.yaml") . | sha256sum }}
checksum/repo-config: {{ include (print $.Template.BasePath "/configmap-repo-config.yaml") . | sha256sum }}
{{- if .Values.podTemplate.annotations }}
{{ toYaml .Values.podTemplate.annotations | indent 8 }}
{{- end }}
{{- if .Values.initConfig.enabled }}
checksum/init-config: {{ include (print $.Template.BasePath "/configmap-init-config.yaml") . | sha256sum }}
{{- end }}
{{- if .Values.podTemplate.annotations }}
{{- toYaml .Values.podTemplate.annotations | nindent 8 }}
{{- end }}
spec:
{{- if .Values.hostAliases }}
hostAliases:
Expand Down Expand Up @@ -123,17 +126,50 @@ spec:
secretName: {{ .Values.customPem }}
{{- end }}
{{- if .Values.extraVolumes }}
{{ toYaml .Values.extraVolumes | indent 6 }}
{{- toYaml .Values.extraVolumes | nindent 6 }}
{{- end }}
{{- if .Values.initConfig.enabled }}
- name: init-config
configMap:
name: {{ template "atlantis.fullname" . }}-init-config
items:
- key: init-config.sh
path: init-config.sh
mode: 0555
- name: init-shared-path
emptyDir:
sizeLimit: {{ .Values.initConfig.sizeLimit }}
{{- end }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.imagePullSecrets }}
- name: {{ . }}
{{- end }}
{{- end }}
{{- if .Values.initContainers }}
{{- if or .Values.initContainers .Values.initConfig.enabled }}
initContainers:
{{ toYaml .Values.initContainers | indent 8 }}
{{- with .Values.initContainers }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.initConfig.enabled }}
- name: init-config
image: {{ .Values.initConfig.image }}
imagePullPolicy: {{ .Values.initConfig.pullPolicy }}
command:
- /init-config.sh
workingDir: {{ .Values.initConfig.workDir }}
env:
- name: PATH
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:{{ .Values.initConfig.sharedDir }}
- name: INIT_SHARED_DIR
value: {{ .Values.initConfig.sharedDir }}
volumeMounts:
- name: init-config
mountPath: /init-config.sh
subPath: init-config.sh
- name: init-shared-path
mountPath: {{ .Values.initConfig.sharedDir }}
{{- end }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
Expand Down Expand Up @@ -408,6 +444,12 @@ spec:
- name: AWS_CONFIG_FILE
value: {{ .Values.aws.directory }}/config
{{- end }}
{{- if .Values.initConfig.enabled }}
- name: PATH
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:{{ .Values.initConfig.sharedDir }}
- name: INIT_SHARED_DIR
value: {{ .Values.initConfig.sharedDir }}
{{- end }}
{{- if .Values.livenessProbe.enabled }}
livenessProbe:
httpGet:
Expand Down Expand Up @@ -499,32 +541,37 @@ spec:
subPath: ca-certificates.crt
{{- end }}
{{- if .Values.extraVolumeMounts }}
{{ toYaml .Values.extraVolumeMounts | indent 10 }}
{{- toYaml .Values.extraVolumeMounts | nindent 10 }}
{{- end }}
{{- if .Values.initConfig.enabled }}
- name: init-shared-path
mountPath: {{ .Values.initConfig.sharedDir }}
readOnly: true
{{- end }}
resources:
{{ toYaml .Values.resources | indent 12 }}
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.extraContainers }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.topologySpreadConstraints }}
topologySpreadConstraints:
{{ toYaml . | indent 8 }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.statefulSet.updateStrategy }}
updateStrategy:
{{ toYaml . | indent 4 }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if .Values.dataStorage }}
volumeClaimTemplates:
Expand Down
42 changes: 36 additions & 6 deletions charts/atlantis/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -977,19 +977,49 @@
"$ref":"#/definitions/io.k8s.api.core.v1.Container"
},
"type":"array",
"default":[

]
"default":[]
},
"initConfig":{
"type":"object",
"description":"Init container used to install plugins/providers shared with Atlantis pods",
"properties":{
"enabled":{
"type":"boolean",
"description":"Enable creation of init config"
},
"image":{
"type":"string",
"description":"Container image to use on init configs"
},
"imagePullPolicy":{
"type":"string",
"description":"Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images"
},
"sharedDir":{
"type":"string",
"description":"sharedDir is set as env var INIT_SHARED_DIR"
},
"workDir":{
"type":"string",
"description":"Starting directory for the script"
},
"sizeLimit":{
"type":"string",
"description":"Size for the init-shared-path emptyDir volume"
},
"script":{
"type":"string",
"description":"Script to install tools/providers required by the atlantis pod"
}
}
},
"hostAliases":{
"description":"Specify HostAliases for Atlantis containers.",
"items":{
"$ref":"#/definitions/io.k8s.api.core.v1.HostAlias"
},
"type":"array",
"default":[

],
"default":[],
"examples":[
{
"ip":"127.0.0.2",
Expand Down
35 changes: 35 additions & 0 deletions charts/atlantis/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,41 @@ initContainers: []
# image: alpine:latest
# command: ['sh', '-c', 'echo The init container is running! && sleep 10']

# Install providers/plugins into a path shared with the Atlantis pod
initConfig:
enabled: false
image: alpine:latest
imagePullPolicy: IfNotPresent
# sharedDir is set as env var INIT_SHARED_DIR
sharedDir: /plugins
workDir: /tmp
sizeLimit: 100Mi
# example of how the script can be configured to install tools/providers required by the atlantis pod
script: |
#!/bin/sh
set -eoux pipefail

# example for terragrunt
TG_VERSION="v0.47.0"
TG_SHA256_SUM="98d45f6bfbfae84b51364c1ad6920f09ecb4d834908b0535e4e331a9fc6fc75b"
TG_FILE="${INIT_SHARED_DIR}/terragrunt"
wget https://github.com/gruntwork-io/terragrunt/releases/download/${TG_VERSION}/terragrunt_linux_amd64 -O "${TG_FILE}"
echo "${TG_SHA256_SUM} ${TG_FILE}" | sha256sum -c
chmod 755 "${TG_FILE}"
terragrunt -v

# example for terragrunt-atlantis-config
TAC_VERSION="1.16.0" # without v
TAC_SHA256_SUM="fc3b069cf4ae51e9b7a7d01f09862d1974b260fffb3ec857d661d7b1756fe26f"
TAC_FILE="${INIT_SHARED_DIR}/terragrunt-atlantis-config"
wget "https://github.com/transcend-io/terragrunt-atlantis-config/releases/download/v${TAC_VERSION}/terragrunt-atlantis-config_${TAC_VERSION}_linux_amd64.tar.gz"
echo "${TAC_SHA256_SUM} terragrunt-atlantis-config_${TAC_VERSION}_linux_amd64.tar.gz" | sha256sum -c
tar xf "terragrunt-atlantis-config_${TAC_VERSION}_linux_amd64.tar.gz"
cp -fv "terragrunt-atlantis-config_${TAC_VERSION}_linux_amd64/terragrunt-atlantis-config_${TAC_VERSION}_linux_amd64" "${TAC_FILE}"
chmod 755 "${TG_FILE}"
terragrunt-atlantis-config version


# hostAliases:
# - hostnames:
# - aaa.com
Expand Down