diff --git a/apstra/blueprint/freeform_system.go b/apstra/blueprint/freeform_system.go index a0a6e1a8..7fa19a91 100644 --- a/apstra/blueprint/freeform_system.go +++ b/apstra/blueprint/freeform_system.go @@ -3,6 +3,7 @@ package blueprint import ( "context" "fmt" + "regexp" "github.com/Juniper/apstra-go-sdk/apstra" "github.com/Juniper/terraform-provider-apstra/apstra/utils" @@ -85,6 +86,7 @@ func (o FreeformSystem) DataSourceAttributes() map[string]dataSourceSchema.Attri } func (o FreeformSystem) ResourceAttributes() map[string]resourceSchema.Attribute { + hostnameRegexp := "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$" return map[string]resourceSchema.Attribute{ "blueprint_id": resourceSchema.StringAttribute{ MarkdownDescription: "Apstra Blueprint ID.", @@ -100,29 +102,33 @@ func (o FreeformSystem) ResourceAttributes() map[string]resourceSchema.Attribute "name": resourceSchema.StringAttribute{ MarkdownDescription: "Freeform System name as shown in the Web UI.", Required: true, - Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexp.MustCompile("^[a-zA-Z0-9.-_]+$"), "name may consist only of the following characters : a-zA-Z0-9.-_")}, }, "hostname": resourceSchema.StringAttribute{ MarkdownDescription: "Hostname of the Freeform System.", - Optional: true, - Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, + Required: true, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexp.MustCompile(hostnameRegexp), "must match regex "+hostnameRegexp), + }, }, - "deploy_mode": dataSourceSchema.StringAttribute{ + "deploy_mode": resourceSchema.StringAttribute{ MarkdownDescription: "Deploy mode of the System", Optional: true, Validators: []validator.String{stringvalidator.OneOf(utils.AllNodeDeployModes()...)}, }, - "type": dataSourceSchema.StringAttribute{ + "type": resourceSchema.StringAttribute{ MarkdownDescription: fmt.Sprintf("Type of the System. Must be one of `%s` or `%s`", apstra.SystemTypeInternal, apstra.SystemTypeExternal), Required: true, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, Validators: []validator.String{stringvalidator.OneOf(apstra.SystemTypeInternal.String(), apstra.SystemTypeExternal.String())}, }, - "device_profile_id": dataSourceSchema.StringAttribute{ + "device_profile_id": resourceSchema.StringAttribute{ MarkdownDescription: "Device profile ID of the System", Optional: true, Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, }, - "system_id": dataSourceSchema.StringAttribute{ + "system_id": resourceSchema.StringAttribute{ MarkdownDescription: "ID (usually serial number) of the Managed Device to associate with this System", Optional: true, Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, @@ -166,7 +172,7 @@ func (o *FreeformSystem) Request(ctx context.Context, diags *diag.Diagnostics) * func (o *FreeformSystem) LoadApiData(ctx context.Context, in *apstra.FreeformSystemData, diags *diag.Diagnostics) { o.Name = types.StringValue(in.Label) o.Hostname = types.StringValue(in.Hostname) - o.Type = types.StringValue(string(rune(in.Type))) + o.Type = types.StringValue(in.Type.String()) o.DeviceProfileId = types.StringValue(string(in.DeviceProfileId)) o.SystemId = types.StringPointerValue((*string)(in.SystemId)) o.Tags = utils.SetValueOrNull(ctx, types.StringType, in.Tags, diags) // safe to ignore diagnostic here diff --git a/apstra/export_test.go b/apstra/export_test.go index 5e1e15e7..9d0f68d0 100644 --- a/apstra/export_test.go +++ b/apstra/export_test.go @@ -11,6 +11,7 @@ var ( ResourceDatacenterGenericSystem = resourceDatacenterGenericSystem{} ResourceDatacenterRoutingZone = resourceDatacenterRoutingZone{} ResourceFreeformConfigTemplate = resourceFreeformConfigTemplate{} + ResourceFreeformSystem = resourceFreeformSystem{} ResourceFreeformPropertySet = resourceFreeformPropertySet{} ResourceIpv4Pool = resourceIpv4Pool{} ResourceTemplatePodBased = resourceTemplatePodBased{} diff --git a/apstra/resource_freeform_system.go b/apstra/resource_freeform_system.go index 3eef0c42..7b255471 100644 --- a/apstra/resource_freeform_system.go +++ b/apstra/resource_freeform_system.go @@ -3,7 +3,6 @@ package tfapstra import ( "context" "fmt" - "github.com/Juniper/apstra-go-sdk/apstra" "github.com/Juniper/terraform-provider-apstra/apstra/blueprint" "github.com/Juniper/terraform-provider-apstra/apstra/utils" diff --git a/apstra/resource_freeform_system_integration_test.go b/apstra/resource_freeform_system_integration_test.go new file mode 100644 index 00000000..cd5e03ac --- /dev/null +++ b/apstra/resource_freeform_system_integration_test.go @@ -0,0 +1,204 @@ +//go:build integration + +package tfapstra_test + +import ( + "context" + "fmt" + "github.com/Juniper/apstra-go-sdk/apstra" + "math/rand" + "strconv" + "testing" + + tfapstra "github.com/Juniper/terraform-provider-apstra/apstra" + testutils "github.com/Juniper/terraform-provider-apstra/apstra/test_utils" + "github.com/hashicorp/go-version" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +const ( + resourceFreeformSystemHcl = ` +resource %q %q { + blueprint_id = %q + name = %q + device_profile_id = %q + hostname = %q + type = %q + deploy_mode = %s + tags = %s +} +` +) + +type resourceFreeformSystem struct { + blueprintId string + name string + deviceProfileId string + hostname string + systemType string + deployMode string + tags []string +} + +func (o resourceFreeformSystem) render(rType, rName string) string { + return fmt.Sprintf(resourceFreeformSystemHcl, + rType, rName, + o.blueprintId, + o.name, + o.deviceProfileId, + o.hostname, + o.systemType, + stringOrNull(o.deployMode), + stringSetOrNull(o.tags), + ) +} + +func (o resourceFreeformSystem) testChecks(t testing.TB, rType, rName string) testChecks { + result := newTestChecks(rType + "." + rName) + + // required and computed attributes can always be checked + result.append(t, "TestCheckResourceAttrSet", "id") + result.append(t, "TestCheckResourceAttr", "blueprint_id", o.blueprintId) + result.append(t, "TestCheckResourceAttr", "name", o.name) + result.append(t, "TestCheckResourceAttr", "type", o.systemType) + result.append(t, "TestCheckResourceAttr", "device_profile_id", o.deviceProfileId) + result.append(t, "TestCheckResourceAttr", "hostname", o.hostname) + if o.deployMode != "" { + result.append(t, "TestCheckResourceAttr", "deploy_mode", o.deployMode) + } + if len(o.tags) > 0 { + result.append(t, "TestCheckResourceAttr", "tags.#", strconv.Itoa(len(o.tags))) + for _, tag := range o.tags { + result.append(t, "TestCheckTypeSetElemAttr", "tags.*", tag) + } + } + + return result +} + +func TestResourceFreeformSystem(t *testing.T) { + ctx := context.Background() + client := testutils.GetTestClient(t, ctx) + apiVersion := version.Must(version.NewVersion(client.ApiVersion())) + + // create a blueprint + bp := testutils.FfBlueprintA(t, ctx) + // get a device profile + dpId, _ := bp.ImportDeviceProfile(ctx, "Juniper_vEX") + + type testStep struct { + config resourceFreeformSystem + } + type testCase struct { + apiVersionConstraints version.Constraints + steps []testStep + } + + testCases := map[string]testCase{ + "start_with_no_tags": { + steps: []testStep{ + { + config: resourceFreeformSystem{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + hostname: acctest.RandString(6), + deviceProfileId: string(dpId), + systemType: apstra.SystemTypeInternal.String(), + }, + }, + { + config: resourceFreeformSystem{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + hostname: acctest.RandString(6), + deviceProfileId: string(dpId), + deployMode: apstra.DeployModeDeploy.String(), + systemType: apstra.SystemTypeInternal.String(), + tags: randomStrings(rand.Intn(10)+2, 6), + }, + }, + { + config: resourceFreeformSystem{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + hostname: acctest.RandString(6), + deployMode: apstra.DeployModeUndeploy.String(), + systemType: apstra.SystemTypeInternal.String(), + deviceProfileId: string(dpId), + }, + }, + }, + }, + "start_with_tags": { + steps: []testStep{ + { + config: resourceFreeformSystem{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + hostname: acctest.RandString(6), + deviceProfileId: string(dpId), + deployMode: apstra.DeployModeDeploy.String(), + systemType: apstra.SystemTypeInternal.String(), + tags: randomStrings(rand.Intn(10)+2, 6), + }, + }, + { + config: resourceFreeformSystem{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + hostname: acctest.RandString(6), + deployMode: apstra.DeployModeUndeploy.String(), + systemType: apstra.SystemTypeExternal.String(), + deviceProfileId: string(dpId), + }, + }, + { + config: resourceFreeformSystem{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + hostname: acctest.RandString(6), + deviceProfileId: string(dpId), + deployMode: apstra.DeployModeDeploy.String(), + systemType: apstra.SystemTypeExternal.String(), + tags: randomStrings(rand.Intn(10)+2, 6), + }, + }, + }, + }, + } + + resourceType := tfapstra.ResourceName(ctx, &tfapstra.ResourceFreeformSystem) + + for tName, tCase := range testCases { + tName, tCase := tName, tCase + t.Run(tName, func(t *testing.T) { + t.Parallel() + if !tCase.apiVersionConstraints.Check(apiVersion) { + t.Skipf("test case %s requires Apstra %s", tName, tCase.apiVersionConstraints.String()) + } + + steps := make([]resource.TestStep, len(tCase.steps)) + for i, step := range tCase.steps { + config := step.config.render(resourceType, tName) + checks := step.config.testChecks(t, resourceType, tName) + + chkLog := checks.string() + stepName := fmt.Sprintf("test case %q step %d", tName, i+1) + + t.Logf("\n// ------ begin config for %s ------\n%s// -------- end config for %s ------\n\n", stepName, config, stepName) + t.Logf("\n// ------ begin checks for %s ------\n%s// -------- end checks for %s ------\n\n", stepName, chkLog, stepName) + + steps[i] = resource.TestStep{ + Config: insecureProviderConfigHCL + config, + Check: resource.ComposeAggregateTestCheckFunc(checks.checks...), + } + } + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: steps, + }) + }) + } +} diff --git a/docs/data-sources/freeform_property_set.md b/docs/data-sources/freeform_property_set.md index a6df6e35..68d885b1 100644 --- a/docs/data-sources/freeform_property_set.md +++ b/docs/data-sources/freeform_property_set.md @@ -20,9 +20,9 @@ At least one optional attribute is required. # first we create a property set so we can use a data source to retrieve it. resource "apstra_freeform_property_set" "prop_set_foo" { - blueprint_id = "freeform_blueprint-5ba09d07" + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" name = "prop_set_foo" - values = jsonencode({ + values = jsonencode({ foo = "bar" clown = 2 }) @@ -31,21 +31,21 @@ resource "apstra_freeform_property_set" "prop_set_foo" { # here we retrieve the property_set. data "apstra_freeform_property_set" "foo" { - blueprint_id = "freeform_blueprint-5ba09d07" + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" name = apstra_freeform_property_set.prop_set_foo.name } -#here we build an output block to display it. -output "foo" {value = data.apstra_freeform_property_set.foo} - -#Output looks like this -#foo = { -# "blueprint_id" = "freeform_blueprint-5ba09d07" -# "id" = tostring(null) -# "name" = "prop_set_foo" -# "system_id" = tostring(null) -# "values" = "{\"clown\": 2, \"foo\": \"bar\"}" -#} +# here we build an output block to display it. +output "foo" { value = data.apstra_freeform_property_set.foo } + +# Output looks like this +# foo = { +# "blueprint_id" = "043c5787-66e8-41c7-8925-c7e52fbe6e32" +# "id" = tostring(null) +# "name" = "prop_set_foo" +# "system_id" = tostring(null) +# "values" = "{\"clown\": 2, \"foo\": \"bar\"}" +# } ``` diff --git a/docs/data-sources/freeform_system.md b/docs/data-sources/freeform_system.md index ab710fac..bf6a546a 100644 --- a/docs/data-sources/freeform_system.md +++ b/docs/data-sources/freeform_system.md @@ -16,7 +16,45 @@ At least one optional attribute is required. ## Example Usage ```terraform -# +# This example defines a freeform system in a blueprint + +resource "apstra_freeform_system" "test" { + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" + name = "test_system" + tags = ["a", "b", "c"] + type = "internal" + hostname = "testsystem" + deploy_mode = "deploy" + device_profile_id = "PtrWb4-VSwKiYRbCodk" +} + +# here we retrieve the freeform system + +data "apstra_freeform_system" "test" { + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" + id = apstra_freeform_system.test.id +} + +# here we build an output bock to display it + +output "test_System_out" {value = data.apstra_freeform_system.test} + +# Output looks like this +# test_System_out = { +# "blueprint_id" = "043c5787-66e8-41c7-8925-c7e52fbe6e32" +# "deploy_mode" = tostring(null) +# "device_profile_id" = "PtrWb4-VSwKiYRbCodk" +# "hostname" = "systemfoo" +# "id" = "-63CYLAiWuAq0ljzX0Q" +# "name" = "test_system_foo" +# "system_id" = tostring(null) +# "tags" = toset([ +# "a", +# "b", +# "c", +# ]) +# "type" = "internal" +# } ``` diff --git a/docs/resources/freeform_property_set.md b/docs/resources/freeform_property_set.md index 2a70cc13..9fdc9d4a 100644 --- a/docs/resources/freeform_property_set.md +++ b/docs/resources/freeform_property_set.md @@ -16,7 +16,7 @@ This resource creates a Property Set in a Freeform Blueprint. # Create a freeform property set resource. resource "apstra_freeform_property_set" "prop_set_foo" { - blueprint_id = "freeform_blueprint-5ba09d07" + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" name = "prop_set_foo" values = jsonencode({ foo = "bar" @@ -27,7 +27,7 @@ resource "apstra_freeform_property_set" "prop_set_foo" { # Read the property set back with a data source. data "apstra_freeform_property_set" "foods" { - blueprint_id = "freeform_blueprint-5ba09d07" + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" name = apstra_freeform_property_set.prop_set_foo.name } @@ -36,13 +36,13 @@ data "apstra_freeform_property_set" "foods" { output "foo" {value = data.apstra_freeform_property_set.foods} # Output should look like: -#foo = { -# "blueprint_id" = "freeform_blueprint-5ba09d07" -# "id" = tostring(null) -# "name" = "prop_set_foo" -# "system_id" = tostring(null) -# "values" = "{\"clown\": 2, \"foo\": \"bar\"}" -#} +# foo = { +# "blueprint_id" = "freeform_blueprint-5ba09d07" +# "id" = tostring(null) +# "name" = "prop_set_foo" +# "system_id" = tostring(null) +# "values" = "{\"clown\": 2, \"foo\": \"bar\"}" +# } ``` diff --git a/docs/resources/freeform_system.md b/docs/resources/freeform_system.md index 308c48b7..72e2e773 100644 --- a/docs/resources/freeform_system.md +++ b/docs/resources/freeform_system.md @@ -13,7 +13,46 @@ This resource creates a System in a Freeform Blueprint. ## Example Usage ```terraform -# +# This example defines a freeform system in a blueprint + + +resource "apstra_freeform_system" "test" { + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" + name = "test_system" + tags = ["a", "b", "c"] + type = "internal" + hostname = "testsystem" + deploy_mode = "deploy" + device_profile_id = "PtrWb4-VSwKiYRbCodk" +} + +# here we retrieve the freeform system + +data "apstra_freeform_system" "test" { + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" + id = apstra_freeform_system.test.id +} + +# here we build an output bock to display it + +output "test_System_out" { value = data.apstra_freeform_system.test } + +# Output looks like this +# test_System_out = { +# "blueprint_id" = "043c5787-66e8-41c7-8925-c7e52fbe6e32" +# "deploy_mode" = tostring(null) +# "device_profile_id" = "PtrWb4-VSwKiYRbCodk" +# "hostname" = "systemfoo" +# "id" = "-63CYLAiWuAq0ljzX0Q" +# "name" = "test_system_foo" +# "system_id" = tostring(null) +# "tags" = toset([ +# "a", +# "b", +# "c", +# ]) +# "type" = "internal" +# } ``` @@ -22,6 +61,7 @@ This resource creates a System in a Freeform Blueprint. ### Required - `blueprint_id` (String) Apstra Blueprint ID. +- `hostname` (String) Hostname of the Freeform System. - `name` (String) Freeform System name as shown in the Web UI. - `type` (String) Type of the System. Must be one of `internal` or `external` @@ -29,7 +69,6 @@ This resource creates a System in a Freeform Blueprint. - `deploy_mode` (String) Deploy mode of the System - `device_profile_id` (String) Device profile ID of the System -- `hostname` (String) Hostname of the Freeform System. - `system_id` (String) ID (usually serial number) of the Managed Device to associate with this System - `tags` (Set of String) Set of Tag labels diff --git a/examples/data-sources/apstra_freeform_property_set/example.tf b/examples/data-sources/apstra_freeform_property_set/example.tf index 723ac049..741bdad0 100644 --- a/examples/data-sources/apstra_freeform_property_set/example.tf +++ b/examples/data-sources/apstra_freeform_property_set/example.tf @@ -2,9 +2,9 @@ # first we create a property set so we can use a data source to retrieve it. resource "apstra_freeform_property_set" "prop_set_foo" { - blueprint_id = "freeform_blueprint-5ba09d07" + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" name = "prop_set_foo" - values = jsonencode({ + values = jsonencode({ foo = "bar" clown = 2 }) @@ -13,19 +13,19 @@ resource "apstra_freeform_property_set" "prop_set_foo" { # here we retrieve the property_set. data "apstra_freeform_property_set" "foo" { - blueprint_id = "freeform_blueprint-5ba09d07" + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" name = apstra_freeform_property_set.prop_set_foo.name } -#here we build an output block to display it. -output "foo" {value = data.apstra_freeform_property_set.foo} +# here we build an output block to display it. +output "foo" { value = data.apstra_freeform_property_set.foo } -#Output looks like this -#foo = { -# "blueprint_id" = "freeform_blueprint-5ba09d07" -# "id" = tostring(null) -# "name" = "prop_set_foo" -# "system_id" = tostring(null) -# "values" = "{\"clown\": 2, \"foo\": \"bar\"}" -#} +# Output looks like this +# foo = { +# "blueprint_id" = "043c5787-66e8-41c7-8925-c7e52fbe6e32" +# "id" = tostring(null) +# "name" = "prop_set_foo" +# "system_id" = tostring(null) +# "values" = "{\"clown\": 2, \"foo\": \"bar\"}" +# } diff --git a/examples/data-sources/apstra_freeform_system/example.tf b/examples/data-sources/apstra_freeform_system/example.tf index 792d6005..a0643c8f 100644 --- a/examples/data-sources/apstra_freeform_system/example.tf +++ b/examples/data-sources/apstra_freeform_system/example.tf @@ -1 +1,40 @@ -# +# This example defines a freeform system in a blueprint + +resource "apstra_freeform_system" "test" { + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" + name = "test_system" + tags = ["a", "b", "c"] + type = "internal" + hostname = "testsystem" + deploy_mode = "deploy" + device_profile_id = "PtrWb4-VSwKiYRbCodk" +} + +# here we retrieve the freeform system + +data "apstra_freeform_system" "test" { + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" + id = apstra_freeform_system.test.id +} + +# here we build an output bock to display it + +output "test_System_out" {value = data.apstra_freeform_system.test} + +# Output looks like this +# test_System_out = { +# "blueprint_id" = "043c5787-66e8-41c7-8925-c7e52fbe6e32" +# "deploy_mode" = tostring(null) +# "device_profile_id" = "PtrWb4-VSwKiYRbCodk" +# "hostname" = "systemfoo" +# "id" = "-63CYLAiWuAq0ljzX0Q" +# "name" = "test_system_foo" +# "system_id" = tostring(null) +# "tags" = toset([ +# "a", +# "b", +# "c", +# ]) +# "type" = "internal" +# } + diff --git a/examples/resources/apstra_freeform_property_set/example.tf b/examples/resources/apstra_freeform_property_set/example.tf index 6fe62bc0..28f3249b 100644 --- a/examples/resources/apstra_freeform_property_set/example.tf +++ b/examples/resources/apstra_freeform_property_set/example.tf @@ -1,7 +1,7 @@ # Create a freeform property set resource. resource "apstra_freeform_property_set" "prop_set_foo" { - blueprint_id = "freeform_blueprint-5ba09d07" + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" name = "prop_set_foo" values = jsonencode({ foo = "bar" @@ -12,7 +12,7 @@ resource "apstra_freeform_property_set" "prop_set_foo" { # Read the property set back with a data source. data "apstra_freeform_property_set" "foods" { - blueprint_id = "freeform_blueprint-5ba09d07" + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" name = apstra_freeform_property_set.prop_set_foo.name } @@ -21,10 +21,10 @@ data "apstra_freeform_property_set" "foods" { output "foo" {value = data.apstra_freeform_property_set.foods} # Output should look like: -#foo = { -# "blueprint_id" = "freeform_blueprint-5ba09d07" -# "id" = tostring(null) -# "name" = "prop_set_foo" -# "system_id" = tostring(null) -# "values" = "{\"clown\": 2, \"foo\": \"bar\"}" -#} +# foo = { +# "blueprint_id" = "freeform_blueprint-5ba09d07" +# "id" = tostring(null) +# "name" = "prop_set_foo" +# "system_id" = tostring(null) +# "values" = "{\"clown\": 2, \"foo\": \"bar\"}" +# } diff --git a/examples/resources/apstra_freeform_system/example.tf b/examples/resources/apstra_freeform_system/example.tf index 792d6005..22cbafa4 100644 --- a/examples/resources/apstra_freeform_system/example.tf +++ b/examples/resources/apstra_freeform_system/example.tf @@ -1 +1,40 @@ -# +# This example defines a freeform system in a blueprint + + +resource "apstra_freeform_system" "test" { + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" + name = "test_system" + tags = ["a", "b", "c"] + type = "internal" + hostname = "testsystem" + deploy_mode = "deploy" + device_profile_id = "PtrWb4-VSwKiYRbCodk" +} + +# here we retrieve the freeform system + +data "apstra_freeform_system" "test" { + blueprint_id = "043c5787-66e8-41c7-8925-c7e52fbe6e32" + id = apstra_freeform_system.test.id +} + +# here we build an output bock to display it + +output "test_System_out" { value = data.apstra_freeform_system.test } + +# Output looks like this +# test_System_out = { +# "blueprint_id" = "043c5787-66e8-41c7-8925-c7e52fbe6e32" +# "deploy_mode" = tostring(null) +# "device_profile_id" = "PtrWb4-VSwKiYRbCodk" +# "hostname" = "systemfoo" +# "id" = "-63CYLAiWuAq0ljzX0Q" +# "name" = "test_system_foo" +# "system_id" = tostring(null) +# "tags" = toset([ +# "a", +# "b", +# "c", +# ]) +# "type" = "internal" +# }