Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Add `tags` option to Kibana's SLOs ([#495](https://github.com/elastic/terraform-provider-elasticstack/pull/495))
- Add support for Authorization header - Bearer Token and ES-Client-Authentication fields added.([#500](https://github.com/elastic/terraform-provider-elasticstack/pull/500))
- Add support for managing Kibana Data Views ([#502](https://github.com/elastic/terraform-provider-elasticstack/pull/502))
- Support Logstash SSL fields in Fleet output ([#498](https://github.com/elastic/terraform-provider-elasticstack/pull/498))

### Fixed
- Rename fleet package objects to `elasticstack_fleet_integration` and `elasticstack_fleet_integration_policy` ([#476](https://github.com/elastic/terraform-provider-elasticstack/pull/476))
Expand Down
13 changes: 13 additions & 0 deletions docs/resources/fleet_output.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,24 @@ resource "elasticstack_fleet_output" "test_output" {
- `default_monitoring` (Boolean) Make this output the default for agent monitoring.
- `hosts` (List of String) A list of hosts.
- `output_id` (String) Unique identifier of the output.
- `ssl` (Block List, Max: 1) SSL configuration. (see [below for nested schema](#nestedblock--ssl))

### Read-Only

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

<a id="nestedblock--ssl"></a>
### Nested Schema for `ssl`

Required:

- `certificate` (String) Client SSL certificate.
- `key` (String, Sensitive) Client SSL certificate key.

Optional:

- `certificate_authorities` (List of String) Server SSL certificate authorities.

## Import

Import is supported using the following syntax:
Expand Down
93 changes: 93 additions & 0 deletions internal/fleet/output_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,35 @@ func ResourceOutput() *schema.Resource {
Type: schema.TypeBool,
Optional: true,
},
"ssl": {
Description: "SSL configuration.",
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"certificate_authorities": {
Description: "Server SSL certificate authorities.",
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"certificate": {
Description: "Client SSL certificate.",
Type: schema.TypeString,
Required: true,
},
"key": {
Description: "Client SSL certificate key.",
Type: schema.TypeString,
Required: true,
Sensitive: true,
},
},
},
},
"config_yaml": {
Description: "Advanced YAML configuration. YAML settings here will be added to the output section of each agent policy.",
Type: schema.TypeString,
Expand Down Expand Up @@ -174,6 +203,27 @@ func resourceOutputCreateLogstash(ctx context.Context, d *schema.ResourceData, m
if value, ok := d.Get("ca_trusted_fingerprint").(string); ok && value != "" {
reqData.CaTrustedFingerprint = &value
}
if value, ok := d.GetOk("ssl"); ok {
ssl := value.([]interface{})[0].(map[string]interface{})
reqData.Ssl = &struct {
Certificate *string `json:"certificate,omitempty"`
CertificateAuthorities *[]string `json:"certificate_authorities,omitempty"`
Key *string `json:"key,omitempty"`
}{}
if value, ok := ssl["certificate_authorities"].([]interface{}); ok {
certs := make([]string, len(value))
for i, v := range value {
certs[i] = v.(string)
}
reqData.Ssl.CertificateAuthorities = &certs
}
if value, ok := ssl["certificate"].(string); ok {
reqData.Ssl.Certificate = &value
}
if value, ok := ssl["key"].(string); ok {
reqData.Ssl.Key = &value
}
}
if value, ok := d.Get("config_yaml").(string); ok && value != "" {
reqData.ConfigYaml = &value
}
Expand Down Expand Up @@ -299,6 +349,27 @@ func resourceOutputUpdateLogstash(ctx context.Context, d *schema.ResourceData, m
if value, ok := d.Get("ca_sha256").(string); ok && value != "" {
reqData.CaSha256 = &value
}
if value, ok := d.GetOk("ssl"); ok {
ssl := value.([]interface{})[0].(map[string]interface{})
reqData.Ssl = &struct {
Certificate *string `json:"certificate,omitempty"`
CertificateAuthorities *[]string `json:"certificate_authorities,omitempty"`
Key *string `json:"key,omitempty"`
}{}
if value, ok := ssl["certificate_authorities"].([]interface{}); ok {
certs := make([]string, len(value))
for i, v := range value {
certs[i] = v.(string)
}
reqData.Ssl.CertificateAuthorities = &certs
}
if value, ok := ssl["certificate"].(string); ok {
reqData.Ssl.Certificate = &value
}
if value, ok := ssl["key"].(string); ok {
reqData.Ssl.Key = &value
}
}
if value, ok := d.Get("config_yaml").(string); ok && value != "" {
reqData.ConfigYaml = &value
}
Expand Down Expand Up @@ -394,6 +465,9 @@ func resourceOutputReadLogstash(d *schema.ResourceData, data fleetapi.OutputCrea
return diag.FromErr(err)
}
}
if err := d.Set("ssl", flattenSslConfig(data)); err != nil {
return diag.FromErr(err)
}
if data.ConfigYaml != nil {
if err := d.Set("config_yaml", *data.ConfigYaml); err != nil {
return diag.FromErr(err)
Expand Down Expand Up @@ -456,3 +530,22 @@ func resourceOutputDelete(ctx context.Context, d *schema.ResourceData, meta inte

return diags
}

func flattenSslConfig(data fleetapi.OutputCreateRequestLogstash) []interface{} {
if data.Ssl == nil {
return []interface{}{}
}

ssl := make(map[string]interface{})
if data.Ssl.CertificateAuthorities != nil {
ssl["certificate_authorities"] = *data.Ssl.CertificateAuthorities
}
if data.Ssl.Certificate != nil {
ssl["certificate"] = *data.Ssl.Certificate
}
if data.Ssl.Key != nil {
ssl["key"] = *data.Ssl.Key
}

return []interface{}{ssl}
}
16 changes: 16 additions & 0 deletions internal/fleet/output_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ func TestAccResourceOutputLogstash(t *testing.T) {
resource.TestCheckResourceAttr("elasticstack_fleet_output.test_output", "default_integrations", "false"),
resource.TestCheckResourceAttr("elasticstack_fleet_output.test_output", "default_monitoring", "false"),
resource.TestCheckResourceAttr("elasticstack_fleet_output.test_output", "hosts.0", "logstash:5044"),
resource.TestCheckResourceAttr("elasticstack_fleet_output.test_output", "ssl.0.certificate_authorities.0", "placeholder"),
resource.TestCheckResourceAttr("elasticstack_fleet_output.test_output", "ssl.0.certificate", "placeholder"),
resource.TestCheckResourceAttr("elasticstack_fleet_output.test_output", "ssl.0.key", "placeholder"),
),
},
{
Expand All @@ -83,6 +86,9 @@ func TestAccResourceOutputLogstash(t *testing.T) {
resource.TestCheckResourceAttr("elasticstack_fleet_output.test_output", "default_integrations", "false"),
resource.TestCheckResourceAttr("elasticstack_fleet_output.test_output", "default_monitoring", "false"),
resource.TestCheckResourceAttr("elasticstack_fleet_output.test_output", "hosts.0", "logstash:5044"),
resource.TestCheckResourceAttr("elasticstack_fleet_output.test_output", "ssl.0.certificate_authorities.0", "placeholder"),
resource.TestCheckResourceAttr("elasticstack_fleet_output.test_output", "ssl.0.certificate", "placeholder"),
resource.TestCheckResourceAttr("elasticstack_fleet_output.test_output", "ssl.0.key", "placeholder"),
),
},
},
Expand Down Expand Up @@ -152,6 +158,11 @@ resource "elasticstack_fleet_output" "test_output" {
hosts = [
"logstash:5044"
]
ssl {
certificate_authorities = ["placeholder"]
certificate = "placeholder"
key = "placeholder"
}
}
`, fmt.Sprintf("Logstash Output %s", id))
}
Expand All @@ -174,6 +185,11 @@ resource "elasticstack_fleet_output" "test_output" {
hosts = [
"logstash:5044"
]
ssl {
certificate_authorities = ["placeholder"]
certificate = "placeholder"
key = "placeholder"
}
}

`, fmt.Sprintf("Updated Logstash Output %s", id))
Expand Down