Skip to content

Commit 855d304

Browse files
Feature: CDN distribution resource and data source (#786)
* add datasource * finish data source * implement resource * add unit tests * add examples * acceptance test * review comments * review comments 2 --------- Co-authored-by: Malte Ehrlen <malte.ehrlen@freiheit.com>
1 parent 3c20b77 commit 855d304

File tree

14 files changed

+1520
-0
lines changed

14 files changed

+1520
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "stackit_cdn_distribution Data Source - stackit"
4+
subcategory: ""
5+
description: |-
6+
CDN distribution data source schema.
7+
~> This resource is in beta and may be subject to breaking changes in the future. Use with caution. See our guide https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources for how to opt-in to use beta resources.
8+
---
9+
10+
# stackit_cdn_distribution (Data Source)
11+
12+
CDN distribution data source schema.
13+
14+
~> This resource is in beta and may be subject to breaking changes in the future. Use with caution. See our [guide](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources) for how to opt-in to use beta resources.
15+
16+
## Example Usage
17+
18+
```terraform
19+
data "stackit_cdn_distribution" "example" {
20+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
21+
distribution_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
22+
}
23+
```
24+
25+
<!-- schema generated by tfplugindocs -->
26+
## Schema
27+
28+
### Required
29+
30+
- `distribution_id` (String) STACKIT project ID associated with the distribution
31+
- `project_id` (String) STACKIT project ID associated with the distribution
32+
33+
### Read-Only
34+
35+
- `config` (Attributes) The distribution configuration (see [below for nested schema](#nestedatt--config))
36+
- `created_at` (String) Time when the distribution was created
37+
- `domains` (Attributes List) List of configured domains for the distribution (see [below for nested schema](#nestedatt--domains))
38+
- `errors` (List of String) List of distribution errors
39+
- `id` (String) Terraform's internal resource identifier. It is structured as "`project_id`,`distribution_id`".
40+
- `status` (String) Status of the distribution
41+
- `updated_at` (String) Time when the distribution was last updated
42+
43+
<a id="nestedatt--config"></a>
44+
### Nested Schema for `config`
45+
46+
Read-Only:
47+
48+
- `backend` (Attributes) The configured backend for the distribution (see [below for nested schema](#nestedatt--config--backend))
49+
- `regions` (List of String) The configured regions where content will be hosted
50+
51+
<a id="nestedatt--config--backend"></a>
52+
### Nested Schema for `config.backend`
53+
54+
Read-Only:
55+
56+
- `origin_request_headers` (Map of String) The configured origin request headers for the backend
57+
- `origin_url` (String) The configured backend type for the distribution
58+
- `type` (String) The configured backend type
59+
60+
61+
62+
<a id="nestedatt--domains"></a>
63+
### Nested Schema for `domains`
64+
65+
Read-Only:
66+
67+
- `errors` (List of String) List of domain errors
68+
- `name` (String) The name of the domain
69+
- `status` (String) The status of the domain
70+
- `type` (String) The type of the domain. Each distribution has one domain of type "managed", and domains of type "custom" may be additionally created by the user

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ Note: AWS specific checks must be skipped as they do not work on STACKIT. For de
153153

154154
- `argus_custom_endpoint` (String, Deprecated) Custom endpoint for the Argus service
155155
- `authorization_custom_endpoint` (String) Custom endpoint for the Membership service
156+
- `cdn_custom_endpoint` (String) Custom endpoint for the CDN service
156157
- `credentials_path` (String) Path of JSON from where the credentials are read. Takes precedence over the env var `STACKIT_CREDENTIALS_PATH`. Default value is `~/.stackit/credentials.json`.
157158
- `default_region` (String) Region will be used as the default location for regional services. Not all services require a region, some are global
158159
- `dns_custom_endpoint` (String) Custom endpoint for the DNS service

docs/resources/cdn_distribution.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "stackit_cdn_distribution Resource - stackit"
4+
subcategory: ""
5+
description: |-
6+
CDN distribution data source schema.
7+
~> This resource is in beta and may be subject to breaking changes in the future. Use with caution. See our guide https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources for how to opt-in to use beta resources.
8+
---
9+
10+
# stackit_cdn_distribution (Resource)
11+
12+
CDN distribution data source schema.
13+
14+
~> This resource is in beta and may be subject to breaking changes in the future. Use with caution. See our [guide](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources) for how to opt-in to use beta resources.
15+
16+
## Example Usage
17+
18+
```terraform
19+
# Create a CDN distribution
20+
resource "stackit_cdn_distribution" "example_distribution" {
21+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
22+
config = {
23+
backend = {
24+
type = "http"
25+
origin_url = "mybackend.onstackit.cloud"
26+
}
27+
regions = ["EN", "US", "ASIA", "AF", "SA"]
28+
}
29+
}
30+
```
31+
32+
<!-- schema generated by tfplugindocs -->
33+
## Schema
34+
35+
### Required
36+
37+
- `config` (Attributes) The distribution configuration (see [below for nested schema](#nestedatt--config))
38+
- `project_id` (String) STACKIT project ID associated with the distribution
39+
40+
### Read-Only
41+
42+
- `created_at` (String) Time when the distribution was created
43+
- `distribution_id` (String) STACKIT project ID associated with the distribution
44+
- `domains` (Attributes List) List of configured domains for the distribution (see [below for nested schema](#nestedatt--domains))
45+
- `errors` (List of String) List of distribution errors
46+
- `id` (String) Terraform's internal resource identifier. It is structured as "`project_id`,`distribution_id`".
47+
- `status` (String) Status of the distribution
48+
- `updated_at` (String) Time when the distribution was last updated
49+
50+
<a id="nestedatt--config"></a>
51+
### Nested Schema for `config`
52+
53+
Required:
54+
55+
- `backend` (Attributes) The configured backend for the distribution (see [below for nested schema](#nestedatt--config--backend))
56+
- `regions` (List of String) The configured regions where content will be hosted
57+
58+
<a id="nestedatt--config--backend"></a>
59+
### Nested Schema for `config.backend`
60+
61+
Required:
62+
63+
- `origin_url` (String) The configured backend type for the distribution
64+
- `type` (String) The configured backend type
65+
66+
Optional:
67+
68+
- `origin_request_headers` (Map of String) The configured origin request headers for the backend
69+
70+
71+
72+
<a id="nestedatt--domains"></a>
73+
### Nested Schema for `domains`
74+
75+
Read-Only:
76+
77+
- `errors` (List of String) List of domain errors
78+
- `name` (String) The name of the domain
79+
- `status` (String) The status of the domain
80+
- `type` (String) The type of the domain. Each distribution has one domain of type "managed", and domains of type "custom" may be additionally created by the user
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
data "stackit_cdn_distribution" "example" {
2+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
3+
distribution_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
4+
}
5+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Create a CDN distribution
2+
resource "stackit_cdn_distribution" "example_distribution" {
3+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
4+
config = {
5+
backend = {
6+
type = "http"
7+
origin_url = "mybackend.onstackit.cloud"
8+
}
9+
regions = ["EN", "US", "ASIA", "AF", "SA"]
10+
}
11+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ require (
1212
github.com/hashicorp/terraform-plugin-log v0.9.0
1313
github.com/hashicorp/terraform-plugin-testing v1.12.0
1414
github.com/stackitcloud/stackit-sdk-go/core v0.17.1
15+
github.com/stackitcloud/stackit-sdk-go/services/cdn v0.3.0
1516
github.com/stackitcloud/stackit-sdk-go/services/dns v0.13.1
1617
github.com/stackitcloud/stackit-sdk-go/services/iaas v0.22.0
1718
github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.0.1

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ github.com/stackitcloud/stackit-sdk-go/core v0.17.1 h1:TTrVoB1lERd/qfWzpe6HpwCJS
154154
github.com/stackitcloud/stackit-sdk-go/core v0.17.1/go.mod h1:8KIw3czdNJ9sdil9QQimxjR6vHjeINFrRv0iZ67wfn0=
155155
github.com/stackitcloud/stackit-sdk-go/services/authorization v0.6.1 h1:2lq6SG8qOgPOx2OIA5Bca8mwRSlect3Yljk57bXqd5I=
156156
github.com/stackitcloud/stackit-sdk-go/services/authorization v0.6.1/go.mod h1:in9kC4GIBU5DpzXKFDL7RDl0fKyvN/RUIc7YbyWYEUA=
157+
github.com/stackitcloud/stackit-sdk-go/services/cdn v0.3.0 h1:l3COE8uny+AVkHW7MElzEGdriy+QzhpRhYgLkYJlnLU=
158+
github.com/stackitcloud/stackit-sdk-go/services/cdn v0.3.0/go.mod h1:O5esCqh35n0ERX7/Sqpf09ZRDWckhHUuflJFbUvx9QM=
157159
github.com/stackitcloud/stackit-sdk-go/services/dns v0.13.1 h1:W5zQhg/nA2RVSkUtRjsGcJMdYlOicoE5gBGE9zMT9Eo=
158160
github.com/stackitcloud/stackit-sdk-go/services/dns v0.13.1/go.mod h1:+i7jQpfgj/OuZNVZ9A9aUHdVUR/j2SfICLeHbtNn+5c=
159161
github.com/stackitcloud/stackit-sdk-go/services/iaas v0.22.0 h1:xaNory8kBIsBG7PJnBfPP1cERc+ERqjebxmEmEOvRHU=

stackit/internal/core/core.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type ProviderData struct {
2121
DefaultRegion string
2222
ArgusCustomEndpoint string
2323
AuthorizationCustomEndpoint string
24+
CdnCustomEndpoint string
2425
DnsCustomEndpoint string
2526
IaaSCustomEndpoint string
2627
LoadBalancerCustomEndpoint string
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package cdn_test
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strings"
7+
"testing"
8+
9+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
10+
"github.com/hashicorp/terraform-plugin-testing/terraform"
11+
"github.com/stackitcloud/stackit-sdk-go/core/config"
12+
"github.com/stackitcloud/stackit-sdk-go/services/cdn"
13+
"github.com/stackitcloud/stackit-sdk-go/services/cdn/wait"
14+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
15+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/testutil"
16+
)
17+
18+
var instanceResource = map[string]string{
19+
"project_id": testutil.ProjectId,
20+
"config_backend_type": "http",
21+
"config_backend_origin_url": "https://test-backend-1.cdn-dev.runs.onstackit.cloud",
22+
"config_regions": "\"EU\", \"US\"",
23+
"config_regions_updated": "\"EU\", \"US\", \"ASIA\"",
24+
}
25+
26+
func configResources(regions string) string {
27+
return fmt.Sprintf(`
28+
%s
29+
30+
resource "stackit_cdn_distribution" "distribution" {
31+
project_id = "%s"
32+
config = {
33+
backend = {
34+
type = "http"
35+
origin_url = "%s"
36+
}
37+
regions = [%s]
38+
}
39+
}
40+
`, testutil.CdnProviderConfig(), testutil.ProjectId, instanceResource["config_backend_origin_url"], regions)
41+
}
42+
43+
func configDatasources(regions string) string {
44+
return fmt.Sprintf(`
45+
%s
46+
47+
data "stackit_cdn_distribution" "distribution" {
48+
project_id = stackit_cdn_distribution.distribution.project_id
49+
distribution_id = stackit_cdn_distribution.distribution.distribution_id
50+
}
51+
`, configResources(regions))
52+
}
53+
54+
func TestAccCDNDistributionResource(t *testing.T) {
55+
resource.Test(t, resource.TestCase{
56+
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
57+
CheckDestroy: testAccCheckCDNDistributionDestroy,
58+
Steps: []resource.TestStep{
59+
// Create
60+
{
61+
Config: configResources(instanceResource["config_regions"]),
62+
Check: resource.ComposeAggregateTestCheckFunc(
63+
resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "distribution_id"),
64+
resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "created_at"),
65+
resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "updated_at"),
66+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "domains.#", "1"),
67+
resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "domains.0.name"),
68+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "domains.0.status", "ACTIVE"),
69+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "config.regions.#", "2"),
70+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "config.regions.0", "EU"),
71+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "config.regions.1", "US"),
72+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "project_id", testutil.ProjectId),
73+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "status", "ACTIVE"),
74+
),
75+
},
76+
// Import
77+
{
78+
ResourceName: "stackit_cdn_distribution.distribution",
79+
ImportStateIdFunc: func(s *terraform.State) (string, error) {
80+
r, ok := s.RootModule().Resources["stackit_cdn_distribution.distribution"]
81+
if !ok {
82+
return "", fmt.Errorf("couldn't find resource stackit_cdn_distribution.distribution")
83+
}
84+
distributionId, ok := r.Primary.Attributes["distribution_id"]
85+
if !ok {
86+
return "", fmt.Errorf("couldn't find attribute distribution_id")
87+
}
88+
89+
return fmt.Sprintf("%s,%s", testutil.ProjectId, distributionId), nil
90+
},
91+
ImportState: true,
92+
ImportStateVerify: true,
93+
},
94+
// Data Source
95+
{
96+
Config: configDatasources(instanceResource["config_regions"]),
97+
Check: resource.ComposeAggregateTestCheckFunc(
98+
resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "distribution_id"),
99+
resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "created_at"),
100+
resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "updated_at"),
101+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "domains.#", "1"),
102+
resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "domains.0.name"),
103+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "domains.0.status", "ACTIVE"),
104+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "config.regions.#", "2"),
105+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "config.regions.0", "EU"),
106+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "config.regions.1", "US"),
107+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "project_id", testutil.ProjectId),
108+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "status", "ACTIVE"),
109+
),
110+
},
111+
// Update
112+
{
113+
Config: configResources(instanceResource["config_regions_updated"]),
114+
Check: resource.ComposeAggregateTestCheckFunc(
115+
resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "distribution_id"),
116+
resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "created_at"),
117+
resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "updated_at"),
118+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "domains.#", "1"),
119+
resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "domains.0.name"),
120+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "domains.0.status", "ACTIVE"),
121+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "config.regions.#", "3"),
122+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "config.regions.0", "EU"),
123+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "config.regions.1", "US"),
124+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "config.regions.2", "ASIA"),
125+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "project_id", testutil.ProjectId),
126+
resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "status", "ACTIVE"),
127+
),
128+
},
129+
},
130+
})
131+
}
132+
func testAccCheckCDNDistributionDestroy(s *terraform.State) error {
133+
ctx := context.Background()
134+
var client *cdn.APIClient
135+
var err error
136+
if testutil.MongoDBFlexCustomEndpoint == "" {
137+
client, err = cdn.NewAPIClient()
138+
} else {
139+
client, err = cdn.NewAPIClient(
140+
config.WithEndpoint(testutil.MongoDBFlexCustomEndpoint),
141+
)
142+
}
143+
if err != nil {
144+
return fmt.Errorf("creating client: %w", err)
145+
}
146+
147+
distributionsToDestroy := []string{}
148+
for _, rs := range s.RootModule().Resources {
149+
if rs.Type != "stackit_mongodbflex_instance" {
150+
continue
151+
}
152+
distributionId := strings.Split(rs.Primary.ID, core.Separator)[1]
153+
distributionsToDestroy = append(distributionsToDestroy, distributionId)
154+
}
155+
156+
for _, dist := range distributionsToDestroy {
157+
_, err := client.DeleteDistribution(ctx, testutil.ProjectId, dist).Execute()
158+
if err != nil {
159+
return fmt.Errorf("destroying CDN distribution %s during CheckDestroy: %w", dist, err)
160+
}
161+
_, err = wait.DeleteDistributionWaitHandler(ctx, client, testutil.ProjectId, dist).WaitWithContext(ctx)
162+
if err != nil {
163+
return fmt.Errorf("destroying CDN distribution %s during CheckDestroy: waiting for deletion %w", dist, err)
164+
}
165+
}
166+
return nil
167+
}

0 commit comments

Comments
 (0)