kitchen-azurerm 1.2.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +52 -11
- data/lib/kitchen/driver/azure_credentials.rb +30 -5
- data/lib/kitchen/driver/azurerm.rb +115 -37
- data/templates/internal.erb +31 -10
- data/templates/public.erb +4 -1
- metadata +4 -88
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20aa37ca60b29d9b0902d8741de326baa5fbe19fde0d37a9874dac2191b97b1f
|
4
|
+
data.tar.gz: f219f48b5b966faf7033fe0f78d8dd2f7638c77118c66f8c6bbae7c53e9f939c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ca9ed3f8eb461263d65f752299e46aded16a7e9b4fd3b73a06f66bacabd7ad5c7e566be1bfc299ed9abb0514ad386807b713bdf3740969883595a64a6afb7a0
|
7
|
+
data.tar.gz: 95988ebe08533122dc27d847cc817e799f07b72e4e13666170d6515bd9b9db5e37d6568722892f30388713ce9227653e04b72899c8d7f8d657fc83f078ca12b9
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# kitchen-azurerm
|
2
2
|
|
3
|
-
[](
|
3
|
+
[](https://badge.fury.io/rb/kitchen-azurerm)
|
4
|
+

|
4
5
|
|
5
6
|
**kitchen-azurerm** is a driver for the popular test harness [Test Kitchen](http://kitchen.ci) that allows Microsoft Azure resources to be provisioned before testing. This driver uses the new Microsoft Azure Resource Management REST API via the [azure-sdk-for-ruby](https://github.com/azure/azure-sdk-for-ruby).
|
6
7
|
|
@@ -259,7 +260,45 @@ suites:
|
|
259
260
|
attributes:
|
260
261
|
```
|
261
262
|
|
262
|
-
### .kitchen.yml example 5 - deploy VM to existing virtual network/subnet (use for ExpressRoute/VPN scenarios)
|
263
|
+
### .kitchen.yml example 5 - deploy VM to existing virtual network/subnet with a Standard SKU public IP (use for ExpressRoute/VPN scenarios)
|
264
|
+
|
265
|
+
The following example introduces the ```vnet_id``` and ```subnet_id``` properties under "driver" in the configuration file. This can be applied at the top level, or per platform.
|
266
|
+
You can use this capability to create the VM on an existing virtual network and subnet created in a different resource group.
|
267
|
+
|
268
|
+
This enables scenarios that require a Standard SKU public IP resource, for example when a NAT gateway is present on the target subnet.
|
269
|
+
|
270
|
+
|
271
|
+
```yaml
|
272
|
+
---
|
273
|
+
driver:
|
274
|
+
name: azurerm
|
275
|
+
subscription_id: 'your-azure-subscription-id-here'
|
276
|
+
location: 'West Europe'
|
277
|
+
machine_size: 'Standard_D1'
|
278
|
+
|
279
|
+
transport:
|
280
|
+
ssh_key: ~/.ssh/id_kitchen-azurerm
|
281
|
+
|
282
|
+
provisioner:
|
283
|
+
name: chef_zero
|
284
|
+
|
285
|
+
platforms:
|
286
|
+
- name: ubuntu-1404
|
287
|
+
driver:
|
288
|
+
image_urn: Canonical:UbuntuServer:14.04.4-LTS:latest
|
289
|
+
vnet_id: /subscriptions/b6e7eee9-YOUR-GUID-HERE-03ab624df016/resourceGroups/pendrica-infrastructure/providers/Microsoft.Network/virtualNetworks/pendrica-arm-vnet
|
290
|
+
subnet_id: subnet-10.1.0
|
291
|
+
public_ip: true
|
292
|
+
public_ip_sku: Standard
|
293
|
+
|
294
|
+
suites:
|
295
|
+
- name: default
|
296
|
+
run_list:
|
297
|
+
- recipe[kitchen-azurerm-demo::default]
|
298
|
+
attributes:
|
299
|
+
```
|
300
|
+
|
301
|
+
### .kitchen.yml example 6 - deploy VM to existing virtual network/subnet (use for ExpressRoute/VPN scenarios) with Private Managed Image
|
263
302
|
|
264
303
|
This example is the same as above, but uses a private managed image to provision the vm.
|
265
304
|
|
@@ -294,7 +333,7 @@ suites:
|
|
294
333
|
attributes:
|
295
334
|
```
|
296
335
|
|
297
|
-
### .kitchen.yml example
|
336
|
+
### .kitchen.yml example 7 - deploy VM to existing virtual network/subnet (use for ExpressRoute/VPN scenarios) with Private Classic OS Image
|
298
337
|
|
299
338
|
This example a classic Custom VM Image (aka a VHD file) is used. As the Image VHD must be in the same storage account then the disk of the instance, the os disk is created in an existing image account.
|
300
339
|
|
@@ -337,7 +376,7 @@ suites:
|
|
337
376
|
attributes:
|
338
377
|
```
|
339
378
|
|
340
|
-
### .kitchen.yml example
|
379
|
+
### .kitchen.yml example 8 - deploy VM to existing virtual network/subnet (use for ExpressRoute/VPN scenarios) with Private Classic OS Image and providing custom data and extra large os disk
|
341
380
|
|
342
381
|
This is the same as above, but uses custom data to customize the instance.
|
343
382
|
|
@@ -382,7 +421,7 @@ suites:
|
|
382
421
|
attributes:
|
383
422
|
```
|
384
423
|
|
385
|
-
### .kitchen.yml example
|
424
|
+
### .kitchen.yml example 9 - Windows 2016 VM with additional data disks
|
386
425
|
|
387
426
|
This example demonstrates how to add 3 additional Managed data disks to a Windows Server 2016 VM. Not supported with legacy (pre-managed disk) storage accounts.
|
388
427
|
|
@@ -419,7 +458,7 @@ suites:
|
|
419
458
|
attributes:
|
420
459
|
```
|
421
460
|
|
422
|
-
### .kitchen.yml example
|
461
|
+
### .kitchen.yml example 10 - "post-deployment" ARM template with MSI authentication
|
423
462
|
|
424
463
|
The following example introduces the ```post_deployment_template``` and ```post_deployment_parameters``` properties in the configuration file.
|
425
464
|
You can use this capability to execute an ARM template containing Azure resources to provision after the system under test is created.
|
@@ -505,7 +544,7 @@ Example postdeploy.json to enable MSI extention on VM:
|
|
505
544
|
}
|
506
545
|
```
|
507
546
|
|
508
|
-
### .kitchen.yml example
|
547
|
+
### .kitchen.yml example 11 - Enabling Managed Service Identities
|
509
548
|
|
510
549
|
This example demonstrates how to enable a System Assigned Identity and User Assigned Identities on a Kitchen VM.
|
511
550
|
Any combination of System and User assigned identities may be enabled, and multiple User Assigned Identities can be supplied.
|
@@ -541,7 +580,7 @@ suites:
|
|
541
580
|
attributes:
|
542
581
|
```
|
543
582
|
|
544
|
-
### .kitchen.yml example
|
583
|
+
### .kitchen.yml example 12 - deploy VM with key vault certificate
|
545
584
|
|
546
585
|
This following example introduces ```secret_url```, ```vault_name```, and ```vault_resource_group``` properties under "driver" in the configuration file. You can use this capability to create a VM with a specified key vault certificate.
|
547
586
|
|
@@ -670,11 +709,11 @@ info: vm image list command OK
|
|
670
709
|
|
671
710
|
* The ```azure_resource_group_prefix``` and ```azure_resource_group_suffix``` can be used to further disambiguate Azure resource group names created by the driver.
|
672
711
|
|
673
|
-
* The ```explicit_resource_group_name``` and ```destroy_explicit_resource_group``` (default: "true") parameters can be used in scenarios where you are provided a pre-created Resource Group. Example usage: ```explicit_resource_group_name: kitchen-<%= ENV["USERNAME"]
|
712
|
+
* The ```explicit_resource_group_name``` and ```destroy_explicit_resource_group``` (default: "true") parameters can be used in scenarios where you are provided a pre-created Resource Group. Example usage: ```explicit_resource_group_name: kitchen-<%= ENV["USERNAME"] %>```. The ```destroy_explicit_resource_group``` option can now be used after using the ```destroy_resource_group_contents``` option creates an empty resource group to destroy the resource group previously created.
|
674
713
|
|
675
|
-
* The ```destroy_resource_group_contents``` (default: "false") parameter can be used when you want to destroy the resources within a resource group without destroying the resource group itself. For example, the following configuration options used in combination would use an existing resource group (or create one if it doesn't exist) and will destroy the contents of the resource group in the ```kitchen destroy``` phase.
|
714
|
+
* The ```destroy_resource_group_contents``` (default: "false") parameter can be used when you want to destroy the resources within a resource group without destroying the resource group itself. For example, the following configuration options used in combination would use an existing resource group (or create one if it doesn't exist) and will destroy the contents of the resource group in the ```kitchen destroy``` phase. If you wish to destroy the empty resource group created after you empty the resource group with this flag you can now set the ```destroy_explicit_resource_group``` to "true" to destroy the empty resource group.
|
676
715
|
|
677
|
-
* The ```destroy_explicit_resource_group_tags``` (default: "true") parameter can be used when you want to remove tags associated with an explicit resource group. The default setting is set to
|
716
|
+
* The ```destroy_explicit_resource_group_tags``` (default: "true") parameter can be used when you want to remove tags associated with an explicit resource group. The default setting is set to "true" to remain consistent with previous behavior. This should be used in combination with an ```explicit_resource_group_name``` and will be honored during the ```kitchen destroy``` phase.
|
678
717
|
|
679
718
|
```yaml
|
680
719
|
---
|
@@ -688,6 +727,8 @@ driver:
|
|
688
727
|
|
689
728
|
* The ```secret_url```, ```vault_name```, and ```vault_resource_group``` parameters can be used to deploy VM with specified key vault certificate.
|
690
729
|
|
730
|
+
* The ```use_fqdn_hostname``` (default: "false") parameter can be used to determine how kitchen communicates with the Virtual Machine. When true, Kitchen will use the FQDN that is assigned to the Virtual Machine. When false, kitchen will use the public IP address of the machine. This may overcome issues with Corporate firewalls or VPNs blocking Public IP addresses.
|
731
|
+
|
691
732
|
## Enabling alternative WinRM configurations
|
692
733
|
|
693
734
|
* By default on Windows machines, a PowerShell script runs that enables WinRM over the SSL transport, for Basic, Negotiate and CredSSP connections. To supply your own PowerShell script (e.g. to enable HTTP), use the `winrm_powershell_script` parameter. Windows 2008 R2 example:
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require "inifile"
|
2
2
|
require "kitchen/logging"
|
3
|
+
autoload :MsRest, "ms_rest"
|
3
4
|
|
4
5
|
module Kitchen
|
5
6
|
module Driver
|
@@ -60,7 +61,7 @@ module Kitchen
|
|
60
61
|
if File.file?(config_path)
|
61
62
|
IniFile.load(config_path)
|
62
63
|
else
|
63
|
-
warn "#{config_path} was not found or not accessible.
|
64
|
+
warn "#{config_path} was not found or not accessible."
|
64
65
|
{}
|
65
66
|
end
|
66
67
|
end
|
@@ -71,7 +72,7 @@ module Kitchen
|
|
71
72
|
end
|
72
73
|
|
73
74
|
def tenant_id!
|
74
|
-
tenant_id ||
|
75
|
+
tenant_id || warn("(#{config_path}) does not contain tenant_id neither is the AZURE_TENANT_ID environment variable set.")
|
75
76
|
end
|
76
77
|
|
77
78
|
def tenant_id
|
@@ -86,13 +87,37 @@ module Kitchen
|
|
86
87
|
ENV["AZURE_CLIENT_SECRET"] || credentials_property("client_secret")
|
87
88
|
end
|
88
89
|
|
90
|
+
# Retrieve a token based upon the preferred authentication method.
|
91
|
+
#
|
92
|
+
# @return [::MsRest::TokenProvider] A new token provider object.
|
89
93
|
def token_provider
|
90
|
-
|
94
|
+
# Login with a credentials file or setting the environment variables
|
95
|
+
#
|
96
|
+
# Typically used with a service principal.
|
97
|
+
#
|
98
|
+
# SPN with client_id, client_secret and tenant_id
|
99
|
+
if client_id && client_secret && tenant_id
|
91
100
|
::MsRestAzure::ApplicationTokenProvider.new(tenant_id, client_id, client_secret, ad_settings)
|
92
|
-
|
101
|
+
# Login with a Managed Service Identity.
|
102
|
+
#
|
103
|
+
# Typically used with a Managed Service Identity when you have a particular object registered in a tenant.
|
104
|
+
#
|
105
|
+
# MSI with client_id and tenant_id (aka User Assigned Identity).
|
106
|
+
elsif client_id && tenant_id
|
93
107
|
::MsRestAzure::MSITokenProvider.new(50342, ad_settings, { client_id: client_id })
|
94
|
-
|
108
|
+
# Default approach to inheriting existing object permissions (application or device this code is running on).
|
109
|
+
#
|
110
|
+
# Typically used when you want to inherit the permissions of the system you're running on that are in a tenant.
|
111
|
+
#
|
112
|
+
# MSI with just tenant_id (aka System Assigned Identity).
|
113
|
+
elsif tenant_id
|
95
114
|
::MsRestAzure::MSITokenProvider.new(50342, ad_settings)
|
115
|
+
# Login using the Azure CLI
|
116
|
+
#
|
117
|
+
# Typically used when you want to rely upon `az login` as your preferred authentication method.
|
118
|
+
else
|
119
|
+
warn("Using tenant id set through `az login`.")
|
120
|
+
::MsRestAzure::AzureCliTokenProvider.new(ad_settings)
|
96
121
|
end
|
97
122
|
end
|
98
123
|
|
@@ -1,21 +1,27 @@
|
|
1
1
|
require "kitchen"
|
2
|
+
|
3
|
+
autoload :MsRestAzure, "ms_rest_azure"
|
2
4
|
require_relative "azure_credentials"
|
3
5
|
require "securerandom" unless defined?(SecureRandom)
|
4
|
-
|
5
|
-
|
6
|
+
module Azure
|
7
|
+
autoload :Resources, "azure_mgmt_resources"
|
8
|
+
autoload :Network, "azure_mgmt_network"
|
9
|
+
end
|
6
10
|
require "base64" unless defined?(Base64)
|
7
|
-
|
11
|
+
autoload :SSHKey, "sshkey"
|
8
12
|
require "fileutils" unless defined?(FileUtils)
|
9
13
|
require "erb" unless defined?(Erb)
|
10
14
|
require "ostruct" unless defined?(OpenStruct)
|
11
15
|
require "json" unless defined?(JSON)
|
12
|
-
|
16
|
+
autoload :Faraday, "faraday"
|
13
17
|
|
14
18
|
module Kitchen
|
15
19
|
module Driver
|
16
20
|
#
|
17
21
|
# Azurerm
|
22
|
+
# Create a new resource group object and set the location and tags attributes then return it.
|
18
23
|
#
|
24
|
+
# @return [::Azure::Resources::Profiles::Latest::Mgmt::Models::ResourceGroup] A new resource group object.
|
19
25
|
class Azurerm < Kitchen::Driver::Base
|
20
26
|
attr_accessor :resource_management_client
|
21
27
|
attr_accessor :network_management_client
|
@@ -202,10 +208,18 @@ module Kitchen
|
|
202
208
|
ENV["AZURE_SUBSCRIPTION_ID"]
|
203
209
|
end
|
204
210
|
|
211
|
+
default_config(:public_ip_sku) do |_config|
|
212
|
+
"Basic"
|
213
|
+
end
|
214
|
+
|
205
215
|
default_config(:azure_api_retries) do |_config|
|
206
216
|
5
|
207
217
|
end
|
208
218
|
|
219
|
+
default_config(:use_fqdn_hostname) do |_config|
|
220
|
+
false
|
221
|
+
end
|
222
|
+
|
209
223
|
def create(state)
|
210
224
|
state = validate_state(state)
|
211
225
|
deployment_parameters = {
|
@@ -214,7 +228,7 @@ module Kitchen
|
|
214
228
|
storageAccountType: config[:storage_account_type],
|
215
229
|
bootDiagnosticsEnabled: config[:boot_diagnostics_enabled],
|
216
230
|
newStorageAccountName: "storage#{state[:uuid]}",
|
217
|
-
adminUsername:
|
231
|
+
adminUsername: config[:username],
|
218
232
|
dnsNameForPublicIP: "kitchen-#{state[:uuid]}",
|
219
233
|
vmName: state[:vm_name],
|
220
234
|
systemAssignedIdentity: config[:system_assigned_identity],
|
@@ -225,7 +239,13 @@ module Kitchen
|
|
225
239
|
}
|
226
240
|
|
227
241
|
if instance.transport[:ssh_key].nil?
|
228
|
-
deployment_parameters[
|
242
|
+
deployment_parameters[:adminPassword] = config[:password]
|
243
|
+
end
|
244
|
+
|
245
|
+
deployment_parameters[:publicIPSKU] = config[:public_ip_sku]
|
246
|
+
|
247
|
+
if config[:public_ip_sku] == "Standard"
|
248
|
+
deployment_parameters[:publicIPAddressType] = "Static"
|
229
249
|
end
|
230
250
|
|
231
251
|
if config[:subscription_id].to_s == ""
|
@@ -301,6 +321,9 @@ module Kitchen
|
|
301
321
|
info "Creating deployment: #{deployment_name}"
|
302
322
|
create_deployment_async(state[:azure_resource_group_name], deployment_name, deployment(deployment_parameters)).value!
|
303
323
|
follow_deployment_until_end_state(state[:azure_resource_group_name], deployment_name)
|
324
|
+
state[:username] = deployment_parameters[:adminUsername] unless existing_state_value?(state, :username)
|
325
|
+
state[:password] = deployment_parameters[:adminPassword] unless existing_state_value?(state, :password) && instance.transport[:ssh_key].nil?
|
326
|
+
|
304
327
|
if File.file?(config[:post_deployment_template])
|
305
328
|
post_deployment_name = "post-deploy-#{state[:uuid]}"
|
306
329
|
info "Creating deployment: #{post_deployment_name}"
|
@@ -326,6 +349,10 @@ module Kitchen
|
|
326
349
|
result = get_public_ip(state[:azure_resource_group_name], "publicip")
|
327
350
|
info "IP Address is: #{result.ip_address} [#{result.dns_settings.fqdn}]"
|
328
351
|
state[:hostname] = result.ip_address
|
352
|
+
if config[:use_fqdn_hostname]
|
353
|
+
info "Using FQDN to communicate instead of IP"
|
354
|
+
state[:hostname] = result.dns_settings.fqdn
|
355
|
+
end
|
329
356
|
else
|
330
357
|
# Retrieve the internal IP from the resource group:
|
331
358
|
result = get_network_interface(state[:azure_resource_group_name], vmnic.to_s)
|
@@ -334,15 +361,24 @@ module Kitchen
|
|
334
361
|
end
|
335
362
|
end
|
336
363
|
|
364
|
+
# Return a True of False if the state is already stored for a particular property.
|
365
|
+
#
|
366
|
+
# @param [Hash] Hash of existing state values.
|
367
|
+
# @param [String] A property to check
|
368
|
+
# @return [Boolean]
|
337
369
|
def existing_state_value?(state, property)
|
338
370
|
state.key?(property) && !state[property].nil?
|
339
371
|
end
|
340
372
|
|
373
|
+
# Leverage existing state values or bring state into existence from a configuration file.
|
374
|
+
#
|
375
|
+
# @param [Hash] Existing Hash of state values.
|
376
|
+
# @return [Hash] Updated Hash of state values.
|
341
377
|
def validate_state(state = {})
|
342
378
|
state[:uuid] = SecureRandom.hex(8) unless existing_state_value?(state, :uuid)
|
343
379
|
state[:server_id] = "vm#{state[:uuid]}" unless existing_state_value?(state, :server_id)
|
344
380
|
state[:azure_resource_group_name] = azure_resource_group_name unless existing_state_value?(state, :azure_resource_group_name)
|
345
|
-
%i{subscription_id
|
381
|
+
%i{subscription_id vm_name azure_environment use_managed_disks}.each do |config_element|
|
346
382
|
state[config_element] = config[config_element] unless existing_state_value?(state, config_element)
|
347
383
|
end
|
348
384
|
state.delete(:password) unless instance.transport[:ssh_key].nil?
|
@@ -523,11 +559,38 @@ module Kitchen
|
|
523
559
|
end
|
524
560
|
|
525
561
|
def destroy(state)
|
526
|
-
|
562
|
+
# TODO: We have some not so fun state issues we need to clean up
|
563
|
+
state[:azure_environment] = config[:azure_environment] unless state[:azure_environment]
|
564
|
+
state[:subscription_id] = config[:subscription_id] unless state[:subscription_id]
|
527
565
|
|
566
|
+
# Setup our authentication components for the SDK
|
528
567
|
options = Kitchen::Driver::AzureCredentials.new(subscription_id: state[:subscription_id],
|
529
|
-
|
568
|
+
environment: state[:azure_environment]).azure_options
|
530
569
|
@resource_management_client = ::Azure::Resources::Profiles::Latest::Mgmt::Client.new(options)
|
570
|
+
|
571
|
+
# If we don't have any instances, let's check to see if the user wants to delete a resource group and if so let's delete!
|
572
|
+
if state[:server_id].nil? && state[:azure_resource_group_name].nil? && !config[:explicit_resource_group_name].nil? && config[:destroy_explicit_resource_group]
|
573
|
+
if resource_group_exists?(config[:explicit_resource_group_name])
|
574
|
+
info "This instance doesn't exist but you asked to delete the resource group."
|
575
|
+
begin
|
576
|
+
info "Destroying Resource Group: #{config[:explicit_resource_group_name]}"
|
577
|
+
delete_resource_group_async(config[:explicit_resource_group_name])
|
578
|
+
info "Destroy operation accepted and will continue in the background."
|
579
|
+
return
|
580
|
+
rescue ::MsRestAzure::AzureOperationError => operation_error
|
581
|
+
error operation_error.body
|
582
|
+
raise operation_error
|
583
|
+
end
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
# Our working environment
|
588
|
+
info "Azure environment: #{state[:azure_environment]}"
|
589
|
+
|
590
|
+
# Skip if we don't have any instances
|
591
|
+
return if state[:server_id].nil?
|
592
|
+
|
593
|
+
# Destroy resource group contents
|
531
594
|
if config[:destroy_resource_group_contents] == true
|
532
595
|
info "Destroying individual resources within the Resource Group."
|
533
596
|
empty_deployment_name = "empty-deploy-#{state[:uuid]}"
|
@@ -536,32 +599,20 @@ module Kitchen
|
|
536
599
|
create_deployment_async(state[:azure_resource_group_name], empty_deployment_name, empty_deployment).value!
|
537
600
|
follow_deployment_until_end_state(state[:azure_resource_group_name], empty_deployment_name)
|
538
601
|
|
539
|
-
#
|
540
|
-
|
541
|
-
|
542
|
-
#
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
rescue ::MsRestAzure::AzureOperationError => operation_error
|
547
|
-
error operation_error.body
|
548
|
-
raise operation_error
|
549
|
-
end
|
550
|
-
end
|
551
|
-
|
552
|
-
# Corner case where we want to use kitchen to remove the tags
|
553
|
-
if config[:destroy_explicit_resource_group_tags] == true
|
554
|
-
warn 'The "destroy_explicit_resource_group_tags" setting value is set to "true". The tags on the resource group will be removed.'
|
555
|
-
# NOTE: We are using the internal wrapper function create_resource_group() which wraps the API
|
556
|
-
# method of create_or_update().
|
602
|
+
# NOTE: We are using the internal wrapper function create_resource_group() which wraps the API
|
603
|
+
# method of create_or_update()
|
604
|
+
begin
|
605
|
+
# Maintain tags on the resource group
|
606
|
+
create_resource_group(state[:azure_resource_group_name], get_resource_group) unless config[:destroy_explicit_resource_group_tags] == true
|
607
|
+
warn 'The "destroy_explicit_resource_group_tags" setting value is set to "false". The tags on the resource group will NOT be removed.' unless config[:destroy_explicit_resource_group_tags] == true
|
608
|
+
# Corner case where we want to use kitchen to remove the tags
|
557
609
|
resource_group = get_resource_group
|
558
610
|
resource_group.tags = {}
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
end
|
611
|
+
create_resource_group(state[:azure_resource_group_name], resource_group) unless config[:destroy_explicit_resource_group_tags] == false
|
612
|
+
warn 'The "destroy_explicit_resource_group_tags" setting value is set to "true". The tags on the resource group will be removed.' unless config[:destroy_explicit_resource_group_tags] == false
|
613
|
+
rescue ::MsRestAzure::AzureOperationError => operation_error
|
614
|
+
error operation_error.body
|
615
|
+
raise operation_error
|
565
616
|
end
|
566
617
|
|
567
618
|
rescue ::MsRestAzure::AzureOperationError => operation_error
|
@@ -569,20 +620,27 @@ module Kitchen
|
|
569
620
|
raise operation_error
|
570
621
|
end
|
571
622
|
end
|
623
|
+
|
624
|
+
# Do not remove the explicitly named resource group
|
572
625
|
if config[:destroy_explicit_resource_group] == false && !config[:explicit_resource_group_name].nil?
|
573
626
|
warn 'The "destroy_explicit_resource_group" setting value is set to "false". The resource group will not be deleted.'
|
574
627
|
warn 'Remember to manually destroy resources, or set "destroy_resource_group_contents: true" to save costs!' unless config[:destroy_resource_group_contents] == true
|
575
|
-
return
|
628
|
+
return state
|
576
629
|
end
|
577
|
-
|
630
|
+
|
631
|
+
# Destroy the world
|
578
632
|
begin
|
579
633
|
info "Destroying Resource Group: #{state[:azure_resource_group_name]}"
|
580
634
|
delete_resource_group_async(state[:azure_resource_group_name])
|
581
635
|
info "Destroy operation accepted and will continue in the background."
|
636
|
+
# Remove resource group name from driver state
|
637
|
+
state.delete(:azure_resource_group_name)
|
582
638
|
rescue ::MsRestAzure::AzureOperationError => operation_error
|
583
639
|
error operation_error.body
|
584
640
|
raise operation_error
|
585
641
|
end
|
642
|
+
|
643
|
+
# Clear state of components
|
586
644
|
state.delete(:server_id)
|
587
645
|
state.delete(:hostname)
|
588
646
|
state.delete(:username)
|
@@ -679,10 +737,10 @@ module Kitchen
|
|
679
737
|
|
680
738
|
def virtual_machine_deployment_template
|
681
739
|
if config[:vnet_id] == ""
|
682
|
-
virtual_machine_deployment_template_file("public.erb", vm_tags: vm_tag_string(config[:vm_tags]), use_managed_disks: config[:use_managed_disks], image_url: config[:image_url], existing_storage_account_blob_url: config[:existing_storage_account_blob_url], image_id: config[:image_id], existing_storage_account_container: config[:existing_storage_account_container], custom_data: config[:custom_data], os_disk_size_gb: config[:os_disk_size_gb], data_disks_for_vm_json: data_disks_for_vm_json, use_ephemeral_osdisk: config[:use_ephemeral_osdisk], ssh_key: instance.transport[:ssh_key], plan_json: plan_json)
|
740
|
+
virtual_machine_deployment_template_file("public.erb", vm_tags: vm_tag_string(config[:vm_tags]), use_managed_disks: config[:use_managed_disks], image_url: config[:image_url], storage_account_type: config[:storage_account_type], existing_storage_account_blob_url: config[:existing_storage_account_blob_url], image_id: config[:image_id], existing_storage_account_container: config[:existing_storage_account_container], custom_data: config[:custom_data], os_disk_size_gb: config[:os_disk_size_gb], data_disks_for_vm_json: data_disks_for_vm_json, use_ephemeral_osdisk: config[:use_ephemeral_osdisk], ssh_key: instance.transport[:ssh_key], plan_json: plan_json)
|
683
741
|
else
|
684
742
|
info "Using custom vnet: #{config[:vnet_id]}"
|
685
|
-
virtual_machine_deployment_template_file("internal.erb", vnet_id: config[:vnet_id], subnet_id: config[:subnet_id], public_ip: config[:public_ip], vm_tags: vm_tag_string(config[:vm_tags]), use_managed_disks: config[:use_managed_disks], image_url: config[:image_url], existing_storage_account_blob_url: config[:existing_storage_account_blob_url], image_id: config[:image_id], existing_storage_account_container: config[:existing_storage_account_container], custom_data: config[:custom_data], os_disk_size_gb: config[:os_disk_size_gb], data_disks_for_vm_json: data_disks_for_vm_json, use_ephemeral_osdisk: config[:use_ephemeral_osdisk], ssh_key: instance.transport[:ssh_key], plan_json: plan_json)
|
743
|
+
virtual_machine_deployment_template_file("internal.erb", vnet_id: config[:vnet_id], subnet_id: config[:subnet_id], public_ip: config[:public_ip], vm_tags: vm_tag_string(config[:vm_tags]), use_managed_disks: config[:use_managed_disks], image_url: config[:image_url], storage_account_type: config[:storage_account_type], existing_storage_account_blob_url: config[:existing_storage_account_blob_url], image_id: config[:image_id], existing_storage_account_container: config[:existing_storage_account_container], custom_data: config[:custom_data], os_disk_size_gb: config[:os_disk_size_gb], data_disks_for_vm_json: data_disks_for_vm_json, use_ephemeral_osdisk: config[:use_ephemeral_osdisk], ssh_key: instance.transport[:ssh_key], public_ip_sku: config[:public_ip_sku], plan_json: plan_json)
|
686
744
|
end
|
687
745
|
end
|
688
746
|
|
@@ -746,6 +804,26 @@ module Kitchen
|
|
746
804
|
resource_group
|
747
805
|
end
|
748
806
|
|
807
|
+
# Checks whether a resource group exists.
|
808
|
+
#
|
809
|
+
# @param resource_group_name [String] The name of the resource group to check.
|
810
|
+
# The name is case insensitive.
|
811
|
+
#
|
812
|
+
# @return [Boolean] operation results.
|
813
|
+
#
|
814
|
+
def resource_group_exists?(resource_group_name)
|
815
|
+
retries = config[:azure_api_retries]
|
816
|
+
begin
|
817
|
+
resource_management_client.resource_groups.check_existence(resource_group_name)
|
818
|
+
rescue Faraday::TimeoutError, Faraday::ClientError => exception
|
819
|
+
send_exception_message(exception, "while checking if resource group '#{resource_group_name}' exists. #{retries} retries left.")
|
820
|
+
raise if retries == 0
|
821
|
+
|
822
|
+
retries -= 1
|
823
|
+
retry
|
824
|
+
end
|
825
|
+
end
|
826
|
+
|
749
827
|
def create_resource_group(resource_group_name, resource_group)
|
750
828
|
retries = config[:azure_api_retries]
|
751
829
|
begin
|
data/templates/internal.erb
CHANGED
@@ -40,6 +40,22 @@
|
|
40
40
|
"description": "Unique DNS Name for the Public IP used to access the Virtual Machine."
|
41
41
|
}
|
42
42
|
},
|
43
|
+
<%- if public_ip_sku %>
|
44
|
+
"publicIPSKU": {
|
45
|
+
"type": "string",
|
46
|
+
"defaultValue": "Standard",
|
47
|
+
"metadata": {
|
48
|
+
"description": "SKU name for the Public IP used to access the Virtual Machine."
|
49
|
+
}
|
50
|
+
},
|
51
|
+
"publicIPAddressType": {
|
52
|
+
"type": "string",
|
53
|
+
"defaultValue": "Dynamic",
|
54
|
+
"metadata": {
|
55
|
+
"description": "SKU name for the Public IP used to access the Virtual Machine."
|
56
|
+
}
|
57
|
+
},
|
58
|
+
<%- end %>
|
43
59
|
<%- unless os_disk_size_gb.to_s.empty? -%>
|
44
60
|
"osDiskSizeGb": {
|
45
61
|
"type": "int",
|
@@ -165,7 +181,7 @@
|
|
165
181
|
},
|
166
182
|
"storageAccountType": {
|
167
183
|
"type": "string",
|
168
|
-
"defaultValue": "
|
184
|
+
"defaultValue": "<%= storage_account_type %>",
|
169
185
|
"metadata": {
|
170
186
|
"description": "The type of storage to use (e.g. Standard_LRS or Premium_LRS)."
|
171
187
|
}
|
@@ -201,7 +217,6 @@
|
|
201
217
|
"subnetPrefix": "10.0.0.0/24",
|
202
218
|
"storageAccountType": "[parameters('storageAccountType')]",
|
203
219
|
"publicIPAddressName": "publicip",
|
204
|
-
"publicIPAddressType": "Dynamic",
|
205
220
|
"vmStorageAccountContainerName": "vhds",
|
206
221
|
"vmName": "[parameters('vmName')]",
|
207
222
|
"vmSize": "[parameters('vmSize')]",
|
@@ -242,12 +257,15 @@
|
|
242
257
|
<%- end -%>
|
243
258
|
<%- if public_ip -%>
|
244
259
|
{
|
245
|
-
"apiVersion": "
|
260
|
+
"apiVersion": "2017-08-01",
|
246
261
|
"type": "Microsoft.Network/publicIPAddresses",
|
247
262
|
"name": "[variables('publicIPAddressName')]",
|
248
263
|
"location": "[variables('location')]",
|
264
|
+
"sku": {
|
265
|
+
"name": "[parameters('publicIPSKU')]"
|
266
|
+
},
|
249
267
|
"properties": {
|
250
|
-
"publicIPAllocationMethod": "[
|
268
|
+
"publicIPAllocationMethod": "[parameters('publicIPAddressType')]",
|
251
269
|
"dnsSettings": {
|
252
270
|
"domainNameLabel": "[parameters('dnsNameForPublicIP')]"
|
253
271
|
}
|
@@ -343,12 +361,12 @@
|
|
343
361
|
},
|
344
362
|
<%- end -%>
|
345
363
|
<%- if use_ephemeral_osdisk -%>
|
346
|
-
"osDisk": {
|
347
|
-
"diffDiskSettings": {
|
348
|
-
"option": "Local"
|
349
|
-
},
|
350
|
-
"caching": "ReadOnly",
|
351
|
-
"createOption": "FromImage"
|
364
|
+
"osDisk": {
|
365
|
+
"diffDiskSettings": {
|
366
|
+
"option": "Local"
|
367
|
+
},
|
368
|
+
"caching": "ReadOnly",
|
369
|
+
"createOption": "FromImage"
|
352
370
|
}
|
353
371
|
<%- elsif use_managed_disks -%>
|
354
372
|
"osDisk": {
|
@@ -356,6 +374,9 @@
|
|
356
374
|
<%- unless os_disk_size_gb.to_s.empty? -%>
|
357
375
|
"diskSizeGB": "[parameters('osDiskSizeGB')]",
|
358
376
|
<%- end -%>
|
377
|
+
"managedDisk": {
|
378
|
+
"storageAccountType": "[parameters('storageAccountType')]"
|
379
|
+
},
|
359
380
|
"createOption": "FromImage"
|
360
381
|
}
|
361
382
|
<%- else -%>
|
data/templates/public.erb
CHANGED
@@ -165,7 +165,7 @@
|
|
165
165
|
},
|
166
166
|
"storageAccountType": {
|
167
167
|
"type": "string",
|
168
|
-
"defaultValue": "
|
168
|
+
"defaultValue": "<%= storage_account_type %>",
|
169
169
|
"metadata": {
|
170
170
|
"description": "The type of storage to use (e.g. Standard_LRS or Premium_LRS)."
|
171
171
|
}
|
@@ -375,6 +375,9 @@
|
|
375
375
|
<%- unless os_disk_size_gb.to_s.empty? -%>
|
376
376
|
"diskSizeGB": "[parameters('osDiskSizeGB')]",
|
377
377
|
<%- end -%>
|
378
|
+
"managedDisk": {
|
379
|
+
"storageAccountType": "[parameters('storageAccountType')]"
|
380
|
+
},
|
378
381
|
"createOption": "FromImage"
|
379
382
|
}
|
380
383
|
<%- else -%>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kitchen-azurerm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2
|
4
|
+
version: 1.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stuart Preston
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: azure_mgmt_network
|
@@ -110,90 +110,6 @@ dependencies:
|
|
110
110
|
- - "<"
|
111
111
|
- !ruby/object:Gem::Version
|
112
112
|
version: '3.0'
|
113
|
-
- !ruby/object:Gem::Dependency
|
114
|
-
name: rake
|
115
|
-
requirement: !ruby/object:Gem::Requirement
|
116
|
-
requirements:
|
117
|
-
- - ">="
|
118
|
-
- !ruby/object:Gem::Version
|
119
|
-
version: '11.0'
|
120
|
-
type: :development
|
121
|
-
prerelease: false
|
122
|
-
version_requirements: !ruby/object:Gem::Requirement
|
123
|
-
requirements:
|
124
|
-
- - ">="
|
125
|
-
- !ruby/object:Gem::Version
|
126
|
-
version: '11.0'
|
127
|
-
- !ruby/object:Gem::Dependency
|
128
|
-
name: chefstyle
|
129
|
-
requirement: !ruby/object:Gem::Requirement
|
130
|
-
requirements:
|
131
|
-
- - '='
|
132
|
-
- !ruby/object:Gem::Version
|
133
|
-
version: 1.2.1
|
134
|
-
type: :development
|
135
|
-
prerelease: false
|
136
|
-
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
requirements:
|
138
|
-
- - '='
|
139
|
-
- !ruby/object:Gem::Version
|
140
|
-
version: 1.2.1
|
141
|
-
- !ruby/object:Gem::Dependency
|
142
|
-
name: rspec
|
143
|
-
requirement: !ruby/object:Gem::Requirement
|
144
|
-
requirements:
|
145
|
-
- - "~>"
|
146
|
-
- !ruby/object:Gem::Version
|
147
|
-
version: '3.5'
|
148
|
-
type: :development
|
149
|
-
prerelease: false
|
150
|
-
version_requirements: !ruby/object:Gem::Requirement
|
151
|
-
requirements:
|
152
|
-
- - "~>"
|
153
|
-
- !ruby/object:Gem::Version
|
154
|
-
version: '3.5'
|
155
|
-
- !ruby/object:Gem::Dependency
|
156
|
-
name: rspec-mocks
|
157
|
-
requirement: !ruby/object:Gem::Requirement
|
158
|
-
requirements:
|
159
|
-
- - "~>"
|
160
|
-
- !ruby/object:Gem::Version
|
161
|
-
version: '3.5'
|
162
|
-
type: :development
|
163
|
-
prerelease: false
|
164
|
-
version_requirements: !ruby/object:Gem::Requirement
|
165
|
-
requirements:
|
166
|
-
- - "~>"
|
167
|
-
- !ruby/object:Gem::Version
|
168
|
-
version: '3.5'
|
169
|
-
- !ruby/object:Gem::Dependency
|
170
|
-
name: rspec-expectations
|
171
|
-
requirement: !ruby/object:Gem::Requirement
|
172
|
-
requirements:
|
173
|
-
- - "~>"
|
174
|
-
- !ruby/object:Gem::Version
|
175
|
-
version: '3.5'
|
176
|
-
type: :development
|
177
|
-
prerelease: false
|
178
|
-
version_requirements: !ruby/object:Gem::Requirement
|
179
|
-
requirements:
|
180
|
-
- - "~>"
|
181
|
-
- !ruby/object:Gem::Version
|
182
|
-
version: '3.5'
|
183
|
-
- !ruby/object:Gem::Dependency
|
184
|
-
name: rspec-its
|
185
|
-
requirement: !ruby/object:Gem::Requirement
|
186
|
-
requirements:
|
187
|
-
- - "~>"
|
188
|
-
- !ruby/object:Gem::Version
|
189
|
-
version: 1.3.0
|
190
|
-
type: :development
|
191
|
-
prerelease: false
|
192
|
-
version_requirements: !ruby/object:Gem::Requirement
|
193
|
-
requirements:
|
194
|
-
- - "~>"
|
195
|
-
- !ruby/object:Gem::Version
|
196
|
-
version: 1.3.0
|
197
113
|
description: Test Kitchen driver for the Microsoft Azure Resource Manager (ARM) API
|
198
114
|
email:
|
199
115
|
- stuart@chef.io
|
@@ -220,14 +136,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
220
136
|
requirements:
|
221
137
|
- - ">="
|
222
138
|
- !ruby/object:Gem::Version
|
223
|
-
version: '
|
139
|
+
version: '2.5'
|
224
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
225
141
|
requirements:
|
226
142
|
- - ">="
|
227
143
|
- !ruby/object:Gem::Version
|
228
144
|
version: '0'
|
229
145
|
requirements: []
|
230
|
-
rubygems_version: 3.1.
|
146
|
+
rubygems_version: 3.1.4
|
231
147
|
signing_key:
|
232
148
|
specification_version: 4
|
233
149
|
summary: Test Kitchen driver for Azure Resource Manager.
|