Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for azurerm_virtual_machine #87

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ import (
var keyNames []string
var nameParser *regexp.Regexp

// Azure has separate resources for the VM and the NIC that holds the IP address
// Everytime we encounter an azurerm_network_interface we will store the IP address
// in this map with the NIC id as the key. Then when we are looking for the VM address
// we'll check if the VM's (primary) NIC exists in the map.
var azureNICPrimaryIps map[string]string
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like this global mutable map of things. Could we eliminate by either doing the lookup lazily (i.e. re-scanning the entire struct when looking up IPs for Azure VMs), or make it a member of some other object (probably state)?


// Azure related keys
const azureNicResourceKey string = "azurerm_network_interface"
const azureNicIpKey string = "private_ip_address"
const azureIdKey string = "id"
const azureVMResourceKey string = "azurerm_virtual_machine"
const azureVMPrimaryNicKey string = "primary_network_interface_id"
const azureVMSecondaryNicKey string = "network_interface_ids.0"

func init() {
keyNames = []string{
"ipv4_address", // DO and SoftLayer
Expand All @@ -34,6 +48,8 @@ func init() {
"primaryip", // Joyent Triton
}

azureNICPrimaryIps = map[string]string{}

// type.name.0
nameParser = regexp.MustCompile(`^(\w+)\.([\w\-]+)(?:\.(\d+))?$`)
}
Expand Down Expand Up @@ -76,6 +92,11 @@ func NewResource(keyName string, state resourceState) (*Resource, error) {
}
}

// Special case for azurerm_network_interface
if m[1] == azureNicResourceKey {
AzureStoreNicIp(state)
}

return &Resource{
State: state,
keyName: keyName,
Expand Down Expand Up @@ -146,6 +167,15 @@ func (r Resource) Tags() map[string]string {
t[kk] = vv
}
}
case "azurerm_virtual_machine":
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be using azureVMResourceKey here?

for k, v := range r.Attributes() {
parts := strings.SplitN(k, ".", 2)
if len(parts) == 2 && parts[0] == "tags" && parts[1] != "%" {
kk := strings.ToLower(parts[1])
vv := strings.ToLower(v)
t[kk] = vv
}
}
}
return t
}
Expand All @@ -163,6 +193,13 @@ func (r Resource) NameWithCounter() string {

// Address returns the IP address of this resource.
func (r Resource) Address() string {

switch r.resourceType {
case azureNicResourceKey, azureVMResourceKey:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Pretty weird to be using a switch for this; there's only a single case.
  • This part should go below the TF_KEY_NAME check, otherwise Azure resources won't be able to use that feature. Put it inside the else, or refactor the method if you'd like.
  • Since AzureAddress() returns an empty string for non-azure resources, we could just always call it and return early if it returns a non-empty string.

// Special case for azurerm_network_interface, azurerm_virtual_machine
return r.AzureAddress()
}

if keyName := os.Getenv("TF_KEY_NAME"); keyName != "" {
if ip := r.State.Primary.Attributes[keyName]; ip != "" {
return ip
Expand All @@ -177,3 +214,30 @@ func (r Resource) Address() string {

return ""
}

func (r Resource) AzureAddress() string {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a docstring to this method.

// We'll actually only handle azurerm_virtual_machine and ignore
// azurerm_network_interface as that is not a real VM resource
if r.resourceType == azureVMResourceKey {
nicId := r.State.Primary.Attributes[azureVMPrimaryNicKey]
if nicId == "" {
nicId = r.State.Primary.Attributes[azureVMSecondaryNicKey]
}
if nicId != "" {
ip := azureNICPrimaryIps[nicId]
return ip
}
}

return ""
}

func AzureStoreNicIp(state resourceState) {
// Store the first ipAddress (primary) to the map with nic id
ip := state.Primary.Attributes[azureNicIpKey]
nicId := state.Primary.Attributes[azureIdKey]

if ip != "" && nicId != "" {
azureNICPrimaryIps[nicId] = ip
}
}