github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/builtin/providers/azurerm/resource_arm_network_security_rule.go (about) 1 package azurerm 2 3 import ( 4 "fmt" 5 "log" 6 "net/http" 7 "time" 8 9 "github.com/Azure/azure-sdk-for-go/arm/network" 10 "github.com/hashicorp/terraform/helper/resource" 11 "github.com/hashicorp/terraform/helper/schema" 12 ) 13 14 func resourceArmNetworkSecurityRule() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceArmNetworkSecurityRuleCreate, 17 Read: resourceArmNetworkSecurityRuleRead, 18 Update: resourceArmNetworkSecurityRuleCreate, 19 Delete: resourceArmNetworkSecurityRuleDelete, 20 21 Schema: map[string]*schema.Schema{ 22 "name": &schema.Schema{ 23 Type: schema.TypeString, 24 Required: true, 25 ForceNew: true, 26 }, 27 28 "resource_group_name": &schema.Schema{ 29 Type: schema.TypeString, 30 Required: true, 31 ForceNew: true, 32 }, 33 34 "network_security_group_name": &schema.Schema{ 35 Type: schema.TypeString, 36 Required: true, 37 }, 38 39 "description": &schema.Schema{ 40 Type: schema.TypeString, 41 Optional: true, 42 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 43 value := v.(string) 44 if len(value) > 140 { 45 errors = append(errors, fmt.Errorf( 46 "The network security rule description can be no longer than 140 chars")) 47 } 48 return 49 }, 50 }, 51 52 "protocol": &schema.Schema{ 53 Type: schema.TypeString, 54 Required: true, 55 ValidateFunc: validateNetworkSecurityRuleProtocol, 56 }, 57 58 "source_port_range": &schema.Schema{ 59 Type: schema.TypeString, 60 Required: true, 61 }, 62 63 "destination_port_range": &schema.Schema{ 64 Type: schema.TypeString, 65 Required: true, 66 }, 67 68 "source_address_prefix": &schema.Schema{ 69 Type: schema.TypeString, 70 Required: true, 71 }, 72 73 "destination_address_prefix": &schema.Schema{ 74 Type: schema.TypeString, 75 Required: true, 76 }, 77 78 "access": &schema.Schema{ 79 Type: schema.TypeString, 80 Required: true, 81 ValidateFunc: validateNetworkSecurityRuleAccess, 82 }, 83 84 "priority": &schema.Schema{ 85 Type: schema.TypeInt, 86 Required: true, 87 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 88 value := v.(int) 89 if value < 100 || value > 4096 { 90 errors = append(errors, fmt.Errorf( 91 "The `priority` can only be between 100 and 4096")) 92 } 93 return 94 }, 95 }, 96 97 "direction": &schema.Schema{ 98 Type: schema.TypeString, 99 Required: true, 100 ValidateFunc: validateNetworkSecurityRuleDirection, 101 }, 102 }, 103 } 104 } 105 106 func resourceArmNetworkSecurityRuleCreate(d *schema.ResourceData, meta interface{}) error { 107 client := meta.(*ArmClient) 108 secClient := client.secRuleClient 109 110 name := d.Get("name").(string) 111 nsgName := d.Get("network_security_group_name").(string) 112 resGroup := d.Get("resource_group_name").(string) 113 114 source_port_range := d.Get("source_port_range").(string) 115 destination_port_range := d.Get("destination_port_range").(string) 116 source_address_prefix := d.Get("source_address_prefix").(string) 117 destination_address_prefix := d.Get("destination_address_prefix").(string) 118 priority := d.Get("priority").(int) 119 access := d.Get("access").(string) 120 direction := d.Get("direction").(string) 121 protocol := d.Get("protocol").(string) 122 123 armMutexKV.Lock(nsgName) 124 defer armMutexKV.Unlock(nsgName) 125 126 properties := network.SecurityRulePropertiesFormat{ 127 SourcePortRange: &source_port_range, 128 DestinationPortRange: &destination_port_range, 129 SourceAddressPrefix: &source_address_prefix, 130 DestinationAddressPrefix: &destination_address_prefix, 131 Priority: &priority, 132 Access: network.SecurityRuleAccess(access), 133 Direction: network.SecurityRuleDirection(direction), 134 Protocol: network.SecurityRuleProtocol(protocol), 135 } 136 137 if v, ok := d.GetOk("description"); ok { 138 description := v.(string) 139 properties.Description = &description 140 } 141 142 sgr := network.SecurityRule{ 143 Name: &name, 144 Properties: &properties, 145 } 146 147 resp, err := secClient.CreateOrUpdate(resGroup, nsgName, name, sgr) 148 if err != nil { 149 return err 150 } 151 d.SetId(*resp.ID) 152 153 log.Printf("[DEBUG] Waiting for Network Security Rule (%s) to become available", name) 154 stateConf := &resource.StateChangeConf{ 155 Pending: []string{"Accepted", "Updating"}, 156 Target: "Succeeded", 157 Refresh: securityRuleStateRefreshFunc(client, resGroup, nsgName, name), 158 Timeout: 10 * time.Minute, 159 } 160 if _, err := stateConf.WaitForState(); err != nil { 161 return fmt.Errorf("Error waiting for Network Securty Rule (%s) to become available: %s", name, err) 162 } 163 164 return resourceArmNetworkSecurityRuleRead(d, meta) 165 } 166 167 func resourceArmNetworkSecurityRuleRead(d *schema.ResourceData, meta interface{}) error { 168 secRuleClient := meta.(*ArmClient).secRuleClient 169 170 id, err := parseAzureResourceID(d.Id()) 171 if err != nil { 172 return err 173 } 174 resGroup := id.ResourceGroup 175 networkSGName := id.Path["networkSecurityGroups"] 176 sgRuleName := id.Path["securityRules"] 177 178 resp, err := secRuleClient.Get(resGroup, networkSGName, sgRuleName) 179 if resp.StatusCode == http.StatusNotFound { 180 d.SetId("") 181 return nil 182 } 183 if err != nil { 184 return fmt.Errorf("Error making Read request on Azure Network Security Rule %s: %s", sgRuleName, err) 185 } 186 187 return nil 188 } 189 190 func resourceArmNetworkSecurityRuleDelete(d *schema.ResourceData, meta interface{}) error { 191 client := meta.(*ArmClient) 192 secRuleClient := client.secRuleClient 193 194 id, err := parseAzureResourceID(d.Id()) 195 if err != nil { 196 return err 197 } 198 resGroup := id.ResourceGroup 199 nsgName := id.Path["networkSecurityGroups"] 200 sgRuleName := id.Path["securityRules"] 201 202 armMutexKV.Lock(nsgName) 203 defer armMutexKV.Unlock(nsgName) 204 205 _, err = secRuleClient.Delete(resGroup, nsgName, sgRuleName) 206 207 return err 208 } 209 210 func securityRuleStateRefreshFunc(client *ArmClient, resourceGroupName string, networkSecurityGroupName string, securityRuleName string) resource.StateRefreshFunc { 211 return func() (interface{}, string, error) { 212 res, err := client.secRuleClient.Get(resourceGroupName, networkSecurityGroupName, securityRuleName) 213 if err != nil { 214 return nil, "", fmt.Errorf("Error issuing read request in securityGroupStateRefreshFunc to Azure ARM for network security rule '%s' (RG: '%s') (NSG: '%s'): %s", securityRuleName, resourceGroupName, networkSecurityGroupName, err) 215 } 216 217 return res, *res.Properties.ProvisioningState, nil 218 } 219 }