github.com/keshavdv/terraform@v0.7.0-rc2.0.20160711232630-d69256dcb425/builtin/providers/aws/resource_aws_efs_mount_target.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "time" 7 8 "github.com/aws/aws-sdk-go/aws" 9 "github.com/aws/aws-sdk-go/aws/awserr" 10 "github.com/aws/aws-sdk-go/service/ec2" 11 "github.com/aws/aws-sdk-go/service/efs" 12 "github.com/hashicorp/terraform/helper/resource" 13 "github.com/hashicorp/terraform/helper/schema" 14 ) 15 16 func resourceAwsEfsMountTarget() *schema.Resource { 17 return &schema.Resource{ 18 Create: resourceAwsEfsMountTargetCreate, 19 Read: resourceAwsEfsMountTargetRead, 20 Update: resourceAwsEfsMountTargetUpdate, 21 Delete: resourceAwsEfsMountTargetDelete, 22 23 Importer: &schema.ResourceImporter{ 24 State: schema.ImportStatePassthrough, 25 }, 26 27 Schema: map[string]*schema.Schema{ 28 "file_system_id": &schema.Schema{ 29 Type: schema.TypeString, 30 Required: true, 31 ForceNew: true, 32 }, 33 34 "ip_address": &schema.Schema{ 35 Type: schema.TypeString, 36 Computed: true, 37 Optional: true, 38 ForceNew: true, 39 }, 40 41 "security_groups": &schema.Schema{ 42 Type: schema.TypeSet, 43 Elem: &schema.Schema{Type: schema.TypeString}, 44 Set: schema.HashString, 45 Computed: true, 46 Optional: true, 47 }, 48 49 "subnet_id": &schema.Schema{ 50 Type: schema.TypeString, 51 Required: true, 52 ForceNew: true, 53 }, 54 55 "network_interface_id": &schema.Schema{ 56 Type: schema.TypeString, 57 Computed: true, 58 }, 59 "dns_name": &schema.Schema{ 60 Type: schema.TypeString, 61 Computed: true, 62 }, 63 }, 64 } 65 } 66 67 func resourceAwsEfsMountTargetCreate(d *schema.ResourceData, meta interface{}) error { 68 conn := meta.(*AWSClient).efsconn 69 70 input := efs.CreateMountTargetInput{ 71 FileSystemId: aws.String(d.Get("file_system_id").(string)), 72 SubnetId: aws.String(d.Get("subnet_id").(string)), 73 } 74 75 if v, ok := d.GetOk("ip_address"); ok { 76 input.IpAddress = aws.String(v.(string)) 77 } 78 if v, ok := d.GetOk("security_groups"); ok { 79 input.SecurityGroups = expandStringList(v.(*schema.Set).List()) 80 } 81 82 log.Printf("[DEBUG] Creating EFS mount target: %#v", input) 83 84 mt, err := conn.CreateMountTarget(&input) 85 if err != nil { 86 return err 87 } 88 89 d.SetId(*mt.MountTargetId) 90 91 stateConf := &resource.StateChangeConf{ 92 Pending: []string{"creating"}, 93 Target: []string{"available"}, 94 Refresh: func() (interface{}, string, error) { 95 resp, err := conn.DescribeMountTargets(&efs.DescribeMountTargetsInput{ 96 MountTargetId: aws.String(d.Id()), 97 }) 98 if err != nil { 99 return nil, "error", err 100 } 101 102 if len(resp.MountTargets) < 1 { 103 return nil, "error", fmt.Errorf("EFS mount target %q not found", d.Id()) 104 } 105 106 mt := resp.MountTargets[0] 107 108 log.Printf("[DEBUG] Current status of %q: %q", *mt.MountTargetId, *mt.LifeCycleState) 109 return mt, *mt.LifeCycleState, nil 110 }, 111 Timeout: 10 * time.Minute, 112 Delay: 2 * time.Second, 113 MinTimeout: 3 * time.Second, 114 } 115 116 _, err = stateConf.WaitForState() 117 if err != nil { 118 return fmt.Errorf("Error waiting for EFS mount target (%s) to create: %s", d.Id(), err) 119 } 120 121 log.Printf("[DEBUG] EFS mount target created: %s", *mt.MountTargetId) 122 123 return resourceAwsEfsMountTargetRead(d, meta) 124 } 125 126 func resourceAwsEfsMountTargetUpdate(d *schema.ResourceData, meta interface{}) error { 127 conn := meta.(*AWSClient).efsconn 128 129 if d.HasChange("security_groups") { 130 input := efs.ModifyMountTargetSecurityGroupsInput{ 131 MountTargetId: aws.String(d.Id()), 132 SecurityGroups: expandStringList(d.Get("security_groups").(*schema.Set).List()), 133 } 134 _, err := conn.ModifyMountTargetSecurityGroups(&input) 135 if err != nil { 136 return err 137 } 138 } 139 140 return resourceAwsEfsMountTargetRead(d, meta) 141 } 142 143 func resourceAwsEfsMountTargetRead(d *schema.ResourceData, meta interface{}) error { 144 conn := meta.(*AWSClient).efsconn 145 resp, err := conn.DescribeMountTargets(&efs.DescribeMountTargetsInput{ 146 MountTargetId: aws.String(d.Id()), 147 }) 148 if err != nil { 149 return err 150 } 151 152 if len(resp.MountTargets) < 1 { 153 return fmt.Errorf("EFS mount target %q not found", d.Id()) 154 } 155 156 mt := resp.MountTargets[0] 157 158 log.Printf("[DEBUG] Found EFS mount target: %#v", mt) 159 160 d.SetId(*mt.MountTargetId) 161 d.Set("file_system_id", *mt.FileSystemId) 162 d.Set("ip_address", *mt.IpAddress) 163 d.Set("subnet_id", *mt.SubnetId) 164 d.Set("network_interface_id", *mt.NetworkInterfaceId) 165 166 sgResp, err := conn.DescribeMountTargetSecurityGroups(&efs.DescribeMountTargetSecurityGroupsInput{ 167 MountTargetId: aws.String(d.Id()), 168 }) 169 if err != nil { 170 return err 171 } 172 173 d.Set("security_groups", schema.NewSet(schema.HashString, flattenStringList(sgResp.SecurityGroups))) 174 175 // DNS name per http://docs.aws.amazon.com/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html 176 az, err := getAzFromSubnetId(*mt.SubnetId, meta.(*AWSClient).ec2conn) 177 if err != nil { 178 return fmt.Errorf("Failed getting AZ from subnet ID (%s): %s", *mt.SubnetId, err) 179 } 180 region := meta.(*AWSClient).region 181 d.Set("dns_name", fmt.Sprintf("%s.%s.efs.%s.amazonaws.com", az, *mt.FileSystemId, region)) 182 183 return nil 184 } 185 186 func getAzFromSubnetId(subnetId string, conn *ec2.EC2) (string, error) { 187 input := ec2.DescribeSubnetsInput{ 188 SubnetIds: []*string{aws.String(subnetId)}, 189 } 190 out, err := conn.DescribeSubnets(&input) 191 if err != nil { 192 return "", err 193 } 194 195 if len(out.Subnets) != 1 { 196 return "", fmt.Errorf("Expected exactly 1 subnet returned for %q", subnetId) 197 } 198 199 return *out.Subnets[0].AvailabilityZone, nil 200 } 201 202 func resourceAwsEfsMountTargetDelete(d *schema.ResourceData, meta interface{}) error { 203 conn := meta.(*AWSClient).efsconn 204 205 log.Printf("[DEBUG] Deleting EFS mount target %q", d.Id()) 206 _, err := conn.DeleteMountTarget(&efs.DeleteMountTargetInput{ 207 MountTargetId: aws.String(d.Id()), 208 }) 209 if err != nil { 210 return err 211 } 212 213 stateConf := &resource.StateChangeConf{ 214 Pending: []string{"available", "deleting", "deleted"}, 215 Target: []string{}, 216 Refresh: func() (interface{}, string, error) { 217 resp, err := conn.DescribeMountTargets(&efs.DescribeMountTargetsInput{ 218 MountTargetId: aws.String(d.Id()), 219 }) 220 if err != nil { 221 awsErr, ok := err.(awserr.Error) 222 if !ok { 223 return nil, "error", err 224 } 225 226 if awsErr.Code() == "MountTargetNotFound" { 227 return nil, "", nil 228 } 229 230 return nil, "error", awsErr 231 } 232 233 if len(resp.MountTargets) < 1 { 234 return nil, "", nil 235 } 236 237 mt := resp.MountTargets[0] 238 239 log.Printf("[DEBUG] Current status of %q: %q", *mt.MountTargetId, *mt.LifeCycleState) 240 return mt, *mt.LifeCycleState, nil 241 }, 242 Timeout: 10 * time.Minute, 243 Delay: 2 * time.Second, 244 MinTimeout: 3 * time.Second, 245 } 246 247 _, err = stateConf.WaitForState() 248 if err != nil { 249 return fmt.Errorf("Error waiting for EFS mount target (%q) to delete: %q", 250 d.Id(), err.Error()) 251 } 252 253 log.Printf("[DEBUG] EFS mount target %q deleted.", d.Id()) 254 255 return nil 256 }