diff --git a/internal/services/compute/shared_image_data_source.go b/internal/services/compute/shared_image_data_source.go index 6816ce7378e8..bfefcf48ba10 100644 --- a/internal/services/compute/shared_image_data_source.go +++ b/internal/services/compute/shared_image_data_source.go @@ -5,6 +5,7 @@ package compute import ( "fmt" + "strings" "time" "github.com/hashicorp/go-azure-helpers/lang/pointer" @@ -126,6 +127,36 @@ func dataSourceSharedImage() *pluginsdk.Resource { Computed: true, }, + "trusted_launch_supported": { + Type: pluginsdk.TypeBool, + Computed: true, + }, + + "trusted_launch_enabled": { + Type: pluginsdk.TypeBool, + Computed: true, + }, + + "confidential_vm_supported": { + Type: pluginsdk.TypeBool, + Computed: true, + }, + + "confidential_vm_enabled": { + Type: pluginsdk.TypeBool, + Computed: true, + }, + + "accelerated_network_support_enabled": { + Type: pluginsdk.TypeBool, + Computed: true, + }, + + "hibernation_enabled": { + Type: pluginsdk.TypeBool, + Computed: true, + }, + "tags": commonschema.TagsDataSource(), }, } @@ -174,6 +205,42 @@ func dataSourceSharedImageRead(d *pluginsdk.ResourceData, meta interface{}) erro if err := d.Set("purchase_plan", flattenGalleryImageDataSourcePurchasePlan(props.PurchasePlan)); err != nil { return fmt.Errorf("setting `purchase_plan`: %+v", err) } + + trustedLaunchSupported := false + trustedLaunchEnabled := false + cvmEnabled := false + cvmSupported := false + acceleratedNetworkSupportEnabled := false + hibernationEnabled := false + if model.Properties.Features != nil { + for _, feature := range *model.Properties.Features { + if feature.Name == nil || feature.Value == nil { + continue + } + + if strings.EqualFold(*feature.Name, "SecurityType") { + trustedLaunchSupported = strings.EqualFold(*feature.Value, "TrustedLaunchSupported") + trustedLaunchEnabled = strings.EqualFold(*feature.Value, "TrustedLaunch") + cvmSupported = strings.EqualFold(*feature.Value, "ConfidentialVmSupported") + cvmEnabled = strings.EqualFold(*feature.Value, "ConfidentialVm") + } + + if strings.EqualFold(*feature.Name, "IsAcceleratedNetworkSupported") { + acceleratedNetworkSupportEnabled = strings.EqualFold(*feature.Value, "true") + } + + if strings.EqualFold(*feature.Name, "IsHibernateSupported") { + hibernationEnabled = strings.EqualFold(*feature.Value, "true") + } + } + } + + d.Set("confidential_vm_supported", cvmSupported) + d.Set("confidential_vm_enabled", cvmEnabled) + d.Set("trusted_launch_supported", trustedLaunchSupported) + d.Set("trusted_launch_enabled", trustedLaunchEnabled) + d.Set("accelerated_network_support_enabled", acceleratedNetworkSupportEnabled) + d.Set("hibernation_enabled", hibernationEnabled) } return tags.FlattenAndSet(d, model.Tags) diff --git a/internal/services/compute/shared_image_data_source_test.go b/internal/services/compute/shared_image_data_source_test.go index 58e3018977de..7b02813f355d 100644 --- a/internal/services/compute/shared_image_data_source_test.go +++ b/internal/services/compute/shared_image_data_source_test.go @@ -21,6 +21,7 @@ func TestAccDataSourceSharedImage_basic(t *testing.T) { Config: r.basic(data, ""), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).Key("tags.%").HasValue("0"), + check.That(data.ResourceName).Key("hibernation_enabled").HasValue("false"), ), }, }) @@ -57,6 +58,90 @@ func TestAccDataSourceSharedImage_complete(t *testing.T) { }) } +func TestAccDataSourceSharedImage_hibernationEnabled(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_shared_image", "test") + r := SharedImageDataSource{} + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.withHibernationEnabled(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("tags.%").HasValue("0"), + check.That(data.ResourceName).Key("hibernation_enabled").HasValue("true"), + ), + }, + }) +} + +func TestAccDataSourceSharedImage_acceleratedNetworkSupportEnabled(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_shared_image", "test") + r := SharedImageDataSource{} + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.withAcceleratedNetworkSupportEnabled(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("tags.%").HasValue("0"), + check.That(data.ResourceName).Key("accelerated_network_support_enabled").HasValue("true"), + ), + }, + }) +} + +func TestAccDataSourceSharedImage_trustedLaunchEnabled(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_shared_image", "test") + r := SharedImageDataSource{} + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.withTrustedLaunchEnabled(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("tags.%").HasValue("0"), + check.That(data.ResourceName).Key("trusted_launch_enabled").HasValue("true"), + ), + }, + }) +} + +func TestAccDataSourceSharedImage_trustedLaunchSupported(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_shared_image", "test") + r := SharedImageDataSource{} + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.withTrustedLaunchSupported(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("tags.%").HasValue("0"), + check.That(data.ResourceName).Key("trusted_launch_supported").HasValue("true"), + ), + }, + }) +} + +func TestAccDataSourceSharedImage_confidentialVMEnabled(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_shared_image", "test") + r := SharedImageDataSource{} + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.withConfidentialVM(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("tags.%").HasValue("0"), + check.That(data.ResourceName).Key("confidential_vm_enabled").HasValue("true"), + ), + }, + }) +} + +func TestAccDataSourceSharedImage_confidentialVMSupported(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_shared_image", "test") + r := SharedImageDataSource{} + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.withConfidentialVMSupported(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("tags.%").HasValue("0"), + check.That(data.ResourceName).Key("confidential_vm_supported").HasValue("true"), + ), + }, + }) +} + func (SharedImageDataSource) basic(data acceptance.TestData, hyperVGen string) string { return fmt.Sprintf(` %s @@ -80,3 +165,75 @@ data "azurerm_shared_image" "test" { } `, SharedImageResource{}.completeWithHyperVGen(data, hyperVGen)) } + +func (SharedImageDataSource) withHibernationEnabled(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_shared_image" "test" { + name = azurerm_shared_image.test.name + gallery_name = azurerm_shared_image.test.gallery_name + resource_group_name = azurerm_shared_image.test.resource_group_name +} +`, SharedImageResource{}.withHibernationEnabled(data)) +} + +func (SharedImageDataSource) withAcceleratedNetworkSupportEnabled(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_shared_image" "test" { + name = azurerm_shared_image.test.name + gallery_name = azurerm_shared_image.test.gallery_name + resource_group_name = azurerm_shared_image.test.resource_group_name +} +`, SharedImageResource{}.withAcceleratedNetworkSupportEnabled(data)) +} + +func (SharedImageDataSource) withTrustedLaunchEnabled(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_shared_image" "test" { + name = azurerm_shared_image.test.name + gallery_name = azurerm_shared_image.test.gallery_name + resource_group_name = azurerm_shared_image.test.resource_group_name +} +`, SharedImageResource{}.withTrustedLaunchEnabled(data)) +} + +func (SharedImageDataSource) withTrustedLaunchSupported(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_shared_image" "test" { + name = azurerm_shared_image.test.name + gallery_name = azurerm_shared_image.test.gallery_name + resource_group_name = azurerm_shared_image.test.resource_group_name +} +`, SharedImageResource{}.withTrustedLaunchSupported(data)) +} + +func (SharedImageDataSource) withConfidentialVM(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_shared_image" "test" { + name = azurerm_shared_image.test.name + gallery_name = azurerm_shared_image.test.gallery_name + resource_group_name = azurerm_shared_image.test.resource_group_name +} +`, SharedImageResource{}.withConfidentialVM(data)) +} + +func (SharedImageDataSource) withConfidentialVMSupported(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_shared_image" "test" { + name = azurerm_shared_image.test.name + gallery_name = azurerm_shared_image.test.gallery_name + resource_group_name = azurerm_shared_image.test.resource_group_name +} +`, SharedImageResource{}.withConfidentialVmSupported(data)) +} diff --git a/internal/services/compute/shared_image_resource.go b/internal/services/compute/shared_image_resource.go index f13539c97b38..207d7fdfdb37 100644 --- a/internal/services/compute/shared_image_resource.go +++ b/internal/services/compute/shared_image_resource.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "log" + "strconv" "strings" "time" @@ -258,6 +259,12 @@ func resourceSharedImage() *pluginsdk.Resource { ForceNew: true, }, + "hibernation_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + ForceNew: true, + }, + "tags": commonschema.Tags(), }, @@ -516,6 +523,7 @@ func resourceSharedImageRead(d *pluginsdk.ResourceData, meta interface{}) error cvmEnabled := false cvmSupported := false acceleratedNetworkSupportEnabled := false + hibernationEnabled := false if features := props.Features; features != nil { for _, feature := range *features { if feature.Name == nil || feature.Value == nil { @@ -532,6 +540,10 @@ func resourceSharedImageRead(d *pluginsdk.ResourceData, meta interface{}) error if strings.EqualFold(*feature.Name, "IsAcceleratedNetworkSupported") { acceleratedNetworkSupportEnabled = strings.EqualFold(*feature.Value, "true") } + + if strings.EqualFold(*feature.Name, "IsHibernateSupported") { + hibernationEnabled = strings.EqualFold(*feature.Value, "true") + } } } d.Set("confidential_vm_supported", cvmSupported) @@ -539,6 +551,7 @@ func resourceSharedImageRead(d *pluginsdk.ResourceData, meta interface{}) error d.Set("trusted_launch_supported", trustedLaunchSupported) d.Set("trusted_launch_enabled", trustedLaunchEnabled) d.Set("accelerated_network_support_enabled", acceleratedNetworkSupportEnabled) + d.Set("hibernation_enabled", hibernationEnabled) } return tags.FlattenAndSet(d, model.Tags) @@ -759,5 +772,12 @@ func expandSharedImageFeatures(d *pluginsdk.ResourceData) *[]galleryimages.Galle }) } + if hibernationEnabled := d.Get("hibernation_enabled").(bool); hibernationEnabled { + features = append(features, galleryimages.GalleryImageFeature{ + Name: pointer.To("IsHibernateSupported"), + Value: pointer.To(strconv.FormatBool(hibernationEnabled)), + }) + } + return &features } diff --git a/internal/services/compute/shared_image_resource_test.go b/internal/services/compute/shared_image_resource_test.go index 5ab2b8eb1693..6710783052b2 100644 --- a/internal/services/compute/shared_image_resource_test.go +++ b/internal/services/compute/shared_image_resource_test.go @@ -186,6 +186,20 @@ func TestAccSharedImage_withAcceleratedNetworkSupportEnabled(t *testing.T) { }) } +func TestAccSharedImage_withHibernationEnabled(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_shared_image", "test") + r := SharedImageResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.withHibernationEnabled(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func TestAccSharedImage_description(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_shared_image", "test") r := SharedImageResource{} @@ -721,6 +735,41 @@ resource "azurerm_shared_image" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger) } +func (SharedImageResource) withHibernationEnabled(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_shared_image_gallery" "test" { + name = "acctestsig%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location +} + +resource "azurerm_shared_image" "test" { + name = "acctestimg%d" + gallery_name = azurerm_shared_image_gallery.test.name + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + os_type = "Linux" + + hibernation_enabled = true + + identifier { + publisher = "AccTesPublisher%d" + offer = "AccTesOffer%d" + sku = "AccTesSku%d" + } +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger) +} + func (SharedImageResource) description(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { diff --git a/website/docs/d/shared_image.html.markdown b/website/docs/d/shared_image.html.markdown index 45278b151b80..5f244f47c585 100644 --- a/website/docs/d/shared_image.html.markdown +++ b/website/docs/d/shared_image.html.markdown @@ -57,6 +57,18 @@ The following attributes are exported: * `release_note_uri` - The URI containing the Release Notes for this Shared Image. +* `trusted_launch_supported` - Specifies if supports creation of both Trusted Launch virtual machines and Gen2 virtual machines with standard security created from the Shared Image. + +* `trusted_launch_enabled` - Specifies if Trusted Launch has to be enabled for the Virtual Machine created from the Shared Image. + +* `confidential_vm_supported` - Specifies if supports creation of both Confidential virtual machines and Gen2 virtual machines with standard security from a compatible Gen2 OS disk VHD or Gen2 Managed image. + +* `confidential_vm_enabled` - Specifies if Confidential Virtual Machines enabled. It will enable all the features of trusted, with higher confidentiality features for isolate machines or encrypted data. Available for Gen2 machines. + +* `accelerated_network_support_enabled` - Specifies if the Shared Image supports Accelerated Network. + +* `hibernation_enabled` - Specifies if the Shared Image supports hibernation. + * `tags` - A mapping of tags assigned to the Shared Image. --- diff --git a/website/docs/r/shared_image.html.markdown b/website/docs/r/shared_image.html.markdown index 92ff00bfc489..13b14078bdcb 100644 --- a/website/docs/r/shared_image.html.markdown +++ b/website/docs/r/shared_image.html.markdown @@ -106,6 +106,8 @@ The following arguments are supported: * `accelerated_network_support_enabled` - (Optional) Specifies if the Shared Image supports Accelerated Network. Changing this forces a new resource to be created. +* `hibernation_enabled` - (Optional) Specifies if the Shared Image supports hibernation. Changing this forces a new resource to be created. + * `tags` - (Optional) A mapping of tags to assign to the Shared Image. ---