diff --git a/README.md b/README.md index ced7576..928d9af 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Terraform provider для платформы Digital Energy Cloud Orchestration - Работа с pfw, - Работа с accounts, - Работа с snapshots, +- Работа с pcidevice, - Работа с sep. Вики проекта: https://github.com/rudecs/terraform-provider-decort/wiki diff --git a/README_EN.md b/README_EN.md index 34e3625..e337988 100644 --- a/README_EN.md +++ b/README_EN.md @@ -15,6 +15,7 @@ NOTE: provider rc-1.25 is designed for DECORT API 3.7.x. For older API versions - Work with pfw, - Work with accounts, - Work with snapshots, +- Work with pcidevice. - Work with sep. This provider supports Import operations on pre-existing resources. diff --git a/decort/data_source_pcidevice.go b/decort/data_source_pcidevice.go new file mode 100644 index 0000000..e3fa314 --- /dev/null +++ b/decort/data_source_pcidevice.go @@ -0,0 +1,128 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Author: Stanislav Solovev, , + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration +Technology platfom. + +Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates. +*/ + +package decort + +import ( + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func dataSourcePcideviceRead(d *schema.ResourceData, m interface{}) error { + pcidevice, err := utilityPcideviceCheckPresence(d, m) + if err != nil { + return err + } + + d.Set("ckey", pcidevice.CKey) + d.Set("meta", flattenMeta(pcidevice.Meta)) + d.Set("compute_id", pcidevice.Computeid) + d.Set("description", pcidevice.Description) + d.Set("guid", pcidevice.Guid) + d.Set("hw_path", pcidevice.HwPath) + d.Set("rg_id", pcidevice.RgID) + d.Set("name", pcidevice.Name) + d.Set("stack_id", pcidevice.StackID) + d.Set("status", pcidevice.Status) + d.Set("system_name", pcidevice.SystemName) + + d.SetId(strconv.Itoa(d.Get("device_id").(int))) + + return nil +} + +func dataSourcePcideviceSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "device_id": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "hw_path": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stack_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "system_name": { + Type: schema.TypeString, + Computed: true, + }, + } + + return rets +} + +func dataSourcePcidevice() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Read: dataSourcePcideviceRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &Timeout30s, + Default: &Timeout60s, + }, + + Schema: dataSourcePcideviceSchemaMake(), + } +} diff --git a/decort/data_source_pcidevice_list.go b/decort/data_source_pcidevice_list.go new file mode 100644 index 0000000..2ee469d --- /dev/null +++ b/decort/data_source_pcidevice_list.go @@ -0,0 +1,152 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Author: Stanislav Solovev, , + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration +Technology platfom. + +Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates. +*/ + +package decort + +import ( + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func flattenPcideviceList(pl PcideviceList) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, item := range pl { + temp := map[string]interface{}{ + "ckey": item.CKey, + "meta": flattenMeta(item.Meta), + "compute_id": item.Computeid, + "description": item.Description, + "guid": item.Guid, + "hw_path": item.HwPath, + "device_id": item.ID, + "rg_id": item.RgID, + "name": item.Name, + "stack_id": item.StackID, + "status": item.Status, + "system_name": item.SystemName, + } + res = append(res, temp) + } + return res +} + +func dataSourcePcideviceListRead(d *schema.ResourceData, m interface{}) error { + pcideviceList, err := utilityPcideviceListCheckPresence(d, m) + if err != nil { + return err + } + + d.Set("items", flattenPcideviceList(pcideviceList)) + + id := uuid.New() + d.SetId(id.String()) + + return nil +} + +func dataSourcePcideviceItem() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "hw_path": { + Type: schema.TypeString, + Computed: true, + }, + "device_id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stack_id": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "system_name": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func dataSourcePcideviceListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "items": { + Type: schema.TypeList, + Computed: true, + Description: "pcidevice list", + Elem: &schema.Resource{ + Schema: dataSourcePcideviceItem(), + }, + }, + } + + return rets +} + +func dataSourcePcideviceList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Read: dataSourcePcideviceListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &Timeout30s, + Default: &Timeout60s, + }, + + Schema: dataSourcePcideviceListSchemaMake(), + } +} diff --git a/decort/models_api.go b/decort/models_api.go index 8657058..578dc81 100644 --- a/decort/models_api.go +++ b/decort/models_api.go @@ -836,6 +836,33 @@ type Snapshot struct { type SnapshotList []Snapshot +///////////////////////////// +// PCIDEVICE // +///////////////////////////// + +const pcideviceListAPI = "/restmachine/cloudbroker/pcidevice/list" +const pcideviceDisableAPI = "/restmachine/cloudbroker/pcidevice/disable" +const pcideviceEnableAPI = "/restmachine/cloudbroker/pcidevice/enable" +const pcideviceCreateAPI = "/restmachine/cloudbroker/pcidevice/create" +const pcideviceDeleteAPI = "/restmachine/cloudbroker/pcidevice/delete" + +type Pcidevice struct { + CKey string `json:"_ckey"` + Meta []interface{} `json:"_meta"` + Computeid int `json:"computeId"` + Description string `json:"description"` + Guid int `json:"guid"` + HwPath string `json:"hwPath"` + ID int `json:"id"` + Name string `json:"name"` + RgID int `json:"rgId"` + StackID int `json:"stackId"` + Status string `json:"status"` + SystemName string `json:"systemName"` +} + +type PcideviceList []Pcidevice + /////////////////// ///// SEP API ///// /////////////////// diff --git a/decort/provider.go b/decort/provider.go index 69b95ef..4119219 100644 --- a/decort/provider.go +++ b/decort/provider.go @@ -111,6 +111,7 @@ func Provider() *schema.Provider { "decort_cdrom_image": resourceCDROMImage(), "decort_delete_images": resourceDeleteImages(), "decort_snapshot": resourceSnapshot(), + "decort_pcidevice": resourcePcidevice(), "decort_sep": resourceSep(), "decort_sep_config": resourceSepConfig(), }, @@ -127,6 +128,8 @@ func Provider() *schema.Provider { "decort_image_list": dataSourceImageList(), "decort_image_list_stacks": dataSourceImageListStacks(), "decort_snapshot_list": dataSourceSnapshotList(), + "decort_pcidevice": dataSourcePcidevice(), + "decort_pcidevice_list": dataSourcePcideviceList(), "decort_sep_list": dataSourceSepList(), "decort_sep": dataSourceSep(), "decort_sep_consumption": dataSourceSepConsumption(), diff --git a/decort/resource_pcidevice.go b/decort/resource_pcidevice.go new file mode 100644 index 0000000..470ddb1 --- /dev/null +++ b/decort/resource_pcidevice.go @@ -0,0 +1,263 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Author: Stanislav Solovev, + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration +Technology platfom. + +Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates. +*/ + +package decort + +import ( + "errors" + "net/url" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + log "github.com/sirupsen/logrus" +) + +func resourcePcideviceCreate(d *schema.ResourceData, m interface{}) error { + log.Debugf("resourcePcideviceCreate: called for pcidevice %s", d.Get("name").(string)) + + if deviceId, ok := d.GetOk("device_id"); ok { + if exists, err := resourcePcideviceExists(d, m); exists { + if err != nil { + return err + } + d.SetId(strconv.Itoa(deviceId.(int))) + err = resourcePcideviceRead(d, m) + if err != nil { + return err + } + + return nil + } + return errors.New("provided device id does not exist") + } + + controller := m.(*ControllerCfg) + urlValues := &url.Values{} + urlValues.Add("name", d.Get("name").(string)) + urlValues.Add("hwPath", d.Get("hw_path").(string)) + urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) + urlValues.Add("stackId", strconv.Itoa(d.Get("stack_id").(int))) + + if description, ok := d.GetOk("description"); ok { + urlValues.Add("description", description.(string)) + } + + pcideviceId, err := controller.decortAPICall("POST", pcideviceCreateAPI, urlValues) + if err != nil { + return err + } + + d.SetId(pcideviceId) + d.Set("device_id", pcideviceId) + + err = resourcePcideviceRead(d, m) + if err != nil { + return err + } + + return nil +} + +func resourcePcideviceRead(d *schema.ResourceData, m interface{}) error { + pcidevice, err := utilityPcideviceCheckPresence(d, m) + if err != nil { + return err + } + + d.SetId(strconv.Itoa(pcidevice.ID)) + d.Set("ckey", pcidevice.CKey) + d.Set("meta", flattenMeta(pcidevice.Meta)) + d.Set("compute_id", pcidevice.Computeid) + d.Set("description", pcidevice.Description) + d.Set("guid", pcidevice.Guid) + d.Set("hw_path", pcidevice.HwPath) + d.Set("device_id", pcidevice.ID) + d.Set("rg_id", pcidevice.RgID) + d.Set("name", pcidevice.Name) + d.Set("stack_id", pcidevice.StackID) + d.Set("status", pcidevice.Status) + d.Set("system_name", pcidevice.SystemName) + + return nil +} + +func resourcePcideviceDelete(d *schema.ResourceData, m interface{}) error { + log.Debugf("resourcePcideviceDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) + + controller := m.(*ControllerCfg) + urlValues := &url.Values{} + urlValues.Add("deviceId", d.Id()) + urlValues.Add("force", strconv.FormatBool(d.Get("force").(bool))) + + _, err := controller.decortAPICall("POST", pcideviceDeleteAPI, urlValues) + if err != nil { + return err + } + + d.SetId("") + + return nil +} + +func resourcePcideviceExists(d *schema.ResourceData, m interface{}) (bool, error) { + pcidevice, err := utilityPcideviceCheckPresence(d, m) + if err != nil { + return false, err + } + if pcidevice == nil { + return false, nil + } + + return true, nil +} + +func resourcePcideviceEdit(d *schema.ResourceData, m interface{}) error { + if d.HasChange("enable") { + state := d.Get("enable").(bool) + c := m.(*ControllerCfg) + urlValues := &url.Values{} + api := "" + + urlValues.Add("deviceId", strconv.Itoa(d.Get("device_id").(int))) + + if state { + api = pcideviceEnableAPI + } else { + api = pcideviceDisableAPI + } + + _, err := c.decortAPICall("POST", api, urlValues) + if err != nil { + return err + } + } + + err := resourcePcideviceRead(d, m) + if err != nil { + return err + } + + return nil +} + +func resourcePcideviceSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "ckey": { + Type: schema.TypeString, + Computed: true, + }, + "meta": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "description, just for information", + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "hw_path": { + Type: schema.TypeString, + Required: true, + Description: "PCI address of the device", + }, + "device_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of Device", + }, + "rg_id": { + Type: schema.TypeInt, + Required: true, + Description: "Resource GROUP", + }, + "stack_id": { + Type: schema.TypeInt, + Required: true, + Description: "stackId", + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "system_name": { + Type: schema.TypeString, + Computed: true, + }, + "force": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Force delete", + }, + "enable": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Enable pci device", + }, + } +} + +func resourcePcidevice() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Create: resourcePcideviceCreate, + Read: resourcePcideviceRead, + Update: resourcePcideviceEdit, + Delete: resourcePcideviceDelete, + Exists: resourcePcideviceExists, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &Timeout60s, + Read: &Timeout30s, + Update: &Timeout60s, + Delete: &Timeout60s, + Default: &Timeout60s, + }, + + Schema: resourcePcideviceSchemaMake(), + } +} diff --git a/decort/utility_pcidevice.go b/decort/utility_pcidevice.go new file mode 100644 index 0000000..2782ac1 --- /dev/null +++ b/decort/utility_pcidevice.go @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Author: Stanislav Solovev, , + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration +Technology platfom. + +Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates. +*/ + +package decort + +import ( + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func utilityPcideviceCheckPresence(d *schema.ResourceData, m interface{}) (*Pcidevice, error) { + pcideviceList, err := utilityPcideviceListCheckPresence(d, m) + if err != nil { + return nil, err + } + + pcideviceId := 0 + if (d.Get("device_id").(int)) != 0 { + pcideviceId = d.Get("device_id").(int) + } else { + id, _ := strconv.Atoi(d.Id()) + pcideviceId = id + } + pcidevice := &Pcidevice{} + + flag := false + + for _, pd := range pcideviceList { + if pd.ID == pcideviceId { + pcidevice = &pd + flag = true + break + } + } + + if !flag { + return nil, nil + } + + return pcidevice, nil +} diff --git a/decort/utility_pcidevice_list.go b/decort/utility_pcidevice_list.go new file mode 100644 index 0000000..6767c7d --- /dev/null +++ b/decort/utility_pcidevice_list.go @@ -0,0 +1,50 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Author: Stanislav Solovev, , + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration +Technology platfom. + +Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates. +*/ + +package decort + +import ( + "encoding/json" + "net/url" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func utilityPcideviceListCheckPresence(d *schema.ResourceData, m interface{}) (PcideviceList, error) { + pcideviceList := PcideviceList{} + controller := m.(*ControllerCfg) + urlValues := &url.Values{} + + pcideviceListRaw, err := controller.decortAPICall("POST", pcideviceListAPI, urlValues) + if err != nil { + return nil, err + } + + err = json.Unmarshal([]byte(pcideviceListRaw), &pcideviceList) + if err != nil { + return nil, err + } + + return pcideviceList, nil +} diff --git a/samples/README.md b/samples/README.md index b27fa02..9a4a0ed 100644 --- a/samples/README.md +++ b/samples/README.md @@ -9,6 +9,8 @@ - image_list - image_list_stacks - snapshot_list + - pcidevice_list + - pcidevice - sep - sep_list - sep_disk_list @@ -23,6 +25,7 @@ - k8s - k8s_wg - snapshot + - pcidevice - sep - sep_config diff --git a/samples/data_pcidevice/main.tf b/samples/data_pcidevice/main.tf new file mode 100644 index 0000000..137f403 --- /dev/null +++ b/samples/data_pcidevice/main.tf @@ -0,0 +1,39 @@ +/* +Пример использования +Получение информации об устройстве + +*/ +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + version = "1.1" + source = "digitalenergy.online/decort/decort" + } + } +} +*/ + + +provider "decort" { + authenticator = "oauth2" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_pcidevice" "pd" { + #id устройства + #обязательный параметр + #тип - число + device_id = 85 +} + +output "test" { + value = data.decort_pcidevice.pd +} diff --git a/samples/data_pcidevice_list/main.tf b/samples/data_pcidevice_list/main.tf new file mode 100644 index 0000000..6597c5c --- /dev/null +++ b/samples/data_pcidevice_list/main.tf @@ -0,0 +1,34 @@ +/* +Пример использования +Получение информации обо всех доступных устройствах + +*/ +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером + +/* +terraform { + required_providers { + decort = { + version = "1.1" + source = "digitalenergy.online/decort/decort" + } + } +} +*/ + +provider "decort" { + authenticator = "oauth2" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_pcidevice_list" "pdl" {} + +output "test" { + value = data.decort_pcidevice_list.pdl.items +} diff --git a/samples/resource_pcidevice/main.tf b/samples/resource_pcidevice/main.tf new file mode 100644 index 0000000..fd7b112 --- /dev/null +++ b/samples/resource_pcidevice/main.tf @@ -0,0 +1,85 @@ +/* +Пример использования +Ресурса pdidevice +Ресурс позволяет: +1. Создавать устройство +2. Редактировать устройство +3. Удалять устройство + +*/ +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + version = "1.1" + source = "digitalenergy.online/decort/decort" + } + } +} +*/ + + +provider "decort" { + authenticator = "oauth2" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +resource "decort_pcidevice" "pd" { + #имя устройства + #обязательный параметр + #тип - строка + name = "test_device" + + #путь до устройства + #обязательный параметр + #тип - строка + hw_path = "0000:01:00.0" + + #описание устройства + #обязательный параметр + #тип - строка + description = "test desc" + + #id ресурсной группы устройства + #обязательный параметр + #тип - число + rg_id = 1111 + + #id стака устройства + #обязательный параметр + #тип - число + stack_id = 11 + + #доступность устройства + #опциональный параметр + #может использоваться на созданном ресурсе + #тип - булево значение + #enable = false + + #принудительное удаление устройства + #опциональный параметр + #используется при удалении ресурса + #тип - булево значение + #force = true + + + #id устройства + #опциональный параметр + #позволяет "восстановить" состояние ресурса терраформа на локальной машине + #тип - число + #device_id = 86 + + +} + +output "test" { + value = decort_pcidevice.pd +}