diff --git a/CHANGELOG.md b/CHANGELOG.md index 08d44ca49..f7ebdca1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## [Unreleased] - Add `headers` for the provider connection ([#1057](https://github.com/elastic/terraform-provider-elasticstack/pull/1057)) +- Add custom `endpoint` configuration support for snapshot repository setup ([#1158](https://github.com/elastic/terraform-provider-elasticstack/pull/1158)) ## [0.11.15] - 2025-04-23 diff --git a/docs/resources/elasticsearch_snapshot_repository.md b/docs/resources/elasticsearch_snapshot_repository.md index 4cdab4e26..5f469f4c9 100644 --- a/docs/resources/elasticsearch_snapshot_repository.md +++ b/docs/resources/elasticsearch_snapshot_repository.md @@ -166,6 +166,7 @@ Optional: - `chunk_size` (String) Maximum size of files in snapshots. - `client` (String) The name of the S3 client to use to connect to S3. - `compress` (Boolean) If true, metadata files, such as index mappings and settings, are compressed in snapshots. +- `endpoint` (String) Custom S3 service endpoint, useful when using VPC endpoints or non-default S3 URLs. - `max_restore_bytes_per_sec` (String) Maximum snapshot restore rate per node. - `max_snapshot_bytes_per_sec` (String) Maximum snapshot creation rate per node. - `path_style_access` (Boolean) If true, path style access pattern will be used. diff --git a/internal/elasticsearch/cluster/snapshot_repository.go b/internal/elasticsearch/cluster/snapshot_repository.go index 0ac999979..27e232b64 100644 --- a/internal/elasticsearch/cluster/snapshot_repository.go +++ b/internal/elasticsearch/cluster/snapshot_repository.go @@ -3,9 +3,11 @@ package cluster import ( "context" "fmt" + "net/url" "reflect" "regexp" "strconv" + "strings" "github.com/elastic/terraform-provider-elasticstack/internal/clients" "github.com/elastic/terraform-provider-elasticstack/internal/clients/elasticsearch" @@ -144,6 +146,13 @@ func ResourceSnapshotRepository() *schema.Resource { Type: schema.TypeString, Required: true, }, + "endpoint": { + Description: "Custom S3 service endpoint, useful when using VPC endpoints or non-default S3 URLs.", + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validateURLEndpoint, + }, "client": { Description: "The name of the S3 client to use to connect to S3.", Type: schema.TypeString, @@ -466,3 +475,21 @@ func resourceSnapRepoDelete(ctx context.Context, d *schema.ResourceData, meta in } return diags } + +func validateURLEndpoint(val interface{}, key string) ([]string, []error) { + v := val.(string) + if v == "" { + return nil, nil + } + + parsed, err := url.ParseRequestURI(v) + if err != nil || parsed.Scheme == "" || parsed.Host == "" { + return nil, []error{fmt.Errorf("%q must be a valid HTTP/HTTPS URL, got: %q", key, v)} + } + + if !strings.HasPrefix(v, "http://") && !strings.HasPrefix(v, "https://") { + return nil, []error{fmt.Errorf("%q must start with http:// or https://, got: %q", key, v)} + } + + return nil, nil +}