Merge pull request #899 from hashicorp/770-azure-provider
Add Azure provider
This commit is contained in:
commit
8749d0090a
|
@ -0,0 +1,12 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/builtin/providers/azure"
|
||||||
|
"github.com/hashicorp/terraform/plugin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
plugin.Serve(&plugin.ServeOpts{
|
||||||
|
ProviderFunc: azure.Provider,
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
package main
|
|
@ -0,0 +1,30 @@
|
||||||
|
package azure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
azure "github.com/MSOpenTech/azure-sdk-for-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
PublishSettingsFile string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) loadAndValidate() error {
|
||||||
|
if _, err := os.Stat(c.PublishSettingsFile); os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"Error loading Azure Publish Settings file '%s': %s",
|
||||||
|
c.PublishSettingsFile,
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[INFO] Importing Azure Publish Settings file...")
|
||||||
|
err := azure.ImportPublishSettingsFile(c.PublishSettingsFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package azure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Provider() terraform.ResourceProvider {
|
||||||
|
return &schema.Provider{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"publish_settings_file": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
DefaultFunc: envDefaultFunc("AZURE_PUBLISH_SETTINGS_FILE"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
|
"azure_virtual_machine": resourceVirtualMachine(),
|
||||||
|
},
|
||||||
|
|
||||||
|
ConfigureFunc: providerConfigure,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func envDefaultFunc(k string) schema.SchemaDefaultFunc {
|
||||||
|
return func() (interface{}, error) {
|
||||||
|
if v := os.Getenv(k); v != "" {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
||||||
|
config := Config{
|
||||||
|
PublishSettingsFile: d.Get("publish_settings_file").(string),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := config.loadAndValidate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &config, nil
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package azure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testAccProviders map[string]terraform.ResourceProvider
|
||||||
|
var testAccProvider *schema.Provider
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
testAccProvider = Provider().(*schema.Provider)
|
||||||
|
testAccProviders = map[string]terraform.ResourceProvider{
|
||||||
|
"azure": testAccProvider,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProvider(t *testing.T) {
|
||||||
|
if err := Provider().(*schema.Provider).InternalValidate(); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProvider_impl(t *testing.T) {
|
||||||
|
var _ terraform.ResourceProvider = Provider()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccPreCheck(t *testing.T) {
|
||||||
|
if v := os.Getenv("AZURE_PUBLISH_SETTINGS_FILE"); v == "" {
|
||||||
|
t.Fatal("AZURE_PUBLISH_SETTINGS_FILE must be set for acceptance tests")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,241 @@
|
||||||
|
package azure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/hashcode"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/MSOpenTech/azure-sdk-for-go/clients/vmClient"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceVirtualMachine() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceVirtualMachineCreate,
|
||||||
|
Read: resourceVirtualMachineRead,
|
||||||
|
Delete: resourceVirtualMachineDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"location": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"image": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"size": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"username": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"password": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Default: "",
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"ssh_public_key_file": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Default: "",
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"ssh_port": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Default: 22,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"endpoint": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true, // This can be updatable once we support updates on the resource
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"protocol": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"port": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"local_port": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Set: resourceVirtualMachineEndpointHash,
|
||||||
|
},
|
||||||
|
|
||||||
|
"url": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"ip_address": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"vip_address": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceVirtualMachineCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Creating Azure Virtual Machine Configuration...")
|
||||||
|
vmConfig, err := vmClient.CreateAzureVMConfiguration(
|
||||||
|
d.Get("name").(string),
|
||||||
|
d.Get("size").(string),
|
||||||
|
d.Get("image").(string),
|
||||||
|
d.Get("location").(string))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating Azure virtual machine configuration: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only Linux VMs are supported. If we want to support other VM types, we need to
|
||||||
|
// grab the image details and based on the OS add the corresponding configuration.
|
||||||
|
log.Printf("[DEBUG] Adding Azure Linux Provisioning Configuration...")
|
||||||
|
vmConfig, err = vmClient.AddAzureLinuxProvisioningConfig(
|
||||||
|
vmConfig,
|
||||||
|
d.Get("username").(string),
|
||||||
|
d.Get("password").(string),
|
||||||
|
d.Get("ssh_public_key_file").(string),
|
||||||
|
d.Get("ssh_port").(int))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error adding Azure linux provisioning configuration: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if v := d.Get("endpoint").(*schema.Set); v.Len() > 0 {
|
||||||
|
log.Printf("[DEBUG] Adding Endpoints to the Azure Virtual Machine...")
|
||||||
|
endpoints := make([]vmClient.InputEndpoint, v.Len())
|
||||||
|
for i, v := range v.List() {
|
||||||
|
m := v.(map[string]interface{})
|
||||||
|
endpoint := vmClient.InputEndpoint{}
|
||||||
|
endpoint.Name = m["name"].(string)
|
||||||
|
endpoint.Protocol = m["protocol"].(string)
|
||||||
|
endpoint.Port = m["port"].(int)
|
||||||
|
endpoint.LocalPort = m["local_port"].(int)
|
||||||
|
endpoints[i] = endpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
configSets := vmConfig.ConfigurationSets.ConfigurationSet
|
||||||
|
if len(configSets) == 0 {
|
||||||
|
return fmt.Errorf("Azure virtual machine does not have configuration sets")
|
||||||
|
}
|
||||||
|
for i := 0; i < len(configSets); i++ {
|
||||||
|
if configSets[i].ConfigurationSetType != "NetworkConfiguration" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
configSets[i].InputEndpoints.InputEndpoint =
|
||||||
|
append(configSets[i].InputEndpoints.InputEndpoint, endpoints...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Creating Azure Virtual Machine...")
|
||||||
|
err = vmClient.CreateAzureVM(
|
||||||
|
vmConfig,
|
||||||
|
d.Get("name").(string),
|
||||||
|
d.Get("location").(string))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating Azure virtual machine: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(d.Get("name").(string))
|
||||||
|
|
||||||
|
return resourceVirtualMachineRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceVirtualMachineRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Getting Azure Virtual Machine Deployment: %s", d.Id())
|
||||||
|
VMDeployment, err := vmClient.GetVMDeployment(d.Id(), d.Id())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error getting Azure virtual machine deployment: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("url", VMDeployment.Url)
|
||||||
|
|
||||||
|
roleInstances := VMDeployment.RoleInstanceList.RoleInstance
|
||||||
|
if len(roleInstances) == 0 {
|
||||||
|
return fmt.Errorf("Virtual Machine does not have IP addresses")
|
||||||
|
}
|
||||||
|
ipAddress := roleInstances[0].IpAddress
|
||||||
|
d.Set("ip_address", ipAddress)
|
||||||
|
|
||||||
|
vips := VMDeployment.VirtualIPs.VirtualIP
|
||||||
|
if len(vips) == 0 {
|
||||||
|
return fmt.Errorf("Virtual Machine does not have VIP addresses")
|
||||||
|
}
|
||||||
|
vip := vips[0].Address
|
||||||
|
d.Set("vip_address", vip)
|
||||||
|
|
||||||
|
d.SetConnInfo(map[string]string{
|
||||||
|
"type": "ssh",
|
||||||
|
"host": vip,
|
||||||
|
"user": d.Get("username").(string),
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceVirtualMachineDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
log.Printf("[DEBUG] Deleting Azure Virtual Machine Deployment: %s", d.Id())
|
||||||
|
if err := vmClient.DeleteVMDeployment(d.Id(), d.Id()); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting Azure virtual machine deployment: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Deleting Azure Hosted Service: %s", d.Id())
|
||||||
|
if err := vmClient.DeleteHostedService(d.Id()); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting Azure hosted service: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId("")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceVirtualMachineEndpointHash(v interface{}) int {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
m := v.(map[string]interface{})
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["protocol"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%d-", m["port"].(int)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%d-", m["local_port"].(int)))
|
||||||
|
|
||||||
|
return hashcode.String(buf.String())
|
||||||
|
}
|
|
@ -0,0 +1,180 @@
|
||||||
|
package azure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
"github.com/MSOpenTech/azure-sdk-for-go/clients/vmClient"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccAzureVirtualMachine_Basic(t *testing.T) {
|
||||||
|
var VMDeployment vmClient.VMDeployment
|
||||||
|
|
||||||
|
// The VM name can only be used once globally within azure,
|
||||||
|
// so we need to generate a random one
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
vmName := fmt.Sprintf("tf-test-vm-%d", rand.Int31())
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAzureVirtualMachineDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccCheckAzureVirtualMachineConfig_basic(vmName),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAzureVirtualMachineExists("azure_virtual_machine.foobar", &VMDeployment),
|
||||||
|
testAccCheckAzureVirtualMachineAttributes(&VMDeployment, vmName),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"azure_virtual_machine.foobar", "name", vmName),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"azure_virtual_machine.foobar", "location", "West US"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"azure_virtual_machine.foobar", "image", "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04-LTS-amd64-server-20140724-en-us-30GB"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"azure_virtual_machine.foobar", "size", "Basic_A1"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"azure_virtual_machine.foobar", "username", "foobar"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAzureVirtualMachine_Endpoints(t *testing.T) {
|
||||||
|
var VMDeployment vmClient.VMDeployment
|
||||||
|
|
||||||
|
// The VM name can only be used once globally within azure,
|
||||||
|
// so we need to generate a random one
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
vmName := fmt.Sprintf("tf-test-vm-%d", rand.Int31())
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAzureVirtualMachineDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccCheckAzureVirtualMachineConfig_endpoints(vmName),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAzureVirtualMachineExists("azure_virtual_machine.foobar", &VMDeployment),
|
||||||
|
testAccCheckAzureVirtualMachineAttributes(&VMDeployment, vmName),
|
||||||
|
testAccCheckAzureVirtualMachineEndpoint(&VMDeployment, "tcp", 80),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAzureVirtualMachineDestroy(s *terraform.State) error {
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "azure_virtual_machine" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := vmClient.GetVMDeployment(rs.Primary.ID, rs.Primary.ID)
|
||||||
|
if err == nil {
|
||||||
|
return fmt.Errorf("Azure Virtual Machine (%s) still exists", rs.Primary.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAzureVirtualMachineExists(n string, VMDeployment *vmClient.VMDeployment) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No Azure Virtual Machine ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
retrieveVMDeployment, err := vmClient.GetVMDeployment(rs.Primary.ID, rs.Primary.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if retrieveVMDeployment.Name != rs.Primary.ID {
|
||||||
|
return fmt.Errorf("Azure Virtual Machine not found %s %s", VMDeployment.Name, rs.Primary.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
*VMDeployment = *retrieveVMDeployment
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAzureVirtualMachineAttributes(VMDeployment *vmClient.VMDeployment, vmName string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
if VMDeployment.Name != vmName {
|
||||||
|
return fmt.Errorf("Bad name: %s != %s", VMDeployment.Name, vmName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAzureVirtualMachineEndpoint(VMDeployment *vmClient.VMDeployment, protocol string, publicPort int) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
roleInstances := VMDeployment.RoleInstanceList.RoleInstance
|
||||||
|
if len(roleInstances) == 0 {
|
||||||
|
return fmt.Errorf("Azure virtual machine does not have role instances")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(roleInstances); i++ {
|
||||||
|
instanceEndpoints := roleInstances[i].InstanceEndpoints.InstanceEndpoint
|
||||||
|
if len(instanceEndpoints) == 0 {
|
||||||
|
return fmt.Errorf("Azure virtual machine does not have endpoints")
|
||||||
|
}
|
||||||
|
endpointFound := 0
|
||||||
|
for j := 0; i < len(instanceEndpoints); i++ {
|
||||||
|
if instanceEndpoints[j].Protocol == protocol && instanceEndpoints[j].PublicPort == publicPort {
|
||||||
|
endpointFound = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if endpointFound == 0 {
|
||||||
|
return fmt.Errorf("Azure virtual machine does not have endpoint %s/%d", protocol, publicPort)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAzureVirtualMachineConfig_basic(vmName string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "azure_virtual_machine" "foobar" {
|
||||||
|
name = "%s"
|
||||||
|
location = "West US"
|
||||||
|
image = "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04-LTS-amd64-server-20140724-en-us-30GB"
|
||||||
|
size = "Basic_A1"
|
||||||
|
username = "foobar"
|
||||||
|
}
|
||||||
|
`, vmName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAzureVirtualMachineConfig_endpoints(vmName string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "azure_virtual_machine" "foobar" {
|
||||||
|
name = "%s"
|
||||||
|
location = "West US"
|
||||||
|
image = "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04-LTS-amd64-server-20140724-en-us-30GB"
|
||||||
|
size = "Basic_A1"
|
||||||
|
username = "foobar"
|
||||||
|
endpoint {
|
||||||
|
name = "http"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = 80
|
||||||
|
local_port = 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`, vmName)
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ body.layout-heroku,
|
||||||
body.layout-mailgun,
|
body.layout-mailgun,
|
||||||
body.layout-digitalocean,
|
body.layout-digitalocean,
|
||||||
body.layout-aws,
|
body.layout-aws,
|
||||||
|
body.layout-azure,
|
||||||
body.layout-docs,
|
body.layout-docs,
|
||||||
body.layout-inner,
|
body.layout-inner,
|
||||||
body.layout-downloads,
|
body.layout-downloads,
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
---
|
||||||
|
layout: "azure"
|
||||||
|
page_title: "Provider: Microsoft Azure"
|
||||||
|
sidebar_current: "docs-azure-index"
|
||||||
|
description: |-
|
||||||
|
The Azure provider is used to interact with Microsoft Azure services. The provider needs to be configured with the proper credentials before it can be used.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Azure Provider
|
||||||
|
|
||||||
|
The Azure provider is used to interact with
|
||||||
|
[Microsoft Azure](http://azure.microsoft.com/). The provider needs
|
||||||
|
to be configured with the proper credentials before it can be used.
|
||||||
|
|
||||||
|
Use the navigation to the left to read about the available resources.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
# Configure the Azure provider
|
||||||
|
provider "azure" {
|
||||||
|
publish_settings_file = "account.publishsettings"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a new instance
|
||||||
|
resource "azure_virtual_machine" "default" {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following keys can be used to configure the provider.
|
||||||
|
|
||||||
|
* `publish_settings_file` - (Required) Path to the JSON file used to describe
|
||||||
|
your account settings, downloaded from Microsoft Azure. It must be provided,
|
||||||
|
but it can also be sourced from the AZURE_PUBLISH_SETTINGS_FILE environment variable.
|
|
@ -0,0 +1,71 @@
|
||||||
|
---
|
||||||
|
layout: "azure"
|
||||||
|
page_title: "Azure: azure_virtual_machine"
|
||||||
|
sidebar_current: "docs-azure-resource-virtual-machine"
|
||||||
|
description: |-
|
||||||
|
Manages a Virtual Machine resource within Azure.
|
||||||
|
---
|
||||||
|
|
||||||
|
# azure\_virtual\_machine
|
||||||
|
|
||||||
|
Manages a Virtual Machine resource within Azure.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "azure_virtual_machine" "default" {
|
||||||
|
name = "test"
|
||||||
|
location = "West US"
|
||||||
|
image = "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04-LTS-amd64-server-20140724-en-us-30GB"
|
||||||
|
size = "Basic_A1"
|
||||||
|
username = "${var.username}"
|
||||||
|
password = ""${var.password}"
|
||||||
|
ssh_public_key_file = "${var.azure_ssh_public_key_file}"
|
||||||
|
endpoint {
|
||||||
|
name = "http"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = 80
|
||||||
|
local_port = 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) A name for the virtual machine. It must use between 3 and
|
||||||
|
24 lowercase letters and numbers and it must be unique within Azure.
|
||||||
|
|
||||||
|
* `location` - (Required) The location that the virtual machine should be created in.
|
||||||
|
|
||||||
|
* `image` - (Required) A image to be used to create the virtual machine.
|
||||||
|
|
||||||
|
* `size` - (Required) Size that you want to use for the virtual machine.
|
||||||
|
|
||||||
|
* `username` - (Required) Name of the account that you will use to administer
|
||||||
|
the virtual machine. You cannot use root for the user name.
|
||||||
|
|
||||||
|
* `password` - (Optional) Password for the admin account.
|
||||||
|
|
||||||
|
* `ssh_public_key_file` - (Optional) SSH key (PEM format).
|
||||||
|
|
||||||
|
* `ssh_port` - (Optional) SSH port.
|
||||||
|
|
||||||
|
* `endpoint` - (Optional) Can be specified multiple times for each
|
||||||
|
endpoint rule. Each endpoint block supports fields documented below.
|
||||||
|
|
||||||
|
The `endpoint` block supports:
|
||||||
|
|
||||||
|
* `name` - (Required) The name of the endpoint.
|
||||||
|
* `protocol` - (Required) The protocol.
|
||||||
|
* `port` - (Required) The public port.
|
||||||
|
* `local_port` - (Required) The private port.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `url` - The URL for the virtual machine deployment.
|
||||||
|
* `ip_address` - The internal IP address of the virtual machine.
|
||||||
|
* `vip_address` - The public Virtual IP address of the virtual machine.
|
|
@ -0,0 +1,26 @@
|
||||||
|
<% wrap_layout :inner do %>
|
||||||
|
<% content_for :sidebar do %>
|
||||||
|
<div class="docs-sidebar hidden-print affix-top" role="complementary">
|
||||||
|
<ul class="nav docs-sidenav">
|
||||||
|
<li<%= sidebar_current("docs-home") %>>
|
||||||
|
<a href="/docs/index.html">« Documentation Home</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-azure-index") %>>
|
||||||
|
<a href="/docs/providers/azure/index.html">Azure Provider</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-azure-resource") %>>
|
||||||
|
<a href="#">Resources</a>
|
||||||
|
<ul class="nav nav-visible">
|
||||||
|
<li<%= sidebar_current("docs-azure-resource-virtual-machine") %>>
|
||||||
|
<a href="/docs/providers/azure/r/virtual_machine.html">azure_virtual_machine</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= yield %>
|
||||||
|
<% end %>
|
|
@ -112,6 +112,10 @@
|
||||||
<a href="/docs/providers/aws/index.html">AWS</a>
|
<a href="/docs/providers/aws/index.html">AWS</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-providers-azure") %>>
|
||||||
|
<a href="/docs/providers/azure/index.html">Azure</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-providers-cloudflare") %>>
|
<li<%= sidebar_current("docs-providers-cloudflare") %>>
|
||||||
<a href="/docs/providers/cloudflare/index.html">CloudFlare</a>
|
<a href="/docs/providers/cloudflare/index.html">CloudFlare</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
Loading…
Reference in New Issue