Skip to content
This repository has been archived by the owner on Nov 20, 2024. It is now read-only.

Store workspace outputs as secrets #80

Merged
merged 4 commits into from
Nov 17, 2020
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
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
## 0.1.6-alpha (November 09, 2020)

Upgrade notes:
This version moves storage of outputs from ConfigMaps to Secrets.
The first time the operator runs it will create new Secrets containing
the workspace's outputs, and it will keep updating only those for
subsequent runs. Old ConfigMaps will be left for the users to delete
when they are ready.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice upgrade notes! I like that users can take this at their own pace, rather than having the ConfigMap automatically deleted.

* Support for VCS backed workspaces. ([#70](https://github.com/hashicorp/terraform-k8s/pull/70))
* Decouple the operator from the Terraform version used in a workspace ([77](https://github.com/hashicorp/terraform-k8s/pull/77))
* Fix bug with timing of configuration version status ([78](https://github.com/hashicorp/terraform-k8s/pull/78))
* Store outputs in k8s Secret objects instead of ConfigMap objects ([80](https://github.com/hashicorp/terraform-k8s/pull/80))

## 0.1.5-alpha (May 20, 2020)

* Upgrade go-tfe to v0.7.0 and dependencies
Expand Down
449 changes: 222 additions & 227 deletions deploy/crds/app.terraform.io_workspaces_crd.yaml

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ require (
github.com/hashicorp/terraform v0.13.4
github.com/mitchellh/cli v1.1.1
github.com/operator-framework/operator-sdk v0.18.0
github.com/pkg/sftp v1.12.0 // indirect
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.6.1
github.com/zclconf/go-cty v1.5.1
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect
k8s.io/api v0.18.2
k8s.io/apimachinery v0.18.2
k8s.io/client-go v12.0.0+incompatible
Expand Down
46 changes: 0 additions & 46 deletions go.sum

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion pkg/apis/app/v1alpha1/workspace_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ type WorkspaceSpec struct {
Outputs []*OutputSpec `json:"outputs,omitempty"`
// Terraform version used for this workspace. The default is `latest`.
// +optional
// +kubebuilder:default=latest
TerraformVersion string `json:"terraformVersion"`
}

Expand Down
37 changes: 19 additions & 18 deletions pkg/controller/workspace/k8s_configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ func configMapForTerraform(name string, namespace string, template []byte) *core
}
}

func configMapForOutputs(name string, namespace string, outputs []*v1alpha1.OutputStatus) *corev1.ConfigMap {
func secretForOutputs(name string, namespace string, outputs []*v1alpha1.OutputStatus) *corev1.Secret {
data := outputsToMap(outputs)
return &corev1.ConfigMap{
return &corev1.Secret {
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Data: *data,
Data: data,
}
}

Expand Down Expand Up @@ -102,41 +102,42 @@ func (r *ReconcileWorkspace) GetConfigMapForVariable(namespace string, variable
return nil
}

func outputsToMap(outputs []*v1alpha1.OutputStatus) *map[string]string {
data := map[string]string{}
func outputsToMap(outputs []*v1alpha1.OutputStatus) map[string][]byte {
data := map[string][]byte{}
for _, output := range outputs {
data[output.Key] = output.Value
data[output.Key] = []byte(output.Value)
}
return &data
return data
}

// UpsertOutputs creates a ConfigMap for the outputs
func (r *ReconcileWorkspace) UpsertOutputs(w *v1alpha1.Workspace, outputs []*v1alpha1.OutputStatus) error {
found := &corev1.ConfigMap{}
// UpsertSecretOutputs creates a Secret for the outputs
func (r *ReconcileWorkspace) UpsertSecretOutputs(w *v1alpha1.Workspace, outputs []*v1alpha1.OutputStatus) error {
found := &corev1.Secret{}
outputName := fmt.Sprintf("%s-outputs", w.Name)
err := r.client.Get(context.TODO(), types.NamespacedName{Name: outputName, Namespace: w.Namespace}, found)
if err != nil && k8serrors.IsNotFound(err) {
configMap := configMapForOutputs(outputName, w.Namespace, outputs)
err = controllerutil.SetControllerReference(w, configMap, r.scheme)
secret := secretForOutputs(outputName, w.Namespace, outputs)
err = controllerutil.SetControllerReference(w, secret, r.scheme)
if err != nil {
return err
}
r.reqLogger.Info("Writing outputs to new ConfigMap")
if err := r.client.Create(context.TODO(), configMap); err != nil {
r.reqLogger.Error(err, "Failed to create new output ConfigMap")
r.reqLogger.Info("Writing outputs to new Secret")
if err := r.client.Create(context.TODO(), secret); err != nil {
r.reqLogger.Error(err, "Failed to create new output secrets")
return err
}
return nil
} else if err != nil {
r.reqLogger.Error(err, "Failed to get output ConfigMap")
r.reqLogger.Error(err, "Failed to get output secrets")
return err
}

currentOutputs := outputsToMap(outputs)
if !reflect.DeepEqual(found.Data, currentOutputs) {
found.Data = *currentOutputs
r.reqLogger.Info("Updating secrets", "name", outputName)
found.Data = currentOutputs
if err := r.client.Update(context.TODO(), found); err != nil {
r.reqLogger.Error(err, "Failed to update output ConfigMap", "Namespace", w.Namespace, "Name", outputName)
r.reqLogger.Error(err, "Failed to update output secrets", "Namespace", w.Namespace, "Name", outputName)
return err
}
return nil
Expand Down
9 changes: 8 additions & 1 deletion pkg/controller/workspace/tfc_org.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,17 @@ func (t *TerraformCloudClient) CheckWorkspace(workspace string, instance *appv1a

// CreateWorkspace creates a Terraform Cloud Workspace that auto-applies
func (t *TerraformCloudClient) CreateWorkspace(workspace string, instance *appv1alpha1.Workspace) (string, error) {
var tfVersion string
if instance.Spec.TerraformVersion == "" {
tfVersion = "latest"
} else {
tfVersion = instance.Spec.TerraformVersion
}

options := tfc.WorkspaceCreateOptions{
AutoApply: &AutoApply,
Name: &workspace,
TerraformVersion: &instance.Spec.TerraformVersion,
TerraformVersion: &tfVersion,
}

if instance.Spec.VCS != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/controller/workspace/workspace_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,8 @@ func (r *ReconcileWorkspace) processFinishedRun(instance *appv1alpha1.Workspace)
r.recorder.Event(instance, corev1.EventTypeNormal, "WorkspaceEvent",
fmt.Sprintf("Updated outputs for run %s", instance.Status.RunID))
}
if err = r.UpsertOutputs(instance, instance.Status.Outputs); err != nil {
r.reqLogger.Error(err, "Error with creating ConfigMap for Terraform Outputs")
if err = r.UpsertSecretOutputs(instance, instance.Status.Outputs); err != nil {
r.reqLogger.Error(err, "Error with creating Secret for Terraform Outputs")
return err
}
return nil
Expand Down