Skip to content

Commit 2f1dbef

Browse files
Merge pull request #389 from sirlatrom/fix-388
Support instance level CI variables
2 parents 15b441e + c379c2d commit 2f1dbef

File tree

5 files changed

+316
-0
lines changed

5 files changed

+316
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
layout: "gitlab"
3+
page_title: "GitLab: gitlab_instance_variable"
4+
sidebar_current: "docs-gitlab-resource-instance-variable"
5+
description: |-
6+
Creates and manages CI/CD variables for GitLab instances
7+
---
8+
9+
# gitlab\_instance\_variable
10+
11+
This resource allows you to create and manage CI/CD variables for your GitLab instance.
12+
For further information on variables, consult the [gitlab
13+
documentation](https://docs.gitlab.com/ee/api/instance_level_ci_variables.html).
14+
15+
## Example Usage
16+
17+
```hcl
18+
resource "gitlab_instance_variable" "example" {
19+
key = "instance_variable_key"
20+
value = "instance_variable_value"
21+
protected = false
22+
masked = false
23+
}
24+
```
25+
26+
## Argument Reference
27+
28+
The following arguments are supported:
29+
30+
* `key` - (Required, string) The name of the variable.
31+
32+
* `value` - (Required, string) The value of the variable.
33+
34+
* `variable_type` - (Optional, string) The type of a variable. Available types are: env_var (default) and file.
35+
36+
* `protected` - (Optional, boolean) If set to `true`, the variable will be passed only to pipelines running on protected branches and tags. Defaults to `false`.
37+
38+
* `masked` - (Optional, boolean) If set to `true`, the value of the variable will be hidden in job logs. The value must meet the [masking requirements](https://docs.gitlab.com/ee/ci/variables/#masked-variable-requirements). Defaults to `false`.
39+
40+
## Import
41+
42+
GitLab instance variables can be imported using an id made up of `variablename`, e.g.
43+
44+
```console
45+
$ terraform import gitlab_instance_variable.example instance_variable_key
46+
```

gitlab/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ func Provider() terraform.ResourceProvider {
9494
"gitlab_project_mirror": resourceGitlabProjectMirror(),
9595
"gitlab_project_level_mr_approvals": resourceGitlabProjectLevelMRApprovals(),
9696
"gitlab_project_approval_rule": resourceGitlabProjectApprovalRule(),
97+
"gitlab_instance_variable": resourceGitlabInstanceVariable(),
9798
},
9899
}
99100

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package gitlab
2+
3+
import (
4+
"log"
5+
"net/http"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
8+
gitlab "github.com/xanzy/go-gitlab"
9+
)
10+
11+
func resourceGitlabInstanceVariable() *schema.Resource {
12+
return &schema.Resource{
13+
Create: resourceGitlabInstanceVariableCreate,
14+
Read: resourceGitlabInstanceVariableRead,
15+
Update: resourceGitlabInstanceVariableUpdate,
16+
Delete: resourceGitlabInstanceVariableDelete,
17+
Importer: &schema.ResourceImporter{
18+
State: schema.ImportStatePassthrough,
19+
},
20+
21+
Schema: map[string]*schema.Schema{
22+
"key": {
23+
Type: schema.TypeString,
24+
ForceNew: true,
25+
Required: true,
26+
ValidateFunc: StringIsGitlabVariableName,
27+
},
28+
"value": {
29+
Type: schema.TypeString,
30+
Required: true,
31+
Sensitive: true,
32+
},
33+
"variable_type": {
34+
Type: schema.TypeString,
35+
Optional: true,
36+
Default: "env_var",
37+
ValidateFunc: StringIsGitlabVariableType,
38+
},
39+
"protected": {
40+
Type: schema.TypeBool,
41+
Optional: true,
42+
Default: false,
43+
},
44+
"masked": {
45+
Type: schema.TypeBool,
46+
Optional: true,
47+
Default: false,
48+
},
49+
},
50+
}
51+
}
52+
53+
func resourceGitlabInstanceVariableCreate(d *schema.ResourceData, meta interface{}) error {
54+
client := meta.(*gitlab.Client)
55+
56+
key := d.Get("key").(string)
57+
value := d.Get("value").(string)
58+
variableType := stringToVariableType(d.Get("variable_type").(string))
59+
protected := d.Get("protected").(bool)
60+
masked := d.Get("masked").(bool)
61+
62+
options := gitlab.CreateInstanceVariableOptions{
63+
Key: &key,
64+
Value: &value,
65+
VariableType: variableType,
66+
Protected: &protected,
67+
Masked: &masked,
68+
}
69+
log.Printf("[DEBUG] create gitlab instance level CI variable %s", key)
70+
71+
_, _, err := client.InstanceVariables.CreateVariable(&options)
72+
if err != nil {
73+
return err
74+
}
75+
76+
d.SetId(key)
77+
78+
return resourceGitlabInstanceVariableRead(d, meta)
79+
}
80+
81+
func resourceGitlabInstanceVariableRead(d *schema.ResourceData, meta interface{}) error {
82+
client := meta.(*gitlab.Client)
83+
84+
key := d.Id()
85+
86+
log.Printf("[DEBUG] read gitlab instance level CI variable %s", key)
87+
88+
v, resp, err := client.InstanceVariables.GetVariable(key)
89+
if err != nil {
90+
if resp.StatusCode == http.StatusNotFound {
91+
log.Printf("[DEBUG] gitlab instance level CI variable for %s not found so removing from state", d.Id())
92+
d.SetId("")
93+
return nil
94+
}
95+
return err
96+
}
97+
98+
d.Set("key", v.Key)
99+
d.Set("value", v.Value)
100+
d.Set("variable_type", v.VariableType)
101+
d.Set("protected", v.Protected)
102+
d.Set("masked", v.Masked)
103+
return nil
104+
}
105+
106+
func resourceGitlabInstanceVariableUpdate(d *schema.ResourceData, meta interface{}) error {
107+
client := meta.(*gitlab.Client)
108+
109+
key := d.Get("key").(string)
110+
value := d.Get("value").(string)
111+
variableType := stringToVariableType(d.Get("variable_type").(string))
112+
protected := d.Get("protected").(bool)
113+
masked := d.Get("masked").(bool)
114+
115+
options := &gitlab.UpdateInstanceVariableOptions{
116+
Value: &value,
117+
Protected: &protected,
118+
VariableType: variableType,
119+
Masked: &masked,
120+
}
121+
log.Printf("[DEBUG] update gitlab instance level CI variable %s", key)
122+
123+
_, _, err := client.InstanceVariables.UpdateVariable(key, options)
124+
if err != nil {
125+
return err
126+
}
127+
return resourceGitlabInstanceVariableRead(d, meta)
128+
}
129+
130+
func resourceGitlabInstanceVariableDelete(d *schema.ResourceData, meta interface{}) error {
131+
client := meta.(*gitlab.Client)
132+
key := d.Get("key").(string)
133+
log.Printf("[DEBUG] Delete gitlab instance level CI variable %s", key)
134+
135+
_, err := client.InstanceVariables.RemoveVariable(key)
136+
return err
137+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package gitlab
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
8+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
9+
"github.com/hashicorp/terraform-plugin-sdk/terraform"
10+
"github.com/xanzy/go-gitlab"
11+
)
12+
13+
func TestAccGitlabInstanceVariable_basic(t *testing.T) {
14+
var instanceVariable gitlab.InstanceVariable
15+
rString := acctest.RandString(5)
16+
17+
resource.Test(t, resource.TestCase{
18+
PreCheck: func() { testAccPreCheck(t) },
19+
Providers: testAccProviders,
20+
Steps: []resource.TestStep{
21+
// Create a variable with default options
22+
{
23+
Config: testAccGitlabInstanceVariableConfig(rString),
24+
Check: resource.ComposeTestCheckFunc(
25+
testAccCheckGitlabInstanceVariableExists("gitlab_instance_variable.foo", &instanceVariable),
26+
testAccCheckGitlabInstanceVariableAttributes(&instanceVariable, &testAccGitlabInstanceVariableExpectedAttributes{
27+
Key: fmt.Sprintf("key_%s", rString),
28+
Value: fmt.Sprintf("value-%s", rString),
29+
}),
30+
),
31+
},
32+
// Update the instance variable to toggle all the values to their inverse
33+
{
34+
Config: testAccGitlabInstanceVariableUpdateConfig(rString),
35+
Check: resource.ComposeTestCheckFunc(
36+
testAccCheckGitlabInstanceVariableExists("gitlab_instance_variable.foo", &instanceVariable),
37+
testAccCheckGitlabInstanceVariableAttributes(&instanceVariable, &testAccGitlabInstanceVariableExpectedAttributes{
38+
Key: fmt.Sprintf("key_%s", rString),
39+
Value: fmt.Sprintf("value-inverse-%s", rString),
40+
Protected: true,
41+
}),
42+
),
43+
},
44+
// Update the instance variable to toggle the options back
45+
{
46+
Config: testAccGitlabInstanceVariableConfig(rString),
47+
Check: resource.ComposeTestCheckFunc(
48+
testAccCheckGitlabInstanceVariableExists("gitlab_instance_variable.foo", &instanceVariable),
49+
testAccCheckGitlabInstanceVariableAttributes(&instanceVariable, &testAccGitlabInstanceVariableExpectedAttributes{
50+
Key: fmt.Sprintf("key_%s", rString),
51+
Value: fmt.Sprintf("value-%s", rString),
52+
Protected: false,
53+
}),
54+
),
55+
},
56+
},
57+
})
58+
}
59+
60+
func testAccCheckGitlabInstanceVariableExists(n string, instanceVariable *gitlab.InstanceVariable) resource.TestCheckFunc {
61+
return func(s *terraform.State) error {
62+
rs, ok := s.RootModule().Resources[n]
63+
if !ok {
64+
return fmt.Errorf("Not Found: %s", n)
65+
}
66+
67+
key := rs.Primary.Attributes["key"]
68+
if key == "" {
69+
return fmt.Errorf("No variable key is set")
70+
}
71+
conn := testAccProvider.Meta().(*gitlab.Client)
72+
73+
gotVariable, _, err := conn.InstanceVariables.GetVariable(key)
74+
if err != nil {
75+
return err
76+
}
77+
*instanceVariable = *gotVariable
78+
return nil
79+
}
80+
}
81+
82+
type testAccGitlabInstanceVariableExpectedAttributes struct {
83+
Key string
84+
Value string
85+
Protected bool
86+
Masked bool
87+
}
88+
89+
func testAccCheckGitlabInstanceVariableAttributes(variable *gitlab.InstanceVariable, want *testAccGitlabInstanceVariableExpectedAttributes) resource.TestCheckFunc {
90+
return func(s *terraform.State) error {
91+
if variable.Key != want.Key {
92+
return fmt.Errorf("got key %s; want %s", variable.Key, want.Key)
93+
}
94+
95+
if variable.Value != want.Value {
96+
return fmt.Errorf("got value %s; value %s", variable.Value, want.Value)
97+
}
98+
99+
if variable.Protected != want.Protected {
100+
return fmt.Errorf("got protected %t; want %t", variable.Protected, want.Protected)
101+
}
102+
103+
if variable.Masked != want.Masked {
104+
return fmt.Errorf("got masked %t; want %t", variable.Masked, want.Masked)
105+
}
106+
107+
return nil
108+
}
109+
}
110+
111+
func testAccGitlabInstanceVariableConfig(rString string) string {
112+
return fmt.Sprintf(`
113+
resource "gitlab_instance_variable" "foo" {
114+
key = "key_%s"
115+
value = "value-%s"
116+
variable_type = "file"
117+
masked = false
118+
}
119+
`, rString, rString)
120+
}
121+
122+
func testAccGitlabInstanceVariableUpdateConfig(rString string) string {
123+
return fmt.Sprintf(`
124+
resource "gitlab_instance_variable" "foo" {
125+
key = "key_%s"
126+
value = "value-inverse-%s"
127+
protected = true
128+
masked = false
129+
}
130+
`, rString, rString)
131+
}

vendor/github.com/xanzy/go-gitlab/gitlab.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)