Merge pull request #5222 from Trip09/NO-TICKET-azure-allow-build-inside-vpc
[Azure] allow build inside vpc access via public IP
This commit is contained in:
commit
216317c49d
|
@ -119,7 +119,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
}
|
||||
|
||||
endpointConnectType := PublicEndpoint
|
||||
if b.isPrivateNetworkCommunication() {
|
||||
if b.isPublicPrivateNetworkCommunication() && b.isPrivateNetworkCommunication() {
|
||||
endpointConnectType = PublicEndpointInPrivateNetwork
|
||||
} else if b.isPrivateNetworkCommunication() {
|
||||
endpointConnectType = PrivateEndpoint
|
||||
}
|
||||
|
||||
|
@ -245,6 +247,10 @@ func (b *Builder) writeSSHPrivateKey(ui packer.Ui, debugKeyPath string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (b *Builder) isPublicPrivateNetworkCommunication() bool {
|
||||
return DefaultPrivateVirtualNetworkWithPublicIp != b.config.PrivateVirtualNetworkWithPublicIp
|
||||
}
|
||||
|
||||
func (b *Builder) isPrivateNetworkCommunication() bool {
|
||||
return b.config.VirtualNetworkName != ""
|
||||
}
|
||||
|
|
|
@ -34,10 +34,11 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
DefaultCloudEnvironmentName = "Public"
|
||||
DefaultImageVersion = "latest"
|
||||
DefaultUserName = "packer"
|
||||
DefaultVMSize = "Standard_A1"
|
||||
DefaultCloudEnvironmentName = "Public"
|
||||
DefaultImageVersion = "latest"
|
||||
DefaultUserName = "packer"
|
||||
DefaultPrivateVirtualNetworkWithPublicIp = false
|
||||
DefaultVMSize = "Standard_A1"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -78,19 +79,20 @@ type Config struct {
|
|||
manageImageLocation string
|
||||
|
||||
// Deployment
|
||||
AzureTags map[string]*string `mapstructure:"azure_tags"`
|
||||
ResourceGroupName string `mapstructure:"resource_group_name"`
|
||||
StorageAccount string `mapstructure:"storage_account"`
|
||||
TempComputeName string `mapstructure:"temp_compute_name"`
|
||||
TempResourceGroupName string `mapstructure:"temp_resource_group_name"`
|
||||
storageAccountBlobEndpoint string
|
||||
CloudEnvironmentName string `mapstructure:"cloud_environment_name"`
|
||||
cloudEnvironment *azure.Environment
|
||||
VirtualNetworkName string `mapstructure:"virtual_network_name"`
|
||||
VirtualNetworkSubnetName string `mapstructure:"virtual_network_subnet_name"`
|
||||
VirtualNetworkResourceGroupName string `mapstructure:"virtual_network_resource_group_name"`
|
||||
CustomDataFile string `mapstructure:"custom_data_file"`
|
||||
customData string
|
||||
AzureTags map[string]*string `mapstructure:"azure_tags"`
|
||||
ResourceGroupName string `mapstructure:"resource_group_name"`
|
||||
StorageAccount string `mapstructure:"storage_account"`
|
||||
TempComputeName string `mapstructure:"temp_compute_name"`
|
||||
TempResourceGroupName string `mapstructure:"temp_resource_group_name"`
|
||||
storageAccountBlobEndpoint string
|
||||
CloudEnvironmentName string `mapstructure:"cloud_environment_name"`
|
||||
cloudEnvironment *azure.Environment
|
||||
PrivateVirtualNetworkWithPublicIp bool `mapstructure:"private_virtual_network_with_public_ip"`
|
||||
VirtualNetworkName string `mapstructure:"virtual_network_name"`
|
||||
VirtualNetworkSubnetName string `mapstructure:"virtual_network_subnet_name"`
|
||||
VirtualNetworkResourceGroupName string `mapstructure:"virtual_network_resource_group_name"`
|
||||
CustomDataFile string `mapstructure:"custom_data_file"`
|
||||
customData string
|
||||
|
||||
// OS
|
||||
OSType string `mapstructure:"os_type"`
|
||||
|
|
|
@ -16,12 +16,14 @@ type EndpointType int
|
|||
const (
|
||||
PublicEndpoint EndpointType = iota
|
||||
PrivateEndpoint
|
||||
PublicEndpointInPrivateNetwork
|
||||
)
|
||||
|
||||
var (
|
||||
EndpointCommunicationText = map[EndpointType]string{
|
||||
PublicEndpoint: "PublicEndpoint",
|
||||
PrivateEndpoint: "PrivateEndpoint",
|
||||
PublicEndpoint: "PublicEndpoint",
|
||||
PrivateEndpoint: "PrivateEndpoint",
|
||||
PublicEndpointInPrivateNetwork: "PublicEndpointInPrivateNetwork",
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -46,6 +48,8 @@ func NewStepGetIPAddress(client *AzureClient, ui packer.Ui, endpoint EndpointTyp
|
|||
step.get = step.getPrivateIP
|
||||
case PublicEndpoint:
|
||||
step.get = step.getPublicIP
|
||||
case PublicEndpointInPrivateNetwork:
|
||||
step.get = step.getPublicIPInPrivateNetwork
|
||||
}
|
||||
|
||||
return step
|
||||
|
@ -70,6 +74,11 @@ func (s *StepGetIPAddress) getPublicIP(resourceGroupName string, ipAddressName s
|
|||
return *resp.IPAddress, nil
|
||||
}
|
||||
|
||||
func (s *StepGetIPAddress) getPublicIPInPrivateNetwork(resourceGroupName string, ipAddressName string, interfaceName string) (string, error) {
|
||||
s.getPrivateIP(resourceGroupName, ipAddressName, interfaceName)
|
||||
return s.getPublicIP(resourceGroupName, ipAddressName, interfaceName)
|
||||
}
|
||||
|
||||
func (s *StepGetIPAddress) Run(state multistep.StateBag) multistep.StepAction {
|
||||
s.say("Getting the VM's IP address ...")
|
||||
|
||||
|
|
|
@ -12,42 +12,50 @@ import (
|
|||
)
|
||||
|
||||
func TestStepGetIPAddressShouldFailIfGetFails(t *testing.T) {
|
||||
var testSubject = &StepGetIPAddress{
|
||||
get: func(string, string, string) (string, error) { return "", fmt.Errorf("!! Unit Test FAIL !!") },
|
||||
endpoint: PublicEndpoint,
|
||||
say: func(message string) {},
|
||||
error: func(e error) {},
|
||||
}
|
||||
endpoints := []EndpointType{PublicEndpoint, PublicEndpointInPrivateNetwork}
|
||||
|
||||
stateBag := createTestStateBagStepGetIPAddress()
|
||||
for _, endpoint := range endpoints {
|
||||
var testSubject = &StepGetIPAddress{
|
||||
get: func(string, string, string) (string, error) { return "", fmt.Errorf("!! Unit Test FAIL !!") },
|
||||
endpoint: endpoint,
|
||||
say: func(message string) {},
|
||||
error: func(e error) {},
|
||||
}
|
||||
|
||||
var result = testSubject.Run(stateBag)
|
||||
if result != multistep.ActionHalt {
|
||||
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
|
||||
}
|
||||
stateBag := createTestStateBagStepGetIPAddress()
|
||||
|
||||
if _, ok := stateBag.GetOk(constants.Error); ok == false {
|
||||
t.Fatalf("Expected the step to set stateBag['%s'], but it was not.", constants.Error)
|
||||
var result = testSubject.Run(stateBag)
|
||||
if result != multistep.ActionHalt {
|
||||
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
|
||||
}
|
||||
|
||||
if _, ok := stateBag.GetOk(constants.Error); ok == false {
|
||||
t.Fatalf("Expected the step to set stateBag['%s'], but it was not.", constants.Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepGetIPAddressShouldPassIfGetPasses(t *testing.T) {
|
||||
var testSubject = &StepGetIPAddress{
|
||||
get: func(string, string, string) (string, error) { return "", nil },
|
||||
endpoint: PublicEndpoint,
|
||||
say: func(message string) {},
|
||||
error: func(e error) {},
|
||||
}
|
||||
endpoints := []EndpointType{PublicEndpoint, PublicEndpointInPrivateNetwork}
|
||||
|
||||
stateBag := createTestStateBagStepGetIPAddress()
|
||||
for _, endpoint := range endpoints {
|
||||
var testSubject = &StepGetIPAddress{
|
||||
get: func(string, string, string) (string, error) { return "", nil },
|
||||
endpoint: endpoint,
|
||||
say: func(message string) {},
|
||||
error: func(e error) {},
|
||||
}
|
||||
|
||||
var result = testSubject.Run(stateBag)
|
||||
if result != multistep.ActionContinue {
|
||||
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
|
||||
}
|
||||
stateBag := createTestStateBagStepGetIPAddress()
|
||||
|
||||
if _, ok := stateBag.GetOk(constants.Error); ok == true {
|
||||
t.Fatalf("Expected the step to not set stateBag['%s'], but it was.", constants.Error)
|
||||
var result = testSubject.Run(stateBag)
|
||||
if result != multistep.ActionContinue {
|
||||
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
|
||||
}
|
||||
|
||||
if _, ok := stateBag.GetOk(constants.Error); ok == true {
|
||||
t.Fatalf("Expected the step to not set stateBag['%s'], but it was.", constants.Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,50 +63,53 @@ func TestStepGetIPAddressShouldTakeStepArgumentsFromStateBag(t *testing.T) {
|
|||
var actualResourceGroupName string
|
||||
var actualIPAddressName string
|
||||
var actualNicName string
|
||||
endpoints := []EndpointType{PublicEndpoint, PublicEndpointInPrivateNetwork}
|
||||
|
||||
var testSubject = &StepGetIPAddress{
|
||||
get: func(resourceGroupName string, ipAddressName string, nicName string) (string, error) {
|
||||
actualResourceGroupName = resourceGroupName
|
||||
actualIPAddressName = ipAddressName
|
||||
actualNicName = nicName
|
||||
for _, endpoint := range endpoints {
|
||||
var testSubject = &StepGetIPAddress{
|
||||
get: func(resourceGroupName string, ipAddressName string, nicName string) (string, error) {
|
||||
actualResourceGroupName = resourceGroupName
|
||||
actualIPAddressName = ipAddressName
|
||||
actualNicName = nicName
|
||||
|
||||
return "127.0.0.1", nil
|
||||
},
|
||||
endpoint: PublicEndpoint,
|
||||
say: func(message string) {},
|
||||
error: func(e error) {},
|
||||
}
|
||||
return "127.0.0.1", nil
|
||||
},
|
||||
endpoint: endpoint,
|
||||
say: func(message string) {},
|
||||
error: func(e error) {},
|
||||
}
|
||||
|
||||
stateBag := createTestStateBagStepGetIPAddress()
|
||||
var result = testSubject.Run(stateBag)
|
||||
stateBag := createTestStateBagStepGetIPAddress()
|
||||
var result = testSubject.Run(stateBag)
|
||||
|
||||
if result != multistep.ActionContinue {
|
||||
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
|
||||
}
|
||||
if result != multistep.ActionContinue {
|
||||
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
|
||||
}
|
||||
|
||||
var expectedResourceGroupName = stateBag.Get(constants.ArmResourceGroupName).(string)
|
||||
var expectedIPAddressName = stateBag.Get(constants.ArmPublicIPAddressName).(string)
|
||||
var expectedNicName = stateBag.Get(constants.ArmNicName).(string)
|
||||
var expectedResourceGroupName = stateBag.Get(constants.ArmResourceGroupName).(string)
|
||||
var expectedIPAddressName = stateBag.Get(constants.ArmPublicIPAddressName).(string)
|
||||
var expectedNicName = stateBag.Get(constants.ArmNicName).(string)
|
||||
|
||||
if actualIPAddressName != expectedIPAddressName {
|
||||
t.Fatal("Expected StepGetIPAddress to source 'constants.ArmIPAddressName' from the state bag, but it did not.")
|
||||
}
|
||||
if actualIPAddressName != expectedIPAddressName {
|
||||
t.Fatal("Expected StepGetIPAddress to source 'constants.ArmIPAddressName' from the state bag, but it did not.")
|
||||
}
|
||||
|
||||
if actualResourceGroupName != expectedResourceGroupName {
|
||||
t.Fatal("Expected StepGetIPAddress to source 'constants.ArmResourceGroupName' from the state bag, but it did not.")
|
||||
}
|
||||
if actualResourceGroupName != expectedResourceGroupName {
|
||||
t.Fatal("Expected StepGetIPAddress to source 'constants.ArmResourceGroupName' from the state bag, but it did not.")
|
||||
}
|
||||
|
||||
if actualNicName != expectedNicName {
|
||||
t.Fatalf("Expected StepGetIPAddress to source 'constants.ArmNetworkInterfaceName' from the state bag, but it did not.")
|
||||
}
|
||||
if actualNicName != expectedNicName {
|
||||
t.Fatalf("Expected StepGetIPAddress to source 'constants.ArmNetworkInterfaceName' from the state bag, but it did not.")
|
||||
}
|
||||
|
||||
expectedIPAddress, ok := stateBag.GetOk(constants.SSHHost)
|
||||
if !ok {
|
||||
t.Fatalf("Expected the state bag to have a value for '%s', but it did not.", constants.SSHHost)
|
||||
}
|
||||
expectedIPAddress, ok := stateBag.GetOk(constants.SSHHost)
|
||||
if !ok {
|
||||
t.Fatalf("Expected the state bag to have a value for '%s', but it did not.", constants.SSHHost)
|
||||
}
|
||||
|
||||
if expectedIPAddress != "127.0.0.1" {
|
||||
t.Fatalf("Expected the value of stateBag[%s] to be '127.0.0.1', but got '%s'.", constants.SSHHost, expectedIPAddress)
|
||||
if expectedIPAddress != "127.0.0.1" {
|
||||
t.Fatalf("Expected the value of stateBag[%s] to be '127.0.0.1', but got '%s'.", constants.SSHHost, expectedIPAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,12 @@ func GetVirtualMachineDeployment(config *Config) (*resources.Deployment, error)
|
|||
builder.SetCustomData(config.customData)
|
||||
}
|
||||
|
||||
if config.VirtualNetworkName != "" {
|
||||
if config.VirtualNetworkName != "" && DefaultPrivateVirtualNetworkWithPublicIp != config.PrivateVirtualNetworkWithPublicIp {
|
||||
builder.SetPrivateVirtualNetworWithPublicIp(
|
||||
config.VirtualNetworkResourceGroupName,
|
||||
config.VirtualNetworkName,
|
||||
config.VirtualNetworkSubnetName)
|
||||
} else if config.VirtualNetworkName != "" {
|
||||
builder.SetVirtualNetwork(
|
||||
config.VirtualNetworkResourceGroupName,
|
||||
config.VirtualNetworkName,
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
{
|
||||
"$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"adminPassword": {
|
||||
"type": "string"
|
||||
},
|
||||
"adminUsername": {
|
||||
"type": "string"
|
||||
},
|
||||
"dnsNameForPublicIP": {
|
||||
"type": "string"
|
||||
},
|
||||
"osDiskName": {
|
||||
"type": "string"
|
||||
},
|
||||
"storageAccountBlobEndpoint": {
|
||||
"type": "string"
|
||||
},
|
||||
"vmName": {
|
||||
"type": "string"
|
||||
},
|
||||
"vmSize": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"apiVersion": "[variables('publicIPAddressApiVersion')]",
|
||||
"location": "[variables('location')]",
|
||||
"name": "[variables('publicIPAddressName')]",
|
||||
"properties": {
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[parameters('dnsNameForPublicIP')]"
|
||||
},
|
||||
"publicIPAllocationMethod": "[variables('publicIPAddressType')]"
|
||||
},
|
||||
"type": "Microsoft.Network/publicIPAddresses"
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkInterfacesApiVersion')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]"
|
||||
],
|
||||
"location": "[variables('location')]",
|
||||
"name": "[variables('nicName')]",
|
||||
"properties": {
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
|
||||
},
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "Microsoft.Network/networkInterfaces"
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('apiVersion')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
|
||||
],
|
||||
"location": "[variables('location')]",
|
||||
"name": "[parameters('vmName')]",
|
||||
"properties": {
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[parameters('vmSize')]"
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"osProfile": {
|
||||
"adminPassword": "[parameters('adminPassword')]",
|
||||
"adminUsername": "[parameters('adminUsername')]",
|
||||
"computerName": "[parameters('vmName')]",
|
||||
"linuxConfiguration": {
|
||||
"ssh": {
|
||||
"publicKeys": [
|
||||
{
|
||||
"keyData": "",
|
||||
"path": "[variables('sshKeyPath')]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"offer": "--image-offer--",
|
||||
"publisher": "--image-publisher--",
|
||||
"sku": "--image-sku--",
|
||||
"version": "--version--"
|
||||
},
|
||||
"osDisk": {
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "fromImage",
|
||||
"name": "osdisk",
|
||||
"osType": "Linux"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "Microsoft.Compute/virtualMachines"
|
||||
}
|
||||
],
|
||||
"variables": {
|
||||
"addressPrefix": "10.0.0.0/16",
|
||||
"apiVersion": "2017-03-30",
|
||||
"location": "[resourceGroup().location]",
|
||||
"managedDiskApiVersion": "2017-03-30",
|
||||
"networkInterfacesApiVersion": "2017-04-01",
|
||||
"nicName": "packerNic",
|
||||
"publicIPAddressApiVersion": "2017-04-01",
|
||||
"publicIPAddressName": "packerPublicIP",
|
||||
"publicIPAddressType": "Dynamic",
|
||||
"sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]",
|
||||
"subnetAddressPrefix": "10.0.0.0/24",
|
||||
"subnetName": "--virtual_network_subnet_name--",
|
||||
"subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]",
|
||||
"virtualNetworkName": "--virtual_network_name--",
|
||||
"virtualNetworkResourceGroup": "--virtual_network_resource_group_name--",
|
||||
"virtualNetworksApiVersion": "2017-04-01",
|
||||
"vmStorageAccountContainerName": "images",
|
||||
"vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]"
|
||||
}
|
||||
}
|
|
@ -318,6 +318,43 @@ func TestVirtualMachineDeployment09(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Ensure the VM template is correct when building with PublicIp and connect to Private Network
|
||||
func TestVirtualMachineDeployment10(t *testing.T) {
|
||||
config := map[string]interface{}{
|
||||
"location": "ignore",
|
||||
"subscription_id": "ignore",
|
||||
"os_type": constants.Target_Linux,
|
||||
"communicator": "none",
|
||||
"image_publisher": "--image-publisher--",
|
||||
"image_offer": "--image-offer--",
|
||||
"image_sku": "--image-sku--",
|
||||
"image_version": "--version--",
|
||||
|
||||
"virtual_network_resource_group_name": "--virtual_network_resource_group_name--",
|
||||
"virtual_network_name": "--virtual_network_name--",
|
||||
"virtual_network_subnet_name": "--virtual_network_subnet_name--",
|
||||
"private_virtual_network_with_public_ip": true,
|
||||
|
||||
"managed_image_name": "ManagedImageName",
|
||||
"managed_image_resource_group_name": "ManagedImageResourceGroupName",
|
||||
}
|
||||
|
||||
c, _, err := newConfig(config, getPackerConfiguration())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deployment, err := GetVirtualMachineDeployment(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = approvaltests.VerifyJSONStruct(t, deployment.Properties.Template)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the link values are not set, and the concrete values are set.
|
||||
func TestKeyVaultDeployment00(t *testing.T) {
|
||||
c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
|
||||
|
|
|
@ -219,6 +219,24 @@ func (s *TemplateBuilder) SetVirtualNetwork(virtualNetworkResourceGroup, virtual
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *TemplateBuilder) SetPrivateVirtualNetworWithPublicIp(virtualNetworkResourceGroup, virtualNetworkName, subnetName string) error {
|
||||
s.setVariable("virtualNetworkResourceGroup", virtualNetworkResourceGroup)
|
||||
s.setVariable("virtualNetworkName", virtualNetworkName)
|
||||
s.setVariable("subnetName", subnetName)
|
||||
|
||||
s.deleteResourceByType(resourceVirtualNetworks)
|
||||
resource, err := s.getResourceByType(resourceNetworkInterfaces)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.deleteResourceDependency(resource, func(s string) bool {
|
||||
return strings.Contains(s, "Microsoft.Network/virtualNetworks")
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *TemplateBuilder) SetTags(tags *map[string]*string) error {
|
||||
if tags == nil || len(*tags) == 0 {
|
||||
return nil
|
||||
|
|
|
@ -131,9 +131,12 @@ When creating a managed image the following two options are required.
|
|||
- `tenant_id` (string) The account identifier with which your `client_id` and `subscription_id` are associated. If not
|
||||
specified, `tenant_id` will be looked up using `subscription_id`.
|
||||
|
||||
- `private_virtual_network_with_public_ip` (boolean) This value allows you to set a `virtual_network_name` and obtain
|
||||
a public IP. If this value is not set and `virtual_network_name` is defined Packer is only allowed to be executed
|
||||
from a host on the same subnet / virtual network.
|
||||
|
||||
- `virtual_network_name` (string) Use a pre-existing virtual network for the VM. This option enables private
|
||||
communication with the VM, no public IP address is **used** or **provisioned**. This value should only be set if
|
||||
Packer is executed from a host on the same subnet / virtual network.
|
||||
communication with the VM, no public IP address is **used** or **provisioned** (unless you set `private_virtual_network_with_public_ip`).
|
||||
|
||||
- `virtual_network_resource_group_name` (string) If virtual\_network\_name is set, this value **may** also be set. If
|
||||
virtual\_network\_name is set, and this value is not set the builder attempts to determine the resource group
|
||||
|
|
Loading…
Reference in New Issue