Merge pull request #1632 from hashicorp/f-generate-sg-names
unique identifier helper for resources / generate AWS security group names
This commit is contained in:
commit
69ef012dfc
|
@ -364,16 +364,13 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface
|
||||||
createLaunchConfigurationOpts.BlockDeviceMappings = blockDevices
|
createLaunchConfigurationOpts.BlockDeviceMappings = blockDevices
|
||||||
}
|
}
|
||||||
|
|
||||||
var id string
|
var lcName string
|
||||||
if v, ok := d.GetOk("name"); ok {
|
if v, ok := d.GetOk("name"); ok {
|
||||||
id = v.(string)
|
lcName = v.(string)
|
||||||
} else {
|
} else {
|
||||||
hash := sha1.Sum([]byte(fmt.Sprintf("%#v", createLaunchConfigurationOpts)))
|
lcName = resource.UniqueId()
|
||||||
configName := fmt.Sprintf("terraform-%s", base64.URLEncoding.EncodeToString(hash[:]))
|
|
||||||
log.Printf("[DEBUG] Computed Launch config name: %s", configName)
|
|
||||||
id = configName
|
|
||||||
}
|
}
|
||||||
createLaunchConfigurationOpts.LaunchConfigurationName = aws.String(id)
|
createLaunchConfigurationOpts.LaunchConfigurationName = aws.String(lcName)
|
||||||
|
|
||||||
log.Printf(
|
log.Printf(
|
||||||
"[DEBUG] autoscaling create launch configuration: %#v", createLaunchConfigurationOpts)
|
"[DEBUG] autoscaling create launch configuration: %#v", createLaunchConfigurationOpts)
|
||||||
|
@ -382,7 +379,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface
|
||||||
return fmt.Errorf("Error creating launch configuration: %s", err)
|
return fmt.Errorf("Error creating launch configuration: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetId(id)
|
d.SetId(lcName)
|
||||||
log.Printf("[INFO] launch configuration ID: %s", d.Id())
|
log.Printf("[INFO] launch configuration ID: %s", d.Id())
|
||||||
|
|
||||||
// We put a Retry here since sometimes eventual consistency bites
|
// We put a Retry here since sometimes eventual consistency bites
|
||||||
|
|
|
@ -24,13 +24,15 @@ func resourceAwsSecurityGroup() *schema.Resource {
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"name": &schema.Schema{
|
"name": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
"description": &schema.Schema{
|
"description": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Optional: true,
|
||||||
|
Default: "Managed by Terraform",
|
||||||
},
|
},
|
||||||
|
|
||||||
"vpc_id": &schema.Schema{
|
"vpc_id": &schema.Schema{
|
||||||
|
@ -144,9 +146,7 @@ func resourceAwsSecurityGroup() *schema.Resource {
|
||||||
func resourceAwsSecurityGroupCreate(d *schema.ResourceData, meta interface{}) error {
|
func resourceAwsSecurityGroupCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
conn := meta.(*AWSClient).ec2conn
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
|
||||||
securityGroupOpts := &ec2.CreateSecurityGroupInput{
|
securityGroupOpts := &ec2.CreateSecurityGroupInput{}
|
||||||
GroupName: aws.String(d.Get("name").(string)),
|
|
||||||
}
|
|
||||||
|
|
||||||
if v := d.Get("vpc_id"); v != nil {
|
if v := d.Get("vpc_id"); v != nil {
|
||||||
securityGroupOpts.VPCID = aws.String(v.(string))
|
securityGroupOpts.VPCID = aws.String(v.(string))
|
||||||
|
@ -156,6 +156,14 @@ func resourceAwsSecurityGroupCreate(d *schema.ResourceData, meta interface{}) er
|
||||||
securityGroupOpts.Description = aws.String(v.(string))
|
securityGroupOpts.Description = aws.String(v.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var groupName string
|
||||||
|
if v, ok := d.GetOk("name"); ok {
|
||||||
|
groupName = v.(string)
|
||||||
|
} else {
|
||||||
|
groupName = resource.UniqueId()
|
||||||
|
}
|
||||||
|
securityGroupOpts.GroupName = aws.String(groupName)
|
||||||
|
|
||||||
log.Printf(
|
log.Printf(
|
||||||
"[DEBUG] Security Group create configuration: %#v", securityGroupOpts)
|
"[DEBUG] Security Group create configuration: %#v", securityGroupOpts)
|
||||||
createResp, err := conn.CreateSecurityGroup(securityGroupOpts)
|
createResp, err := conn.CreateSecurityGroup(securityGroupOpts)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package aws
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/awslabs/aws-sdk-go/aws"
|
"github.com/awslabs/aws-sdk-go/aws"
|
||||||
|
@ -184,6 +185,35 @@ func TestAccAWSSecurityGroup_Change(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccAWSSecurityGroup_generatedName(t *testing.T) {
|
||||||
|
var group ec2.SecurityGroup
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSSecurityGroupConfig_generatedName,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_security_group.web", "description", "Managed by Terraform"),
|
||||||
|
func(s *terraform.State) error {
|
||||||
|
if group.GroupName == nil {
|
||||||
|
return fmt.Errorf("bad: No SG name")
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(*group.GroupName, "terraform-") {
|
||||||
|
return fmt.Errorf("No terraform- prefix: %s", *group.GroupName)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func testAccCheckAWSSecurityGroupDestroy(s *terraform.State) error {
|
func testAccCheckAWSSecurityGroupDestroy(s *terraform.State) error {
|
||||||
conn := testAccProvider.Meta().(*AWSClient).ec2conn
|
conn := testAccProvider.Meta().(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
@ -518,3 +548,18 @@ resource "aws_security_group" "foo" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const testAccAWSSecurityGroupConfig_generatedName = `
|
||||||
|
resource "aws_security_group" "web" {
|
||||||
|
ingress {
|
||||||
|
protocol = "tcp"
|
||||||
|
from_port = 80
|
||||||
|
to_port = 8000
|
||||||
|
cidr_blocks = ["10.0.0.0/8"]
|
||||||
|
}
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "tf-acc-test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package resource
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/base32"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const UniqueIdPrefix = `terraform-`
|
||||||
|
|
||||||
|
// Helper for a resource to generate a unique identifier
|
||||||
|
//
|
||||||
|
// This uses a simple RFC 4122 v4 UUID with some basic cosmetic filters
|
||||||
|
// applied (base32, remove padding, downcase) to make visually distinguishing
|
||||||
|
// identifiers easier.
|
||||||
|
func UniqueId() string {
|
||||||
|
return fmt.Sprintf("%s%s", UniqueIdPrefix,
|
||||||
|
strings.ToLower(
|
||||||
|
strings.Replace(
|
||||||
|
base32.StdEncoding.EncodeToString(uuidV4()),
|
||||||
|
"=", "", -1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func uuidV4() []byte {
|
||||||
|
var uuid [16]byte
|
||||||
|
|
||||||
|
// Set all the other bits to randomly (or pseudo-randomly) chosen
|
||||||
|
// values.
|
||||||
|
rand.Read(uuid[:])
|
||||||
|
|
||||||
|
// Set the two most significant bits (bits 6 and 7) of the
|
||||||
|
// clock_seq_hi_and_reserved to zero and one, respectively.
|
||||||
|
uuid[8] = (uuid[8] | 0x80) & 0x8f
|
||||||
|
|
||||||
|
// Set the four most significant bits (bits 12 through 15) of the
|
||||||
|
// time_hi_and_version field to the 4-bit version number from Section 4.1.3.
|
||||||
|
uuid[6] = (uuid[6] | 0x40) & 0x4f
|
||||||
|
|
||||||
|
return uuid[:]
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package resource
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUniqueId(t *testing.T) {
|
||||||
|
iterations := 10000
|
||||||
|
ids := make(map[string]struct{})
|
||||||
|
var id string
|
||||||
|
for i := 0; i < iterations; i++ {
|
||||||
|
id = UniqueId()
|
||||||
|
|
||||||
|
if _, ok := ids[id]; ok {
|
||||||
|
t.Fatalf("Got duplicated id! %s", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.HasPrefix(id, "terraform-") {
|
||||||
|
t.Fatalf("Unique ID didn't have terraform- prefix! %s", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
ids[id] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue