Skip to content

Commit 37b21e3

Browse files
committed
Require one of kubeconfig_path or kubeconfig_raw fix #90
This commit changes the provider to require exactly one of `kubeconfig_path` or `kubeconfig_raw` set. The environment variable `KUBECONFIG_PATH` is available to set `kubeconfig_path`. Previously, the provider tried to find a valid configuration in either `kubeconfig_raw` or `kubeconfig_path` and would fall back to `kubectl` default environment variables and paths if no configuration was given.
1 parent bf0f4b8 commit 37b21e3

File tree

4 files changed

+67
-69
lines changed

4 files changed

+67
-69
lines changed

.github/workflows/main.yml

+11-14
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ jobs:
3535

3636
- name: 'Run TF acceptance tests (${{ matrix.runner }})'
3737
if: startsWith(matrix.runner, 'ubuntu-')
38-
run: |
39-
export KUBECONFIG="$(kind get kubeconfig-path --name="kind")"
40-
make test
4138
env:
42-
TF_ACC: '1'
39+
KUBECONFIG_PATH: ~/.kube/config
40+
run: make test
4341

4442
- name: 'Run TF unit tests (${{ matrix.runner }})'
4543
if: startsWith(matrix.runner, 'ubuntu-') == false
44+
env:
45+
KUBECONFIG_PATH: ~/.kube/config
4646
run: go test -v ./kustomize
4747

4848
compile_provider:
@@ -86,6 +86,9 @@ jobs:
8686
runs-on: ubuntu-latest
8787
needs: [compile_provider]
8888

89+
env:
90+
KUBECONFIG_PATH: ~/.kube/config
91+
8992
steps:
9093
- name: 'Checkout'
9194
uses: actions/checkout@v1
@@ -110,10 +113,6 @@ jobs:
110113
with:
111114
version: "v0.9.0"
112115

113-
- name: 'Set KUBECONFIG env var'
114-
run: |
115-
export KUBECONFIG="$(kind get kubeconfig-path --name="kind")"
116-
117116
- name: 'Terraform Init'
118117
run: terraform init
119118

@@ -150,10 +149,9 @@ jobs:
150149

151150
- name: 'Create provider.tf with kubeconfig_raw'
152151
run: |
153-
unset KUBECONFIG
154152
echo "provider "kustomization" {" > provider.tf
155153
echo " kubeconfig_raw = <<EOT" >> provider.tf
156-
cat $(kind get kubeconfig-path --name="kind") >> provider.tf
154+
kind get kubeconfig --name kind >> provider.tf
157155
echo "EOT" >> provider.tf
158156
echo "}" >> provider.tf
159157
@@ -167,6 +165,9 @@ jobs:
167165
runs-on: ubuntu-latest
168166
needs: [compile_provider]
169167

168+
env:
169+
KUBECONFIG_PATH: ~/.kube/config
170+
170171
steps:
171172
- name: 'Checkout'
172173
uses: actions/checkout@v1
@@ -191,10 +192,6 @@ jobs:
191192
- name: 'Ensure provider is executable'
192193
run: chmod +x terraform.d/plugins/registry.terraform.io/kbst/kustomization/1.0.0/linux_amd64/terraform-provider-kustomization_v1.0.0
193194

194-
- name: 'Set KUBECONFIG env var'
195-
run: |
196-
export KUBECONFIG="$(kind get kubeconfig-path --name="kind")"
197-
198195
- name: 'Download kustomize'
199196
run: |
200197
wget https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv3.5.4/kustomize_v3.5.4_linux_amd64.tar.gz

README.md

+5-15
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,7 @@
22

33
![Run Tests](https://github.com/kbst/terraform-provider-kustomize/workflows/Run%20Tests/badge.svg?branch=master&event=push)
44

5-
This provider aims to solve 3 common issues of applying a kustomization using kubectl by integrating Kustomize and Terraform.
6-
7-
1. Lack of feedback what changes will be applied.
8-
1. Resources from a previous apply not in the current apply are not purged.
9-
1. Immutable changes like e.g. changing a deployment's selector cause the apply to fail mid way.
10-
11-
To solve this the provider uses the Terraform state to show changes to each resource individually during plan as well as track resources in need of purging.
12-
13-
It also uses [server side dry runs](https://kubernetes.io/docs/reference/using-api/api-concepts/#dry-run) to validate changes to the desired state and translate this into a Terraform plan that will show if a resource will be updated in-place or requires a delete and recreate to apply the changes.
14-
15-
As such it can be useful both to replace kustomize/kubectl integrated into a Terraform configuration as a provisioner as well as standalone `kubectl diff/apply` steps in CI/CD.
5+
This provider is maintained as part of the [Terraform GitOps framework Kubestack](https://www.kubestack.com/).
166

177
## Using the Provider
188

@@ -25,16 +15,16 @@ The Terraform provider for Kustomize is available from the [Terraform registry](
2515

2616
## Building and Developing the Provider
2717

28-
To work on the provider, you need go installed on your machine (version 1.13.x tested). The provider uses go mod to manage its dependencies, so GOPATH is not required.
18+
To work on the provider, you need go installed on your machine. The provider uses go mod to manage its dependencies, so GOPATH is not required.
2919

3020
To compile the provider, run `make build` as shown below. This will build the provider and put the provider binary in the `terraform.d/plugins/linux_amd64/` directory.
3121

3222
```sh
33-
$ make build
23+
make build
3424
```
3525

36-
In order to test the provider, you can simply run the acceptance tests using `make test`. You can set the `KUBECONFIG` environment variable to point the tests to a specific cluster or set the context of your current config accordingly. The tests create namespaces on the current context. [Kind](https://github.com/kubernetes-sigs/kind) or [Minikube](https://github.com/kubernetes/minikube) clusters work well for testing.
26+
In order to test the provider, run the acceptance tests using `make test`. You have to set the `KUBECONFIG_PATH` environment variable to point the tests to a valid config file. Each tests uses an individual namespaces. [Kind](https://github.com/kubernetes-sigs/kind) or [Minikube](https://github.com/kubernetes/minikube) clusters work well for testing.
3727

3828
```sh
39-
$ make test
29+
make test
4030
```

docs/index.md

+22-13
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
# Kustomize Provider
22

3-
This provider aims to solve 3 common issues of applying a kustomization using kubectl by integrating Kustomize and Terraform.
3+
This provider allows building existing kustomizations using the `kustomization_build` data source or defining
4+
dynamic kustomizations in HCL using the `kustomization_overlay` data source and applying the resources from
5+
either kustomization against a Kubernetes cluster using the `kustomization_resource` resource.
46

5-
1. Lack of feedback what changes will be applied.
6-
1. Resources from a previous apply not in the current apply are not purged.
7-
1. Immutable changes like e.g. changing a deployment's selector cause the apply to fail mid way.
7+
The provider is maintained as part of the [Terraform GitOps framework Kubestack](https://www.kubestack.com/).
88

9-
To solve this the provider uses the Terraform state to show changes to each resource individually during plan as well as track resources in need of purging.
9+
Using this Kustomize provider and Terraform has three main benefits compared to applying a kustomization using `kubectl`:
1010

11-
It also uses [server side dry runs](https://kubernetes.io/docs/reference/using-api/api-concepts/#dry-run) to validate changes to the desired state and translate this into a Terraform plan that will show if a resource will be updated in-place or requires a delete and recreate to apply the changes.
11+
1. Running `terraform plan` will show a diff of the changes to be applied.
12+
1. Deleted resources from a previous configuration will be purged.
13+
1. Changes to immutable fields will generate a destroy and re-create plan.
1214

13-
As such it can be useful both to replace kustomize/kubectl integrated into a Terraform configuration as a provisioner as well as standalone `kubectl diff/apply` steps in CI/CD. The provider was primarily developed for Kubestack, the [Terraform GitOps framework](https://www.kubestack.com/), but is supported and tested to be used standalone.
15+
As such the provider can be useful to replace kustomize/kubectl integrated into a Terraform configuration as a provisioner or to replace standalone `kubectl diff/apply` steps in CI/CD.
1416

1517
## Example Usage
1618

@@ -19,21 +21,28 @@ terraform {
1921
required_providers {
2022
kustomization = {
2123
source = "kbst/kustomization"
22-
version = ">= 0.2"
24+
version = "0.5.0"
2325
}
2426
}
25-
required_version = ">= 0.12"
2627
}
2728
28-
provider "kustomization" {}
29+
provider "kustomization" {
30+
# one of kubeconfig_path or kubeconfig_raw is required
31+
32+
# kubeconfig_path = "~/.kube/config"
33+
# can also be set using KUBECONFIG_PATH environment variable
34+
35+
# kubeconfig_raw = data.template_file.kubeconfig.rendered
36+
# kubeconfig_raw = yamlencode(local.kubeconfig)
37+
}
2938
3039
```
3140

3241
## Argument Reference
3342

34-
- `kubeconfig_path` - (Optional) Path to a kubeconfig file. Defaults to `KUBECONFIG`, `KUBE_CONFIG` or `~/.kube/config`.
35-
- `kubeconfig_raw` - (Optional) Raw kubeconfig file. If kubeconfig_raw is set, kubeconfig_path is ignored.
36-
- `context` - (Optional) Context to use in kubeconfig with multiple contexts, if not specified the default context is to be used.
43+
- `kubeconfig_path` - (One of `kubeconfig_path` or `kubeconfig_raw` required) Path to a kubeconfig file. Can be set using `KUBECONFIG_PATH` environment variable.
44+
- `kubeconfig_raw` - (One of `kubeconfig_path` or `kubeconfig_raw` required) Raw kubeconfig file. If `kubeconfig_raw` is set, `kubeconfig_path` is ignored.
45+
- `context` - (Optional) Context to use in kubeconfig with multiple contexts, if not specified the default context is used.
3746

3847
## Imports
3948

kustomize/provider.go

+29-27
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ type Config struct {
2727
Mutex *sync.Mutex
2828
}
2929

30-
const kubeconfigDefault = "~/.kube/config"
31-
3230
// Provider ...
3331
func Provider() *schema.Provider {
3432
p := &schema.Provider{
@@ -48,21 +46,17 @@ func Provider() *schema.Provider {
4846

4947
Schema: map[string]*schema.Schema{
5048
"kubeconfig_path": {
51-
Type: schema.TypeString,
52-
Optional: true,
53-
DefaultFunc: schema.MultiEnvDefaultFunc(
54-
[]string{
55-
"KUBE_CONFIG",
56-
"KUBECONFIG",
57-
},
58-
kubeconfigDefault),
59-
Description: fmt.Sprintf("Path to a kubeconfig file. Defaults to '%s'.", kubeconfigDefault),
49+
Type: schema.TypeString,
50+
Optional: true,
51+
DefaultFunc: schema.EnvDefaultFunc("KUBECONFIG_PATH", nil),
52+
ExactlyOneOf: []string{"kubeconfig_path", "kubeconfig_raw"},
53+
Description: fmt.Sprintf("Path to a kubeconfig file. Can be set using KUBECONFIG_PATH env var. Either kubeconfig_path or kubeconfig_raw is required."),
6054
},
6155
"kubeconfig_raw": {
62-
Type: schema.TypeString,
63-
Optional: true,
64-
Default: "",
65-
Description: "Raw kubeconfig file. If kubeconfig_raw is set, kubeconfig_path is ignored.",
56+
Type: schema.TypeString,
57+
Optional: true,
58+
ExactlyOneOf: []string{"kubeconfig_path", "kubeconfig_raw"},
59+
Description: "Raw kube config. If kubeconfig_raw is set, kubeconfig_path is ignored.",
6660
},
6761
"context": {
6862
Type: schema.TypeString,
@@ -78,36 +72,44 @@ func Provider() *schema.Provider {
7872
var config *rest.Config
7973
var err error
8074

81-
context := d.Get("context").(string)
8275
raw := d.Get("kubeconfig_raw").(string)
83-
data = []byte(raw)
76+
path := d.Get("kubeconfig_path").(string)
77+
context := d.Get("context").(string)
8478

85-
// try to get a config from kubeconfig_raw
86-
config, err = getClientConfig(data, context)
87-
if err != nil {
88-
// if kubeconfig_raw did not work, try kubeconfig_path
89-
path := d.Get("kubeconfig_path").(string)
90-
data, _ = readKubeconfigFile(path)
79+
if raw != "" {
80+
config, err = getClientConfig([]byte(raw), context)
81+
if err != nil {
82+
return nil, fmt.Errorf("provider kustomization: kubeconfig_raw: %s", err)
83+
}
84+
}
9185

86+
if raw == "" && path != "" {
87+
data, _ = readKubeconfigFile(path)
9288
config, err = getClientConfig(data, context)
9389
if err != nil {
94-
// if neither worked we fall back to an empty default config
95-
config = &rest.Config{}
90+
return nil, fmt.Errorf("provider kustomization: kubeconfig_path: %s", err)
9691
}
9792
}
9893

94+
// empty default config required to support
95+
// using a cluster resource or data source
96+
// that may not exist yet, to configure the provider
97+
if config == nil {
98+
config = &rest.Config{}
99+
}
100+
99101
// Increase QPS and Burst rate limits
100102
config.QPS = 120
101103
config.Burst = 240
102104

103105
client, err := dynamic.NewForConfig(config)
104106
if err != nil {
105-
return nil, err
107+
return nil, fmt.Errorf("provider kustomization: %s", err)
106108
}
107109

108110
clientset, err := kubernetes.NewForConfig(config)
109111
if err != nil {
110-
return nil, err
112+
return nil, fmt.Errorf("provider kustomization: %s", err)
111113
}
112114

113115
cgvk := newCachedGroupVersionKind(clientset)

0 commit comments

Comments
 (0)