Skip to content

Commit 66d6b63

Browse files
togishtobio
andauthored
Adding ignore_missing_component_templates (#1206)
* Adding ignore_missing_component_templates #631 * Trigger workflow * Reverting trigger change * Adding acceptance tests on index template for parameter ignore_missing_component_templates * Updating changelog * Handling inconsistent tabs vs spaces * Handling inconsistent tabs vs spaces * es version awareness ignore_missing_component_templates * Formatting * Updating ressource ref from data source test * Update Changelog --------- Co-authored-by: Toby Brain <toby.brain@elastic.co> Co-authored-by: Toby Brain <tobio85@gmail.com>
1 parent 45b2447 commit 66d6b63

File tree

8 files changed

+148
-10
lines changed

8 files changed

+148
-10
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## [Unreleased]
22

3+
- Add `ignore_missing_component_templates` to `elasticstack_elasticsearch_index_template` ([#1206](https://github.com/elastic/terraform-provider-elasticstack/pull/1206))
4+
35
## [0.11.17] - 2025-07-21
46

57
- Add `elasticstack_apm_agent_configuration` resource ([#1196](https://github.com/elastic/terraform-provider-elasticstack/pull/1196))

docs/data-sources/elasticsearch_index_template.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ output "template" {
4242
- `composed_of` (List of String) An ordered list of component template names.
4343
- `data_stream` (List of Object) If this object is included, the template is used to create data streams and their backing indices. Supports an empty object. (see [below for nested schema](#nestedatt--data_stream))
4444
- `id` (String) Internal identifier of the resource
45+
- `ignore_missing_component_templates` (List of String) A list of component template names that are ignored if missing.
4546
- `index_patterns` (Set of String) Array of wildcard (*) expressions used to match the names of data streams and indices during creation.
4647
- `metadata` (String) Optional user metadata about the index template.
4748
- `priority` (Number) Priority to determine index template precedence when a new data stream or index is created.

docs/resources/elasticsearch_index_template.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ resource "elasticstack_elasticsearch_index_template" "my_data_stream" {
5858
- `composed_of` (List of String) An ordered list of component template names.
5959
- `data_stream` (Block List, Max: 1) If this object is included, the template is used to create data streams and their backing indices. Supports an empty object. (see [below for nested schema](#nestedblock--data_stream))
6060
- `elasticsearch_connection` (Block List, Max: 1, Deprecated) Elasticsearch connection configuration block. This property will be removed in a future provider version. Configure the Elasticsearch connection via the provider configuration instead. (see [below for nested schema](#nestedblock--elasticsearch_connection))
61+
- `ignore_missing_component_templates` (List of String) A list of component template names that are ignored if missing.
6162
- `metadata` (String) Optional user metadata about the index template.
6263
- `priority` (Number) Priority to determine index template precedence when a new data stream or index is created.
6364
- `template` (Block List, Max: 1) Template to be applied. It may optionally include an aliases, mappings, lifecycle, or settings configuration. (see [below for nested schema](#nestedblock--template))

internal/elasticsearch/index/template.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,17 @@ import (
1010
"github.com/elastic/terraform-provider-elasticstack/internal/clients/elasticsearch"
1111
"github.com/elastic/terraform-provider-elasticstack/internal/models"
1212
"github.com/elastic/terraform-provider-elasticstack/internal/utils"
13+
"github.com/hashicorp/go-version"
1314
"github.com/hashicorp/terraform-plugin-log/tflog"
1415
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1516
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1617
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1718
)
1819

20+
var (
21+
MinSupportedIgnoreMissingComponentTemplateVersion = version.Must(version.NewVersion("8.7.0"))
22+
)
23+
1924
func ResourceTemplate() *schema.Resource {
2025
templateSchema := map[string]*schema.Schema{
2126
"id": {
@@ -38,6 +43,15 @@ func ResourceTemplate() *schema.Resource {
3843
Type: schema.TypeString,
3944
},
4045
},
46+
"ignore_missing_component_templates": {
47+
Description: "A list of component template names that are ignored if missing.",
48+
Type: schema.TypeList,
49+
Optional: true,
50+
Computed: true,
51+
Elem: &schema.Schema{
52+
Type: schema.TypeString,
53+
},
54+
},
4155
"data_stream": {
4256
Description: "If this object is included, the template is used to create data streams and their backing indices. Supports an empty object.",
4357
Type: schema.TypeList,
@@ -210,6 +224,12 @@ func resourceIndexTemplatePut(ctx context.Context, d *schema.ResourceData, meta
210224
if diags.HasError() {
211225
return diags
212226
}
227+
228+
serverVersion, diags := client.ServerVersion(ctx)
229+
if diags.HasError() {
230+
return diags
231+
}
232+
213233
var indexTemplate models.IndexTemplate
214234
indexTemplate.Name = templateId
215235

@@ -221,6 +241,18 @@ func resourceIndexTemplatePut(ctx context.Context, d *schema.ResourceData, meta
221241
}
222242
indexTemplate.ComposedOf = compsOf
223243

244+
if v, ok := d.GetOk("ignore_missing_component_templates"); ok {
245+
compsOfIgnore := make([]string, 0)
246+
for _, c := range v.([]interface{}) {
247+
compsOfIgnore = append(compsOfIgnore, c.(string))
248+
}
249+
250+
if len(compsOfIgnore) > 0 && serverVersion.LessThan(MinSupportedIgnoreMissingComponentTemplateVersion) {
251+
return diag.FromErr(fmt.Errorf("'ignore_missing_component_templates' is supported only for Elasticsearch v%s and above", MinSupportedIgnoreMissingComponentTemplateVersion.String()))
252+
}
253+
indexTemplate.IgnoreMissingComponentTemplates = compsOfIgnore
254+
}
255+
224256
if v, ok := d.GetOk("data_stream"); ok {
225257
// 8.x workaround
226258
hasAllowCustomRouting := false
@@ -371,6 +403,9 @@ func resourceIndexTemplateRead(ctx context.Context, d *schema.ResourceData, meta
371403
if err := d.Set("composed_of", tpl.IndexTemplate.ComposedOf); err != nil {
372404
return diag.FromErr(err)
373405
}
406+
if err := d.Set("ignore_missing_component_templates", tpl.IndexTemplate.IgnoreMissingComponentTemplates); err != nil {
407+
return diag.FromErr(err)
408+
}
374409
if stream := tpl.IndexTemplate.DataStream; stream != nil {
375410
ds := make([]interface{}, 1)
376411
dSettings := make(map[string]interface{})

internal/elasticsearch/index/template_data_source.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ func DataSourceTemplate() *schema.Resource {
2929
Type: schema.TypeString,
3030
},
3131
},
32+
"ignore_missing_component_templates": {
33+
Description: "A list of component template names that are ignored if missing.",
34+
Type: schema.TypeList,
35+
Computed: true,
36+
Elem: &schema.Schema{
37+
Type: schema.TypeString,
38+
},
39+
},
3240
"data_stream": {
3341
Description: "If this object is included, the template is used to create data streams and their backing indices. Supports an empty object.",
3442
Type: schema.TypeList,

internal/elasticsearch/index/template_data_source_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ import (
55
"testing"
66

77
"github.com/elastic/terraform-provider-elasticstack/internal/acctest"
8+
"github.com/elastic/terraform-provider-elasticstack/internal/elasticsearch/index"
9+
"github.com/elastic/terraform-provider-elasticstack/internal/versionutils"
810
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
911
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1012
)
1113

1214
func TestAccIndexTemplateDataSource(t *testing.T) {
1315
// generate a random role name
1416
templateName := "test-template-" + sdkacctest.RandStringFromCharSet(10, sdkacctest.CharSetAlphaNum)
17+
templateNameComponent := "test-template-" + sdkacctest.RandStringFromCharSet(10, sdkacctest.CharSetAlphaNum)
1518

1619
resource.Test(t, resource.TestCase{
1720
PreCheck: func() { acctest.PreCheck(t) },
@@ -25,6 +28,16 @@ func TestAccIndexTemplateDataSource(t *testing.T) {
2528
resource.TestCheckResourceAttr("data.elasticstack_elasticsearch_index_template.test", "priority", "100"),
2629
),
2730
},
31+
{
32+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(index.MinSupportedIgnoreMissingComponentTemplateVersion),
33+
Config: testAccIndexTemplateDataSourceWithIgnoreComponentConfig(templateNameComponent),
34+
Check: resource.ComposeAggregateTestCheckFunc(
35+
resource.TestCheckResourceAttr("data.elasticstack_elasticsearch_index_template.test_component", "name", templateNameComponent),
36+
resource.TestCheckTypeSetElemAttr("data.elasticstack_elasticsearch_index_template.test_component", "index_patterns.*", fmt.Sprintf("tf-acc-component-%s-*", templateNameComponent)),
37+
resource.TestCheckTypeSetElemAttr("data.elasticstack_elasticsearch_index_template.test_component", "composed_of.*", fmt.Sprintf("%s-logscomponent@custom", templateNameComponent)),
38+
resource.TestCheckTypeSetElemAttr("data.elasticstack_elasticsearch_index_template.test_component", "ignore_missing_component_templates.*", fmt.Sprintf("%s-logscomponent@custom", templateNameComponent)),
39+
),
40+
},
2841
},
2942
})
3043
}
@@ -47,3 +60,22 @@ data "elasticstack_elasticsearch_index_template" "test" {
4760
}
4861
`, templateName, templateName)
4962
}
63+
64+
func testAccIndexTemplateDataSourceWithIgnoreComponentConfig(templateName string) string {
65+
return fmt.Sprintf(`
66+
provider "elasticstack" {
67+
elasticsearch {}
68+
}
69+
70+
resource "elasticstack_elasticsearch_index_template" "test_component" {
71+
name = "%s"
72+
index_patterns = ["tf-acc-component-%s-*"]
73+
composed_of = ["%s-logscomponent@custom"]
74+
ignore_missing_component_templates = ["%s-logscomponent@custom"]
75+
}
76+
77+
data "elasticstack_elasticsearch_index_template" "test_component" {
78+
name = elasticstack_elasticsearch_index_template.test_component.name
79+
}
80+
`, templateName, templateName, templateName, templateName)
81+
}

internal/elasticsearch/index/template_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66

77
"github.com/elastic/terraform-provider-elasticstack/internal/acctest"
88
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
9+
"github.com/elastic/terraform-provider-elasticstack/internal/elasticsearch/index"
10+
"github.com/elastic/terraform-provider-elasticstack/internal/versionutils"
911
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
1012
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1113
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
@@ -14,6 +16,7 @@ import (
1416
func TestAccResourceIndexTemplate(t *testing.T) {
1517
// generate random template name
1618
templateName := sdkacctest.RandStringFromCharSet(10, sdkacctest.CharSetAlphaNum)
19+
templateNameComponent := sdkacctest.RandStringFromCharSet(10, sdkacctest.CharSetAlphaNum)
1720

1821
resource.Test(t, resource.TestCase{
1922
PreCheck: func() { acctest.PreCheck(t) },
@@ -41,6 +44,26 @@ func TestAccResourceIndexTemplate(t *testing.T) {
4144
resource.TestCheckResourceAttr("elasticstack_elasticsearch_index_template.test2", "data_stream.0.hidden", "false"),
4245
),
4346
},
47+
{
48+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(index.MinSupportedIgnoreMissingComponentTemplateVersion),
49+
Config: testAccResourceIndexTemplateCreateWithIgnoreComponent(templateNameComponent),
50+
Check: resource.ComposeTestCheckFunc(
51+
resource.TestCheckResourceAttr("elasticstack_elasticsearch_index_template.test_component", "name", templateNameComponent),
52+
resource.TestCheckTypeSetElemAttr("elasticstack_elasticsearch_index_template.test_component", "index_patterns.*", fmt.Sprintf("%s-logscomponent-*", templateNameComponent)),
53+
resource.TestCheckTypeSetElemAttr("elasticstack_elasticsearch_index_template.test_component", "composed_of.*", fmt.Sprintf("%s-logscomponent@custom", templateNameComponent)),
54+
resource.TestCheckTypeSetElemAttr("elasticstack_elasticsearch_index_template.test_component", "ignore_missing_component_templates.*", fmt.Sprintf("%s-logscomponent@custom", templateNameComponent)),
55+
),
56+
},
57+
{
58+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(index.MinSupportedIgnoreMissingComponentTemplateVersion),
59+
Config: testAccResourceIndexTemplateUpdateWithIgnoreComponent(templateNameComponent),
60+
Check: resource.ComposeTestCheckFunc(
61+
resource.TestCheckResourceAttr("elasticstack_elasticsearch_index_template.test_component", "name", templateNameComponent),
62+
resource.TestCheckTypeSetElemAttr("elasticstack_elasticsearch_index_template.test_component", "index_patterns.*", fmt.Sprintf("%s-logscomponent-*", templateNameComponent)),
63+
resource.TestCheckTypeSetElemAttr("elasticstack_elasticsearch_index_template.test_component", "composed_of.*", fmt.Sprintf("%s-logscomponent-updated@custom", templateNameComponent)),
64+
resource.TestCheckTypeSetElemAttr("elasticstack_elasticsearch_index_template.test_component", "ignore_missing_component_templates.*", fmt.Sprintf("%s-logscomponent-updated@custom", templateNameComponent)),
65+
),
66+
},
4467
},
4568
})
4669
}
@@ -117,6 +140,41 @@ resource "elasticstack_elasticsearch_index_template" "test2" {
117140
`, name, name, name)
118141
}
119142

143+
func testAccResourceIndexTemplateCreateWithIgnoreComponent(name string) string {
144+
return fmt.Sprintf(`
145+
provider "elasticstack" {
146+
elasticsearch {}
147+
}
148+
149+
resource "elasticstack_elasticsearch_index_template" "test_component" {
150+
name = "%s"
151+
index_patterns = ["%s-logscomponent-*"]
152+
153+
composed_of = ["%s-logscomponent@custom"]
154+
ignore_missing_component_templates = ["%s-logscomponent@custom"]
155+
}
156+
`, name, name, name, name)
157+
}
158+
159+
func testAccResourceIndexTemplateUpdateWithIgnoreComponent(name string) string {
160+
return fmt.Sprintf(`
161+
provider "elasticstack" {
162+
elasticsearch {}
163+
}
164+
165+
resource "elasticstack_elasticsearch_index_template" "test_component" {
166+
name = "%s"
167+
index_patterns = ["%s-logscomponent-*"]
168+
169+
composed_of = ["%s-logscomponent-updated@custom"]
170+
ignore_missing_component_templates = ["%s-logscomponent-updated@custom"]
171+
172+
template {
173+
}
174+
}
175+
`, name, name, name, name)
176+
}
177+
120178
func checkResourceIndexTemplateDestroy(s *terraform.State) error {
121179
client, err := clients.NewAcceptanceTestingClient()
122180
if err != nil {

internal/models/models.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,16 +163,17 @@ type Application struct {
163163
}
164164

165165
type IndexTemplate struct {
166-
Name string `json:"-"`
167-
Create bool `json:"-"`
168-
Timeout string `json:"-"`
169-
ComposedOf []string `json:"composed_of"`
170-
DataStream *DataStreamSettings `json:"data_stream,omitempty"`
171-
IndexPatterns []string `json:"index_patterns"`
172-
Meta map[string]interface{} `json:"_meta,omitempty"`
173-
Priority *int `json:"priority,omitempty"`
174-
Template *Template `json:"template,omitempty"`
175-
Version *int `json:"version,omitempty"`
166+
Name string `json:"-"`
167+
Create bool `json:"-"`
168+
Timeout string `json:"-"`
169+
ComposedOf []string `json:"composed_of"`
170+
IgnoreMissingComponentTemplates []string `json:"ignore_missing_component_templates,omitempty"`
171+
DataStream *DataStreamSettings `json:"data_stream,omitempty"`
172+
IndexPatterns []string `json:"index_patterns"`
173+
Meta map[string]interface{} `json:"_meta,omitempty"`
174+
Priority *int `json:"priority,omitempty"`
175+
Template *Template `json:"template,omitempty"`
176+
Version *int `json:"version,omitempty"`
176177
}
177178

178179
type DataStreamSettings struct {

0 commit comments

Comments
 (0)