terraspace_plugin_azurerm 0.0.0 → 0.1.0
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/CHANGELOG.md +3 -4
- data/Gemfile +1 -2
- data/lib/templates/hcl/module/main.tf +6 -5
- data/lib/templates/hcl/module/variables.tf +6 -0
- data/lib/templates/hcl/project/config/terraform/backend.tf +1 -1
- data/lib/templates/hcl/stack/main.tf +7 -5
- data/lib/templates/hcl/stack/variables.tf +5 -1
- data/lib/templates/ruby/project/config/terraform/backend.rb +1 -1
- data/lib/terraspace_plugin_azurerm.rb +5 -0
- data/lib/terraspace_plugin_azurerm/interfaces/backend/base.rb +4 -0
- data/lib/terraspace_plugin_azurerm/interfaces/backend/resource_group_creator.rb +2 -2
- data/lib/terraspace_plugin_azurerm/interfaces/backend/storage_account.rb +4 -4
- data/lib/terraspace_plugin_azurerm/interfaces/backend/storage_container.rb +2 -2
- data/lib/terraspace_plugin_azurerm/interfaces/config.rb +2 -0
- data/lib/terraspace_plugin_azurerm/interfaces/expander.rb +1 -5
- data/lib/terraspace_plugin_azurerm/interfaces/summary.rb +122 -0
- data/lib/terraspace_plugin_azurerm/version.rb +1 -1
- data/terraspace_plugin_azurerm.gemspec +2 -1
- metadata +31 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 96bcbc4372bc972b9aac47dea9ae90c9b666934a3d7b8a0384d96a793bd0c85e
|
|
4
|
+
data.tar.gz: d6f539c1ada933e1227e53e9e4a133ddc21425800e59c6eda3c59f88d0b1a76e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4d6f485d4b65dc2dbf12ca58215422390593ee78a78c1d41dc69e06322fb959722246a77d3845457bdaaee3c6093e0d2a3fdd6c1726591bfe1b15b46adfdf896
|
|
7
|
+
data.tar.gz: a37fb5daa3b964c2c2c743ec3636302412e6207c5d3cb4563ad482f13f869477362aa1403357c61096a0fac925b5305c16c56456de471ff64fe6420c5e576adb
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
resource "azurerm_storage_account" "this" {
|
|
2
|
-
name
|
|
3
|
-
resource_group_name
|
|
4
|
-
location
|
|
5
|
-
account_tier
|
|
6
|
-
account_replication_type
|
|
2
|
+
name = var.name
|
|
3
|
+
resource_group_name = var.resource_group_name
|
|
4
|
+
location = var.location
|
|
5
|
+
account_tier = "Standard"
|
|
6
|
+
account_replication_type = "GRS"
|
|
7
|
+
enable_https_traffic_only = var.enable_https_traffic_only
|
|
7
8
|
}
|
|
@@ -5,6 +5,6 @@ terraform {
|
|
|
5
5
|
resource_group_name = "<%= backend_expand('azurerm', 'terraform-resources-:LOCATION') %>"
|
|
6
6
|
storage_account_name = "<%= backend_expand('azurerm', 'ts:SUBSCRIPTION_HASH:LOCATION:ENV') %>"
|
|
7
7
|
container_name = "terraform-state"
|
|
8
|
-
key = "<%= backend_expand('azurerm', ':LOCATION/:ENV/:BUILD_DIR') %>"
|
|
8
|
+
key = "<%= backend_expand('azurerm', ':LOCATION/:ENV/:BUILD_DIR.tfstate') %>"
|
|
9
9
|
}
|
|
10
10
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
resource "random_pet" "this" {
|
|
2
|
-
length =
|
|
2
|
+
length = 2 # using 2, since default separator is '-', also account name can only be 24 characters, and lowercase letters
|
|
3
|
+
separator = ""# a blank string separator because azure storage accounts dont support - characters
|
|
3
4
|
}
|
|
4
5
|
|
|
5
6
|
resource "azurerm_resource_group" "this" {
|
|
@@ -8,8 +9,9 @@ resource "azurerm_resource_group" "this" {
|
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
module "storage_account" {
|
|
11
|
-
source
|
|
12
|
-
name
|
|
13
|
-
resource_group_name
|
|
14
|
-
location
|
|
12
|
+
source = "../../modules/example"
|
|
13
|
+
name = "sa${random_pet.this.id}"
|
|
14
|
+
resource_group_name = azurerm_resource_group.this.name
|
|
15
|
+
location = azurerm_resource_group.this.location
|
|
16
|
+
enable_https_traffic_only = var.enable_https_traffic_only
|
|
15
17
|
}
|
|
@@ -5,7 +5,7 @@ class TerraspacePluginAzurerm::Interfaces::Backend
|
|
|
5
5
|
|
|
6
6
|
def create
|
|
7
7
|
if exist?
|
|
8
|
-
|
|
8
|
+
logger.debug "Resource Group #{@resource_group_name} already exists"
|
|
9
9
|
else
|
|
10
10
|
create_resource_group
|
|
11
11
|
end
|
|
@@ -16,7 +16,7 @@ class TerraspacePluginAzurerm::Interfaces::Backend
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def create_resource_group
|
|
19
|
-
|
|
19
|
+
logger.info "Creating Resource Group #{@resource_group_name}..."
|
|
20
20
|
resource_group = ResourceGroup.new
|
|
21
21
|
resource_group.name = @resource_group_name
|
|
22
22
|
resource_group.location = config.location || AzureInfo.location
|
|
@@ -5,7 +5,7 @@ class TerraspacePluginAzurerm::Interfaces::Backend
|
|
|
5
5
|
|
|
6
6
|
def create
|
|
7
7
|
if exist?
|
|
8
|
-
|
|
8
|
+
logger.debug "Storage Account #{@storage_account_name} already exists"
|
|
9
9
|
else
|
|
10
10
|
create_storage_account
|
|
11
11
|
end
|
|
@@ -24,8 +24,8 @@ class TerraspacePluginAzurerm::Interfaces::Backend
|
|
|
24
24
|
|
|
25
25
|
case result.reason
|
|
26
26
|
when "AccountNameInvalid"
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
logger.error "ERROR: Failed to create storage account, reason: #{result.reason}".color(:red)
|
|
28
|
+
logger.error "Provided storage_account_name: #{@storage_account_name}"
|
|
29
29
|
exit 1
|
|
30
30
|
else
|
|
31
31
|
false
|
|
@@ -33,7 +33,7 @@ class TerraspacePluginAzurerm::Interfaces::Backend
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def create_storage_account
|
|
36
|
-
|
|
36
|
+
logger.info "Creating Storage Account #{@storage_account_name}..."
|
|
37
37
|
storage_accounts.create(@resource_group_name, @storage_account_name, storage_account_params)
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -5,7 +5,7 @@ class TerraspacePluginAzurerm::Interfaces::Backend
|
|
|
5
5
|
|
|
6
6
|
def create
|
|
7
7
|
if exist?
|
|
8
|
-
|
|
8
|
+
logger.debug "Storage Container #{@container_name} already exists"
|
|
9
9
|
else
|
|
10
10
|
create_storage_container
|
|
11
11
|
end
|
|
@@ -21,7 +21,7 @@ class TerraspacePluginAzurerm::Interfaces::Backend
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def create_storage_container
|
|
24
|
-
|
|
24
|
+
logger.info "Creating Storage Container #{@container_name}..."
|
|
25
25
|
blob_container = BlobContainer.new
|
|
26
26
|
blob_container.name = @container_name
|
|
27
27
|
blob_containers.create(@resource_group_name, @storage_account_name, @container_name, blob_container)
|
|
@@ -3,6 +3,8 @@ module TerraspacePluginAzurerm::Interfaces
|
|
|
3
3
|
include Terraspace::Plugin::Config::Interface
|
|
4
4
|
include Singleton # Config class must be a Singleton with the class .instance method
|
|
5
5
|
|
|
6
|
+
# interface method
|
|
7
|
+
# load_project_config: config/plugins/azurerm.rb
|
|
6
8
|
def provider
|
|
7
9
|
"azurerm"
|
|
8
10
|
end
|
|
@@ -27,10 +27,6 @@ module TerraspacePluginAzurerm::Interfaces
|
|
|
27
27
|
def subscription_hash
|
|
28
28
|
Digest::SHA1.hexdigest(subscription)[0..3]
|
|
29
29
|
end
|
|
30
|
-
|
|
31
|
-
# NOTE: be careful to not change this! or else state path will change
|
|
32
|
-
def namespace_hash
|
|
33
|
-
Digest::SHA1.hexdigest(subscription)[0..3]
|
|
34
|
-
end
|
|
30
|
+
alias_method :namespace_hash, :subscription_hash
|
|
35
31
|
end
|
|
36
32
|
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
require 'azure/storage/blob'
|
|
2
|
+
|
|
3
|
+
module TerraspacePluginAzurerm::Interfaces
|
|
4
|
+
class Summary
|
|
5
|
+
include Terraspace::Plugin::Summary::Interface
|
|
6
|
+
include TerraspacePluginAzurerm::Clients::Storage # for mgmt storage_accounts to get keys only, the azure/storage/blob gem is used to get the objects
|
|
7
|
+
extend Memoist
|
|
8
|
+
|
|
9
|
+
# interface method
|
|
10
|
+
def bucket_field
|
|
11
|
+
'storage_account_name'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# interface method
|
|
15
|
+
def download
|
|
16
|
+
marker = nil
|
|
17
|
+
loop do
|
|
18
|
+
blobs = list_blobs(container_name, marker: marker)
|
|
19
|
+
blobs.each do |blob|
|
|
20
|
+
blob, content = blob_client.get_blob(container_name, blob.name)
|
|
21
|
+
local_path = "#{@dest}/#{blob.name}"
|
|
22
|
+
FileUtils.mkdir_p(File.dirname(local_path))
|
|
23
|
+
File.open(local_path, 'wb') {|f| f.write(content)}
|
|
24
|
+
end
|
|
25
|
+
marker = blobs.continuation_token
|
|
26
|
+
break unless marker && !marker.empty?
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# interface method
|
|
31
|
+
def delete_empty_statefile(key)
|
|
32
|
+
delete_blob(key)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def delete_blob(key)
|
|
36
|
+
blob_client.delete_blob(container_name, key)
|
|
37
|
+
rescue Azure::Core::Http::HTTPError => e
|
|
38
|
+
case e.message
|
|
39
|
+
when /BlobNotFound/
|
|
40
|
+
logger.info "WARN: #{e.class}: #{e.message}"
|
|
41
|
+
logger.info "Blob item does not exist: #{key}"
|
|
42
|
+
when /ContainerNotFound/
|
|
43
|
+
logger.info "WARN: #{e.class}: #{e.message}"
|
|
44
|
+
logger.info "Container not found: #{container_name}"
|
|
45
|
+
else
|
|
46
|
+
raise
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def container_name
|
|
51
|
+
@info['container_name']
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Friendly error handling for user
|
|
55
|
+
def list_blobs(container_name, marker:)
|
|
56
|
+
blob_client.list_blobs(container_name, marker: marker)
|
|
57
|
+
rescue Azure::Core::Http::HTTPError => e
|
|
58
|
+
if e.message.include?("AuthenticationFailed")
|
|
59
|
+
logger.error "e.class #{e.class}: #{e.message}"
|
|
60
|
+
logger.error "Unable to authenticate to download the statefiles from the storage account.".color(:red)
|
|
61
|
+
if ENV['AZURE_STORAGE_ACCESS_KEY']
|
|
62
|
+
logger.error <<~EOL
|
|
63
|
+
It looks like you have the AZURE_STORAGE_ACCESS_KEY environment variable set.
|
|
64
|
+
It may be the incorrect key for the storage account: #{@info['storage_account_name']}
|
|
65
|
+
Try unsetting it:
|
|
66
|
+
|
|
67
|
+
unset AZURE_STORAGE_ACCESS_KEY
|
|
68
|
+
|
|
69
|
+
When the environment variable is not set, this library will try to fetch the key for you.
|
|
70
|
+
Or you can try setting the correct key.
|
|
71
|
+
EOL
|
|
72
|
+
else
|
|
73
|
+
logger.error <<~EOL
|
|
74
|
+
The fetched storage access key did not seem to authenticate successfully.
|
|
75
|
+
Try setting the AZURE_STORAGE_ACCESS_KEY environment variable with access to the storage account: #{@info['storage_account_name']}
|
|
76
|
+
EOL
|
|
77
|
+
end
|
|
78
|
+
# Common message
|
|
79
|
+
logger.error <<~EOL
|
|
80
|
+
One way to get the key is with:
|
|
81
|
+
|
|
82
|
+
az storage account keys list --account-name #{@info['storage_account_name']} --resource-group #{@info['resource_group_name']}
|
|
83
|
+
|
|
84
|
+
Then you can set it:
|
|
85
|
+
|
|
86
|
+
export AZURE_STORAGE_ACCESS_KEY=[replace-with-value]
|
|
87
|
+
EOL
|
|
88
|
+
exit 1
|
|
89
|
+
else
|
|
90
|
+
raise
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
def blob_client
|
|
96
|
+
# Note per docs: https://github.com/azure/azure-storage-ruby/tree/master/blob#via-environment-variables
|
|
97
|
+
#
|
|
98
|
+
# export AZURE_STORAGE_ACCOUNT = <your azure storage account name>
|
|
99
|
+
# export AZURE_STORAGE_ACCESS_KEY = <your azure storage access key>
|
|
100
|
+
#
|
|
101
|
+
# Works if zero args are passed to the create method. But set the storage_account_name arg, so we must also set
|
|
102
|
+
# the storage_access_key explicitly. We'll follow the same env variable convention.
|
|
103
|
+
#
|
|
104
|
+
Azure::Storage::Blob::BlobService.create(
|
|
105
|
+
storage_account_name: @info['storage_account_name'],
|
|
106
|
+
storage_access_key: storage_access_key
|
|
107
|
+
)
|
|
108
|
+
end
|
|
109
|
+
memoize :blob_client
|
|
110
|
+
|
|
111
|
+
def storage_access_key
|
|
112
|
+
ENV['AZURE_STORAGE_ACCESS_KEY'] || fetch_storage_access_key
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def fetch_storage_access_key
|
|
116
|
+
# result is a StorageAccountListKeysResult with a keys reader method
|
|
117
|
+
# then .value contains the key
|
|
118
|
+
result = storage_accounts.list_keys(@info['resource_group_name'], @info['storage_account_name'])
|
|
119
|
+
result.keys.first.value
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -22,7 +22,8 @@ Gem::Specification.new do |spec|
|
|
|
22
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
23
23
|
spec.require_paths = ["lib"]
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
spec.add_dependency "azure-storage-blob"
|
|
26
|
+
spec.add_dependency "azure_info"
|
|
26
27
|
spec.add_dependency "azure_mgmt_resources"
|
|
27
28
|
spec.add_dependency "azure_mgmt_storage"
|
|
28
29
|
spec.add_dependency "memoist"
|
metadata
CHANGED
|
@@ -1,15 +1,43 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: terraspace_plugin_azurerm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tung Nguyen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-07-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: azure-storage-blob
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: azure_info
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
13
41
|
- !ruby/object:Gem::Dependency
|
|
14
42
|
name: azure_mgmt_resources
|
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -123,6 +151,7 @@ files:
|
|
|
123
151
|
- lib/terraspace_plugin_azurerm/interfaces/config.rb
|
|
124
152
|
- lib/terraspace_plugin_azurerm/interfaces/expander.rb
|
|
125
153
|
- lib/terraspace_plugin_azurerm/interfaces/layer.rb
|
|
154
|
+
- lib/terraspace_plugin_azurerm/interfaces/summary.rb
|
|
126
155
|
- lib/terraspace_plugin_azurerm/version.rb
|
|
127
156
|
- terraspace_plugin_azurerm.gemspec
|
|
128
157
|
homepage: https://github.com/boltops-tools/terraspace_plugin_azurerm
|