Skip to content

Commit cf631fd

Browse files
authored
SCALRCORE-35600 - BE > Serverless Agent pools > provider support (#450)
* SCALRCORE-35600 - BE > Serverless Agent pools > provider support * SCALRCORE-35600 - BE > Serverless Agent pools > provider support * SCALRCORE-35600 - BE > Serverless Agent pools > provider support * SCALRCORE-35600 - BE > Serverless Agent pools > provider support
1 parent cc97e51 commit cf631fd

File tree

9 files changed

+207
-12
lines changed

9 files changed

+207
-12
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- `scalr_agent_pool`: new arguments `api_gateway_url` and `header`. ([#450](https://github.com/Scalr/terraform-provider-scalr/pull/450))
13+
1014
## [3.6.0] - 2025-08-08
1115

1216
### Fixed

docs/data-sources/agent_pool.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,16 @@ data "scalr_agent_pool" "example2" {
3737

3838
### Read-Only
3939

40+
- `api_gateway_url` (String) HTTP(s) destination URL for pool webhook.
4041
- `environments` (Set of String) The list of the environment identifiers that the agent pool is shared to, or `["*"]` if shared with all environments.
42+
- `header` (Set of Object) Additional headers to set in the pool webhook request. (see [below for nested schema](#nestedatt--header))
4143
- `workspace_ids` (List of String) The list of IDs of linked workspaces.
44+
45+
<a id="nestedatt--header"></a>
46+
### Nested Schema for `header`
47+
48+
Read-Only:
49+
50+
- `name` (String)
51+
- `sensitive` (Boolean)
52+
- `value` (String)

docs/resources/agent_pool.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,28 @@ resource "scalr_agent_pool" "default" {
2929
### Optional
3030

3131
- `account_id` (String, Deprecated) ID of the account.
32+
- `api_gateway_url` (String) HTTP(s) destination URL for pool webhook.
3233
- `environment_id` (String, Deprecated) ID of the environment.
3334
- `environments` (Set of String) The list of the environment identifiers that the agent pool is shared to. Use `["*"]` to share with all environments.
35+
- `header` (Block Set) Additional headers to set in the agent pool webhook request. (see [below for nested schema](#nestedblock--header))
3436
- `vcs_enabled` (Boolean) Indicates whether the VCS support is enabled for agents in the pool.
3537

3638
### Read-Only
3739

3840
- `id` (String) The ID of this resource.
3941

42+
<a id="nestedblock--header"></a>
43+
### Nested Schema for `header`
44+
45+
Required:
46+
47+
- `name` (String) The name of the header.
48+
- `value` (String) The value of the header.
49+
50+
Optional:
51+
52+
- `sensitive` (Boolean) Whether the header value is a secret.
53+
4054
## Import
4155

4256
Import is supported using the following syntax:

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ require (
1616
github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0
1717
github.com/hashicorp/terraform-plugin-testing v1.11.0
1818
github.com/hashicorp/terraform-svchost v0.1.1
19-
github.com/scalr/go-scalr v0.0.0-20250731123843-2fa05f0d9908
19+
github.com/scalr/go-scalr v0.0.0-20250806171926-c0ff01eddf22
2020
)
2121

2222
require (

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO
201201
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
202202
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
203203
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
204-
github.com/scalr/go-scalr v0.0.0-20250731123843-2fa05f0d9908 h1:3GdutYCDNn4dtqU1Qu1qheLx8a++2VGULJrErCiD9EU=
205-
github.com/scalr/go-scalr v0.0.0-20250731123843-2fa05f0d9908/go.mod h1:Om3UIkHGeOcUK72OzjWI1GlS/hFyY8RRLxgbO0ZPsn4=
204+
github.com/scalr/go-scalr v0.0.0-20250806171926-c0ff01eddf22 h1:kSHV8OOFjvwKlOgHJmMylx57T+m+/lTfvJl6CMAhcq4=
205+
github.com/scalr/go-scalr v0.0.0-20250806171926-c0ff01eddf22/go.mod h1:Om3UIkHGeOcUK72OzjWI1GlS/hFyY8RRLxgbO0ZPsn4=
206206
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
207207
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
208208
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=

internal/provider/data_source_scalr_agent_pool.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,36 @@ func dataSourceScalrAgentPool() *schema.Resource {
6666
Computed: true,
6767
Elem: &schema.Schema{Type: schema.TypeString},
6868
},
69+
70+
"header": {
71+
Description: "Additional headers to set in the pool webhook request.",
72+
Type: schema.TypeSet,
73+
Computed: true,
74+
Elem: &schema.Resource{
75+
Schema: map[string]*schema.Schema{
76+
"name": {
77+
Description: "The name of the header.",
78+
Type: schema.TypeString,
79+
Computed: true,
80+
},
81+
"value": {
82+
Description: "The value of the header.",
83+
Type: schema.TypeString,
84+
Computed: true,
85+
},
86+
"sensitive": {
87+
Description: "Whether the header value is a secret.",
88+
Type: schema.TypeBool,
89+
Computed: true,
90+
},
91+
},
92+
},
93+
},
94+
"api_gateway_url": {
95+
Description: "HTTP(s) destination URL for pool webhook.",
96+
Type: schema.TypeString,
97+
Computed: true,
98+
},
6999
},
70100
}
71101
}
@@ -134,6 +164,21 @@ func dataSourceScalrAgentPoolRead(ctx context.Context, d *schema.ResourceData, m
134164
}
135165
_ = d.Set("vcs_enabled", agentPool.VcsEnabled)
136166
_ = d.Set("name", agentPool.Name)
167+
if agentPool.WebhookEnabled {
168+
_ = d.Set("api_gateway_url", agentPool.WebhookUrl)
169+
170+
headers := make([]map[string]interface{}, 0)
171+
if agentPool.WebhookHeaders != nil {
172+
for _, header := range agentPool.WebhookHeaders {
173+
headers = append(headers, map[string]interface{}{
174+
"name": header.Name,
175+
"value": header.Value,
176+
"sensitive": header.Sensitive,
177+
})
178+
}
179+
}
180+
_ = d.Set("header", headers)
181+
}
137182
d.SetId(agentPool.ID)
138183

139184
return nil

internal/provider/data_source_scalr_agent_pool_test.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@ func TestAccScalrAgentPoolDataSource_basic(t *testing.T) {
3333
Check: resource.ComposeAggregateTestCheckFunc(
3434
testAccCheckEqualID("data.scalr_agent_pool.test", "scalr_agent_pool.test"),
3535
resource.TestCheckResourceAttrSet("data.scalr_agent_pool.test", "id"),
36-
resource.TestCheckResourceAttr("data.scalr_agent_pool.test", "name", "ds-agent_pool-test-acc"),
36+
resource.TestCheckResourceAttr("data.scalr_agent_pool.test", "name", "ds-agent_pool-test-env"),
3737
resource.TestCheckResourceAttr("data.scalr_agent_pool.test", "account_id", defaultAccount),
38+
resource.TestCheckResourceAttr("scalr_agent_pool.test", "api_gateway_url", "https://example.com"),
39+
resource.TestCheckResourceAttr("scalr_agent_pool.test", "header.0.name", "Authorization"),
40+
resource.TestCheckResourceAttr("scalr_agent_pool.test", "header.0.value", "1234567890"),
3841
resource.TestCheckResourceAttr(
3942
"data.scalr_agent_pool.test", "environments.#", "1"),
4043
resource.TestCheckResourceAttrPair(
@@ -47,7 +50,7 @@ func TestAccScalrAgentPoolDataSource_basic(t *testing.T) {
4750
{
4851
Config: testAccScalrAgentPoolAccountDataSourceByNameConfig,
4952
Check: resource.ComposeAggregateTestCheckFunc(
50-
testAccCheckEqualID("data.scalr_agent_pool.test", "scalr_agent_pool.test"),
53+
testAccCheckEqualID("data.scalr_agent_pool.test", "scalr_agent_pool.test-by-name"),
5154
resource.TestCheckResourceAttrSet("data.scalr_agent_pool.test", "id"),
5255
resource.TestCheckResourceAttr("data.scalr_agent_pool.test", "name", "ds-agent_pool-test-acc"),
5356
resource.TestCheckResourceAttr("data.scalr_agent_pool.test", "account_id", defaultAccount),
@@ -58,7 +61,7 @@ func TestAccScalrAgentPoolDataSource_basic(t *testing.T) {
5861
Check: resource.ComposeAggregateTestCheckFunc(
5962
testAccCheckEqualID("data.scalr_agent_pool.test", "scalr_agent_pool.test"),
6063
resource.TestCheckResourceAttrSet("data.scalr_agent_pool.test", "id"),
61-
resource.TestCheckResourceAttr("data.scalr_agent_pool.test", "name", "ds-agent_pool-test-acc"),
64+
resource.TestCheckResourceAttr("data.scalr_agent_pool.test", "name", "ds-agent_pool-test-acc-id-and-name"),
6265
resource.TestCheckResourceAttr("data.scalr_agent_pool.test", "account_id", defaultAccount),
6366
),
6467
},
@@ -90,8 +93,13 @@ resource scalr_environment test-new {
9093
}
9194
9295
resource "scalr_agent_pool" "test" {
93-
name = "ds-agent_pool-test-acc"
96+
name = "ds-agent_pool-test-env"
9497
environments = [scalr_environment.test-new.id]
98+
api_gateway_url = "https://example.com"
99+
header {
100+
name = "Authorization"
101+
value = "1234567890"
102+
}
95103
}
96104
97105
data "scalr_agent_pool" "test" {
@@ -100,19 +108,19 @@ data "scalr_agent_pool" "test" {
100108
}`, defaultAccount)
101109

102110
var testAccScalrAgentPoolAccountDataSourceByNameConfig = fmt.Sprintf(`
103-
resource "scalr_agent_pool" "test" {
111+
resource "scalr_agent_pool" "test-by-name" {
104112
name = "ds-agent_pool-test-acc"
105113
account_id = "%s"
106114
}
107115
108116
data "scalr_agent_pool" "test" {
109-
name = scalr_agent_pool.test.name
110-
account_id = scalr_agent_pool.test.account_id
117+
name = scalr_agent_pool.test-by-name.name
118+
account_id = scalr_agent_pool.test-by-name.account_id
111119
}`, defaultAccount)
112120

113121
var testAccScalrAgentPoolAccountDataSourceByIDAndNameConfig = fmt.Sprintf(`
114122
resource "scalr_agent_pool" "test" {
115-
name = "ds-agent_pool-test-acc"
123+
name = "ds-agent_pool-test-acc-id-and-name"
116124
account_id = "%s"
117125
}
118126

internal/provider/resource_scalr_agent_pool.go

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"errors"
66
"log"
77

8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
9+
810
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
911

1012
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -50,7 +52,39 @@ func resourceScalrAgentPool() *schema.Resource {
5052
Optional: true,
5153
Default: false,
5254
},
53-
55+
"api_gateway_url": {
56+
Description: "HTTP(s) destination URL for pool webhook.",
57+
Type: schema.TypeString,
58+
Optional: true,
59+
ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotWhiteSpace),
60+
},
61+
"header": {
62+
Description: "Additional headers to set in the agent pool webhook request.",
63+
Type: schema.TypeSet,
64+
Optional: true,
65+
Elem: &schema.Resource{
66+
Schema: map[string]*schema.Schema{
67+
"name": {
68+
Description: "The name of the header.",
69+
Type: schema.TypeString,
70+
Required: true,
71+
ValidateFunc: validation.StringIsNotWhiteSpace,
72+
},
73+
"value": {
74+
Description: "The value of the header.",
75+
Type: schema.TypeString,
76+
Required: true,
77+
ValidateFunc: validation.StringIsNotWhiteSpace,
78+
},
79+
"sensitive": {
80+
Description: "Whether the header value is a secret.",
81+
Type: schema.TypeBool,
82+
Optional: true,
83+
Default: false,
84+
},
85+
},
86+
},
87+
},
5488
"environments": {
5589
Description: "The list of the environment identifiers that the agent pool is shared to. Use `[\"*\"]` to share with all environments.",
5690
Type: schema.TypeSet,
@@ -65,6 +99,20 @@ func resourceScalrAgentPool() *schema.Resource {
6599
}
66100
}
67101

102+
func parsePoolHeaders(d *schema.ResourceData) []*scalr.AgentPoolHeader {
103+
headers := d.Get("header").(*schema.Set)
104+
headerValues := make([]*scalr.AgentPoolHeader, 0)
105+
for _, headerI := range headers.List() {
106+
header := headerI.(map[string]interface{})
107+
headerValues = append(headerValues, &scalr.AgentPoolHeader{
108+
Name: header["name"].(string),
109+
Value: header["value"].(string),
110+
Sensitive: header["sensitive"].(bool),
111+
})
112+
}
113+
return headerValues
114+
}
115+
68116
func resourceScalrAgentPoolCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
69117
scalrClient := meta.(*scalr.Client)
70118
var envID string
@@ -86,6 +134,11 @@ func resourceScalrAgentPoolCreate(ctx context.Context, d *schema.ResourceData, m
86134
}
87135
}
88136

137+
if v, ok := d.GetOk("api_gateway_url"); ok {
138+
options.WebhookUrl = ptr(v.(string))
139+
options.WebhookEnabled = ptr(true)
140+
}
141+
89142
if environmentsI, ok := d.GetOk("environments"); ok {
90143
environments := environmentsI.(*schema.Set).List()
91144
if (len(environments) == 1) && (environments[0].(string) == "*") {
@@ -110,6 +163,10 @@ func resourceScalrAgentPoolCreate(ctx context.Context, d *schema.ResourceData, m
110163
}
111164
}
112165

166+
if _, ok := d.GetOk("header"); ok {
167+
options.WebhookHeaders = parsePoolHeaders(d)
168+
}
169+
113170
log.Printf("[DEBUG] Creating agent pool %s. Environment: %s", name, envID)
114171
agentPool, err := scalrClient.AgentPools.Create(ctx, options)
115172
if err != nil {
@@ -154,6 +211,32 @@ func resourceScalrAgentPoolRead(ctx context.Context, d *schema.ResourceData, met
154211
}
155212
_ = d.Set("environments", environmentIDs)
156213
}
214+
215+
if agentPool.WebhookEnabled {
216+
_ = d.Set("api_gateway_url", agentPool.WebhookUrl)
217+
headers := make([]map[string]interface{}, 0)
218+
if agentPool.WebhookHeaders != nil {
219+
_, doesConfigHasHeaders := d.GetOk("header")
220+
for _, header := range agentPool.WebhookHeaders {
221+
if header.Sensitive && doesConfigHasHeaders {
222+
for _, headerI := range d.Get("header").(*schema.Set).List() {
223+
configHeader := headerI.(map[string]interface{})
224+
if header.Name == configHeader["name"] {
225+
header.Value = configHeader["value"].(string)
226+
}
227+
}
228+
}
229+
230+
headers = append(headers, map[string]interface{}{
231+
"name": header.Name,
232+
"value": header.Value,
233+
"sensitive": header.Sensitive,
234+
})
235+
}
236+
}
237+
_ = d.Set("header", headers)
238+
}
239+
157240
return nil
158241
}
159242

@@ -200,6 +283,17 @@ func resourceScalrAgentPoolUpdate(ctx context.Context, d *schema.ResourceData, m
200283
options.Environments = make([]*scalr.Environment, 0)
201284
}
202285

286+
if d.HasChange("api_gateway_url") {
287+
url := d.Get("api_gateway_url").(string)
288+
options.WebhookUrl = ptr(url)
289+
options.WebhookEnabled = ptr(len(url) > 0)
290+
291+
}
292+
293+
if d.HasChange("header") {
294+
options.WebhookHeaders = parsePoolHeaders(d)
295+
}
296+
203297
log.Printf("[DEBUG] Update agent pool %s", id)
204298
_, err := scalrClient.AgentPools.Update(ctx, id, options)
205299
if err != nil {

internal/provider/resource_scalr_agent_pool_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ func TestAccScalrAgentPool_basic(t *testing.T) {
2727
),
2828
resource.TestCheckResourceAttr("scalr_agent_pool.test", "account_id", defaultAccount),
2929
resource.TestCheckResourceAttr("scalr_agent_pool.test", "environments.0", "*"),
30+
resource.TestCheckResourceAttr("scalr_agent_pool.test", "api_gateway_url", "https://example.com"),
31+
resource.TestCheckResourceAttr("scalr_agent_pool.test", "header.0.name", "Authorization"),
32+
resource.TestCheckResourceAttr("scalr_agent_pool.test", "header.0.value", "1234567890"),
33+
resource.TestCheckResourceAttr("scalr_agent_pool.test", "header.0.sensitive", "false"),
3034
),
3135
},
3236
},
@@ -57,6 +61,10 @@ func TestAccScalrAgentPool_update(t *testing.T) {
5761
Check: resource.ComposeTestCheckFunc(
5862
testAccCheckScalrAgentPoolExists("scalr_agent_pool.test", pool),
5963
resource.TestCheckResourceAttr("scalr_agent_pool.test", "name", "agent_pool-updated"),
64+
resource.TestCheckResourceAttr("scalr_agent_pool.test", "api_gateway_url", "https://example.com/new"),
65+
resource.TestCheckResourceAttr("scalr_agent_pool.test", "header.0.name", "Authorization"),
66+
resource.TestCheckResourceAttr("scalr_agent_pool.test", "header.0.value", "1234567890new"),
67+
resource.TestCheckResourceAttr("scalr_agent_pool.test", "header.0.sensitive", "true"),
6068
),
6169
},
6270
},
@@ -134,12 +142,23 @@ func testAccScalrAgentPoolBasic(rInt int) string {
134142
return fmt.Sprintf(`
135143
resource "scalr_agent_pool" "test" {
136144
name = "agent_pool-test-%d"
145+
api_gateway_url = "https://example.com"
146+
header {
147+
name = "Authorization"
148+
value = "1234567890"
149+
}
137150
}`, rInt)
138151
}
139152

140153
func testAccScalrAgentPoolUpdate() string {
141154
return `
142155
resource "scalr_agent_pool" "test" {
143156
name = "agent_pool-updated"
157+
api_gateway_url = "https://example.com/new"
158+
header {
159+
name = "Authorization"
160+
value = "1234567890new"
161+
sensitive = true
162+
}
144163
}`
145164
}

0 commit comments

Comments
 (0)