github.com/alexissmirnov/terraform@v0.4.3-0.20150423153700-1ef9731a2f14/builtin/providers/aws/resource_aws_route53_zone.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 "time" 8 9 "github.com/hashicorp/terraform/helper/hashcode" 10 "github.com/hashicorp/terraform/helper/resource" 11 "github.com/hashicorp/terraform/helper/schema" 12 13 "github.com/awslabs/aws-sdk-go/aws" 14 "github.com/awslabs/aws-sdk-go/service/route53" 15 ) 16 17 func resourceAwsRoute53Zone() *schema.Resource { 18 return &schema.Resource{ 19 Create: resourceAwsRoute53ZoneCreate, 20 Read: resourceAwsRoute53ZoneRead, 21 Update: resourceAwsRoute53ZoneUpdate, 22 Delete: resourceAwsRoute53ZoneDelete, 23 24 Schema: map[string]*schema.Schema{ 25 "name": &schema.Schema{ 26 Type: schema.TypeString, 27 Required: true, 28 ForceNew: true, 29 }, 30 31 "zone_id": &schema.Schema{ 32 Type: schema.TypeString, 33 Computed: true, 34 }, 35 36 "name_servers": &schema.Schema{ 37 Type: schema.TypeSet, 38 Elem: &schema.Schema{Type: schema.TypeString}, 39 Computed: true, 40 Set: func(v interface{}) int { 41 return hashcode.String(v.(string)) 42 }, 43 }, 44 45 "tags": tagsSchema(), 46 }, 47 } 48 } 49 50 func resourceAwsRoute53ZoneCreate(d *schema.ResourceData, meta interface{}) error { 51 r53 := meta.(*AWSClient).r53conn 52 53 comment := &route53.HostedZoneConfig{Comment: aws.String("Managed by Terraform")} 54 req := &route53.CreateHostedZoneInput{ 55 Name: aws.String(d.Get("name").(string)), 56 HostedZoneConfig: comment, 57 CallerReference: aws.String(time.Now().Format(time.RFC3339Nano)), 58 } 59 60 log.Printf("[DEBUG] Creating Route53 hosted zone: %s", *req.Name) 61 resp, err := r53.CreateHostedZone(req) 62 if err != nil { 63 return err 64 } 65 66 // Store the zone_id 67 zone := cleanZoneID(*resp.HostedZone.ID) 68 d.Set("zone_id", zone) 69 d.SetId(zone) 70 71 // Wait until we are done initializing 72 wait := resource.StateChangeConf{ 73 Delay: 30 * time.Second, 74 Pending: []string{"PENDING"}, 75 Target: "INSYNC", 76 Timeout: 10 * time.Minute, 77 MinTimeout: 2 * time.Second, 78 Refresh: func() (result interface{}, state string, err error) { 79 changeRequest := &route53.GetChangeInput{ 80 ID: aws.String(cleanChangeID(*resp.ChangeInfo.ID)), 81 } 82 return resourceAwsGoRoute53Wait(r53, changeRequest) 83 }, 84 } 85 _, err = wait.WaitForState() 86 if err != nil { 87 return err 88 } 89 return resourceAwsRoute53ZoneUpdate(d, meta) 90 } 91 92 func resourceAwsRoute53ZoneRead(d *schema.ResourceData, meta interface{}) error { 93 r53 := meta.(*AWSClient).r53conn 94 zone, err := r53.GetHostedZone(&route53.GetHostedZoneInput{ID: aws.String(d.Id())}) 95 if err != nil { 96 // Handle a deleted zone 97 if r53err, ok := err.(aws.APIError); ok && r53err.Code == "NoSuchHostedZone" { 98 d.SetId("") 99 return nil 100 } 101 return err 102 } 103 104 ns := make([]string, len(zone.DelegationSet.NameServers)) 105 for i := range zone.DelegationSet.NameServers { 106 ns[i] = *zone.DelegationSet.NameServers[i] 107 } 108 if err := d.Set("name_servers", ns); err != nil { 109 return fmt.Errorf("[DEBUG] Error setting name servers for: %s, error: %#v", d.Id(), err) 110 } 111 112 // get tags 113 req := &route53.ListTagsForResourceInput{ 114 ResourceID: aws.String(d.Id()), 115 ResourceType: aws.String("hostedzone"), 116 } 117 118 resp, err := r53.ListTagsForResource(req) 119 if err != nil { 120 return err 121 } 122 123 var tags []*route53.Tag 124 if resp.ResourceTagSet != nil { 125 tags = resp.ResourceTagSet.Tags 126 } 127 128 if err := d.Set("tags", tagsToMapR53(tags)); err != nil { 129 return err 130 } 131 132 return nil 133 } 134 135 func resourceAwsRoute53ZoneUpdate(d *schema.ResourceData, meta interface{}) error { 136 conn := meta.(*AWSClient).r53conn 137 138 if err := setTagsR53(conn, d); err != nil { 139 return err 140 } else { 141 d.SetPartial("tags") 142 } 143 144 return resourceAwsRoute53ZoneRead(d, meta) 145 } 146 147 func resourceAwsRoute53ZoneDelete(d *schema.ResourceData, meta interface{}) error { 148 r53 := meta.(*AWSClient).r53conn 149 150 log.Printf("[DEBUG] Deleting Route53 hosted zone: %s (ID: %s)", 151 d.Get("name").(string), d.Id()) 152 _, err := r53.DeleteHostedZone(&route53.DeleteHostedZoneInput{ID: aws.String(d.Id())}) 153 if err != nil { 154 return err 155 } 156 157 return nil 158 } 159 160 func resourceAwsGoRoute53Wait(r53 *route53.Route53, ref *route53.GetChangeInput) (result interface{}, state string, err error) { 161 162 status, err := r53.GetChange(ref) 163 if err != nil { 164 return nil, "UNKNOWN", err 165 } 166 return true, *status.ChangeInfo.Status, nil 167 } 168 169 // cleanChangeID is used to remove the leading /change/ 170 func cleanChangeID(ID string) string { 171 return cleanPrefix(ID, "/change/") 172 } 173 174 // cleanZoneID is used to remove the leading /hostedzone/ 175 func cleanZoneID(ID string) string { 176 return cleanPrefix(ID, "/hostedzone/") 177 } 178 179 // cleanPrefix removes a string prefix from an ID 180 func cleanPrefix(ID, prefix string) string { 181 if strings.HasPrefix(ID, prefix) { 182 ID = strings.TrimPrefix(ID, prefix) 183 } 184 return ID 185 }