Skip to content

Commit

Permalink
Merge pull request #296 from chef-cft/russellseymour/azure-wombat-images
Browse files Browse the repository at this point in the history
Added support to selectively delete items in the RG
  • Loading branch information
Bakh Inamov authored Feb 15, 2017
2 parents 2f730da + b3d9562 commit 7bac491
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 71 deletions.
2 changes: 1 addition & 1 deletion generator_files/packer/workstation.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
],
"type": "windows-shell",
"inline": [
"C:\\Windows\\System32\\sysprep\\sysprep.exe /quiet /generalize /shutdown"
"C:\\Windows\\System32\\sysprep\\sysprep.exe /quiet /generalize /oobe /shutdown"
]
}
]
Expand Down
2 changes: 1 addition & 1 deletion generator_files/templates/arm.json.erb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@

"sa": {
"name": "[parameters('storageAccountName')]",
"container": "vhds",
"container": "[concat('vhds-', variables('unique'))]",
"type": "Standard_LRS"
},

Expand Down
32 changes: 32 additions & 0 deletions generator_files/templates/arm.tidy.json.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.1",
"parameters": {
"storageAccountName": {
"type": "string",
"metadata": {
"description": "Name of the storage account that should be used to store the machine disks"
},
"defaultValue": "<%= @storage_account %>"
}
},
"variables": {
"sa": {
"name": "[parameters('storageAccountName')]",
"type": "Standard_LRS"
},
"location": "[resourceGroup().location]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('sa').name]",
"apiVersion": "2015-06-15",
"location": "[variables('location')]",
"properties": {
"accountType": "[variables('sa').type]"
}
}
],
"outputs": {}
}
9 changes: 9 additions & 0 deletions lib/wombat/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,15 @@ def self.parse(args)
opts.on("-c CLOUD", "--cloud CLOUD", "Select cloud") do |opt|
options.cloud = opt
end

opts.on("--all", "Remove entire Resource Group which includes images (Azure Only)") do |opt|
options.remove_all = opt
end

opts.on("--async", "Delete resources asynchronously when not removing all, e.g. do not block command line. (Azure Only)") do |opt|
options.azure_async = opt
end

},
argv: stack_argv_proc
},
Expand Down
81 changes: 71 additions & 10 deletions lib/wombat/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,17 @@ def update_template(cloud)
warn('No lock - skipping template creation')
else

@demo = lock['name']
@version = lock['version']
@ttl = lock['ttl']

# Determine the region/location/zone for the specific cloud
case cloud
when 'aws'
region = lock['aws']['region']
template_file = "cfn.json.erb"
template_files = {
"cfn.json.erb": "#{conf['stack_dir']}/#{@demo}.json"
}
@chef_server_ami = lock['amis'][region]['chef-server']
@automate_ami = lock['amis'][region]['automate']
@compliance_ami = lock['amis'][region]['compliance']
Expand All @@ -219,7 +225,10 @@ def update_template(cloud)
when 'azure'
region = lock['azure']['location']
@storage_account = lock['azure']['storage_account']
template_file = "arm.json.erb"
template_files = {
"arm.json.erb": "#{conf['stack_dir']}/#{@demo}.json",
"arm.tidy.json.erb": "#{conf['stack_dir']}/#{@demo}.tidy.json"
}
@chef_server_uri = lock['amis'][region]['chef-server']
@automate_uri = lock['amis'][region]['automate']
@compliance_uri = lock['amis'][region]['compliance']
Expand Down Expand Up @@ -249,14 +258,13 @@ def update_template(cloud)
end
end

@demo = lock['name']
@version = lock['version']
@ttl = lock['ttl']

rendered_cfn = ERB.new(File.read("#{conf['template_dir']}/#{template_file}"), nil, '-').result(binding)
Dir.mkdir(conf['stack_dir'], 0755) unless File.exist?(conf['stack_dir'])
File.open("#{conf['stack_dir']}/#{@demo}.json", 'w') { |file| file.puts rendered_cfn }
banner("Generated: #{conf['stack_dir']}/#{@demo}.json")
# Iterate around each of the template files that have been defined and render it
template_files.each do |template_file, destination|
rendered_cfn = ERB.new(File.read("#{conf['template_dir']}/#{template_file}"), nil, '-').result(binding)
Dir.mkdir(conf['stack_dir'], 0755) unless File.exist?(conf['stack_dir'])
File.open("#{destination}", 'w') { |file| file.puts rendered_cfn }
banner("Generated: #{destination}")
end
end
end

Expand All @@ -268,5 +276,58 @@ def is_valid_json?(file)
false
end
end

# Track the progress of the deployment in Azure
#
# ===== Attributes
#
# * +rg_name+ - Name of the resource group being deployed to
# * +deployment_name+ - Name of the deployment that is currently being processed
def follow_azure_deployment(rg_name, deployment_name)

end_provisioning_states = 'Canceled,Failed,Deleted,Succeeded'
end_provisioning_state_reached = false

until end_provisioning_state_reached
list_outstanding_deployment_operations(rg_name, deployment_name)
sleep 10
deployment_provisioning_state = deployment_state(rg_name, deployment_name)
end_provisioning_state_reached = end_provisioning_states.split(',').include?(deployment_provisioning_state)
end
info format("Resource Template deployment reached end state of %s", deployment_provisioning_state)
end

# Get a list of the outstanding deployment operations
#
# ===== Attributes
#
# * +rg_name+ - Name of the resource group being deployed to
# * +deployment_name+ - Name of the deployment that is currently being processed
def list_outstanding_deployment_operations(rg_name, deployment_name)
end_operation_states = 'Failed,Succeeded'
deployment_operations = resource_management_client.deployment_operations.list(rg_name, deployment_name)
deployment_operations.each do |val|
resource_provisioning_state = val.properties.provisioning_state
unless val.properties.target_resource.nil?
resource_name = val.properties.target_resource.resource_name
resource_type = val.properties.target_resource.resource_type
end
end_operation_state_reached = end_operation_states.split(',').include?(resource_provisioning_state)
unless end_operation_state_reached
info format("resource %s '%s' provisioning status is %s", resource_type, resource_name, resource_provisioning_state)
end
end
end

# Get the state of the specified deployment
#
# ===== Attributes
#
# * +rg_name+ - Name of the resource group being deployed to
# * +deployment_name+ - Name of the deployment that is currently being processed
def deployment_state(rg_name, deployment_name)
deployments = resource_management_client.deployments.get(rg_name, deployment_name)
deployments.properties.provisioning_state
end
end
end
54 changes: 49 additions & 5 deletions lib/wombat/delete.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ class DeleteRunner
include Wombat::Common

attr_reader :stack, :cloud
attr_accessor :resource_management_client

def initialize(opts)
@stack = opts.stack
@cloud = opts.cloud.nil? ? "aws" : opts.cloud
@remove_all = opts.remove_all.nil? ? false : opts.remove_all
@azure_async = opts.azure_async.nil? ? false : opts.azure_async
end

def start
Expand Down Expand Up @@ -44,14 +47,55 @@ def cfn_delete_stack(stack)
azure_conn = MsRest::TokenCredentials.new(token_provider)

# Create a resource client so that the resource group can be deleted
resource_management_client = Azure::ARM::Resources::ResourceManagementClient.new(azure_conn)
resource_management_client.subscription_id = subscription_id
@resource_management_client = Azure::ARM::Resources::ResourceManagementClient.new(azure_conn)
@resource_management_client.subscription_id = subscription_id

banner(format("Deleting resource group: %s", stack))
# Only delete the entire resource group if it has been explicitly set
if (@remove_all)
banner(format("Deleting resource group: %s", stack))

resource_management_client.resource_groups.begin_delete(stack)
resource_management_client.resource_groups.begin_delete(stack)

info "Destroy operation accepted and will continue in the background."
info "Destroy operation accepted and will continue in the background."
else

banner(format("Tidying resource group: %s", stack))

# Create new deployment using the tidy template so that the storage account is left
# behind but all the other resources are removed
template_file = File.read("#{conf['stack_dir']}/#{stack}.tidy.json")

# determine the name of the deployment
deployment_name = format('deploy-tidy-%s', Time.now().to_i)

# Create the deployment definition
deployment = Azure::ARM::Resources::Models::Deployment.new
deployment.properties = Azure::ARM::Resources::Models::DeploymentProperties.new
deployment.properties.mode = Azure::ARM::Resources::Models::DeploymentMode::Complete
deployment.properties.template = JSON.parse(template_file)

# Perform the deployment to the named resource group
begin
resource_management_client.deployments.begin_create_or_update_async(stack, deployment_name, deployment).value!
rescue MsRestAzure::AzureOperationError => operation_error
rest_error = operation_error.body['error']
deployment_active = rest_error['code'] == 'DeploymentActive'
if deployment_active
info format("Deployment for resource group '%s' is ongoing", stack)
else
warn rest_error
raise operation_error
end
end

# Monitor the deployment
if @azure_async
info "Deployment operation accepted. Use the Azure Portal to check progress"
else
info "Removing Automate resources"
follow_azure_deployment(stack, deployment_name)
end
end
end
end
end
Expand Down
52 changes: 0 additions & 52 deletions lib/wombat/deploy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,59 +102,7 @@ def create_stack(stack)
end
end

# Track the progress of the deployment in Azure
#
# ===== Attributes
#
# * +rg_name+ - Name of the resource group being deployed to
# * +deployment_name+ - Name of the deployment that is currently being processed
def follow_azure_deployment(rg_name, deployment_name)

end_provisioning_states = 'Canceled,Failed,Deleted,Succeeded'
end_provisioning_state_reached = false

until end_provisioning_state_reached
list_outstanding_deployment_operations(rg_name, deployment_name)
info ""
sleep 10
deployment_provisioning_state = deployment_state(rg_name, deployment_name)
end_provisioning_state_reached = end_provisioning_states.split(',').include?(deployment_provisioning_state)
end
info format("Resource Template deployment reached end state of %s", deployment_provisioning_state)
end

# Get a list of the outstanding deployment operations
#
# ===== Attributes
#
# * +rg_name+ - Name of the resource group being deployed to
# * +deployment_name+ - Name of the deployment that is currently being processed
def list_outstanding_deployment_operations(rg_name, deployment_name)
end_operation_states = 'Failed,Succeeded'
deployment_operations = resource_management_client.deployment_operations.list(rg_name, deployment_name)
deployment_operations.each do |val|
resource_provisioning_state = val.properties.provisioning_state
unless val.properties.target_resource.nil?
resource_name = val.properties.target_resource.resource_name
resource_type = val.properties.target_resource.resource_type
end
end_operation_state_reached = end_operation_states.split(',').include?(resource_provisioning_state)
unless end_operation_state_reached
info format("resource %s '%s' provisioning status is %s", resource_type, resource_name, resource_provisioning_state)
end
end
end

# Get the state of the specified deployment
#
# ===== Attributes
#
# * +rg_name+ - Name of the resource group being deployed to
# * +deployment_name+ - Name of the deployment that is currently being processed
def deployment_state(rg_name, deployment_name)
deployments = resource_management_client.deployments.get(rg_name, deployment_name)
deployments.properties.provisioning_state
end

end
end
4 changes: 2 additions & 2 deletions wombat-cli.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ Gem::Specification.new do |gem|
gem.add_dependency 'net-ssh', '~> 3.2'
gem.add_dependency 'parallel', '~> 1.9'
gem.add_dependency 'aws-sdk', '~> 2.5'
gem.add_dependency 'azure_mgmt_resources', '~> 0.8'
gem.add_dependency 'azure_mgmt_storage', '~> 0.8'
gem.add_dependency 'azure_mgmt_resources', '~> 0.9'
gem.add_dependency 'azure_mgmt_storage', '~> 0.9'
end

0 comments on commit 7bac491

Please sign in to comment.