github.com/daveadams/terraform@v0.6.4-0.20160830094355-13ce74975936/builtin/providers/aws/resource_aws_efs_file_system.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/efs" 11 "github.com/hashicorp/terraform/helper/resource" 12 "github.com/hashicorp/terraform/helper/schema" 13 ) 14 15 func resourceAwsEfsFileSystem() *schema.Resource { 16 return &schema.Resource{ 17 Create: resourceAwsEfsFileSystemCreate, 18 Read: resourceAwsEfsFileSystemRead, 19 Update: resourceAwsEfsFileSystemUpdate, 20 Delete: resourceAwsEfsFileSystemDelete, 21 22 Importer: &schema.ResourceImporter{ 23 State: schema.ImportStatePassthrough, 24 }, 25 26 Schema: map[string]*schema.Schema{ 27 "creation_token": &schema.Schema{ 28 Type: schema.TypeString, 29 Optional: true, 30 ForceNew: true, 31 ValidateFunc: validateMaxLength(64), 32 }, 33 34 "reference_name": &schema.Schema{ 35 Type: schema.TypeString, 36 Optional: true, 37 ForceNew: true, 38 Deprecated: "Please use attribute `creation_token' instead. This attribute might be removed in future releases.", 39 ConflictsWith: []string{"creation_token"}, 40 ValidateFunc: validateReferenceName, 41 }, 42 43 "performance_mode": &schema.Schema{ 44 Type: schema.TypeString, 45 Optional: true, 46 ForceNew: true, 47 ValidateFunc: validatePerformanceModeType, 48 }, 49 50 "tags": tagsSchema(), 51 }, 52 } 53 } 54 55 func resourceAwsEfsFileSystemCreate(d *schema.ResourceData, meta interface{}) error { 56 conn := meta.(*AWSClient).efsconn 57 58 creationToken := "" 59 if v, ok := d.GetOk("creation_token"); ok { 60 creationToken = v.(string) 61 } else { 62 if v, ok := d.GetOk("reference_name"); ok { 63 creationToken = resource.PrefixedUniqueId(fmt.Sprintf("%s-", v.(string))) 64 log.Printf("[WARN] Using deprecated `reference_name' attribute.") 65 } else { 66 creationToken = resource.UniqueId() 67 } 68 } 69 70 createOpts := &efs.CreateFileSystemInput{ 71 CreationToken: aws.String(creationToken), 72 } 73 74 if v, ok := d.GetOk("performance_mode"); ok { 75 createOpts.PerformanceMode = aws.String(v.(string)) 76 } 77 78 log.Printf("[DEBUG] EFS file system create options: %#v", *createOpts) 79 fs, err := conn.CreateFileSystem(createOpts) 80 if err != nil { 81 return fmt.Errorf("Error creating EFS file system: %s", err) 82 } 83 84 d.SetId(*fs.FileSystemId) 85 log.Printf("[INFO] EFS file system ID: %s", d.Id()) 86 87 stateConf := &resource.StateChangeConf{ 88 Pending: []string{"creating"}, 89 Target: []string{"available"}, 90 Refresh: func() (interface{}, string, error) { 91 resp, err := conn.DescribeFileSystems(&efs.DescribeFileSystemsInput{ 92 FileSystemId: aws.String(d.Id()), 93 }) 94 if err != nil { 95 return nil, "error", err 96 } 97 98 if len(resp.FileSystems) < 1 { 99 return nil, "not-found", fmt.Errorf("EFS file system %q not found", d.Id()) 100 } 101 102 fs := resp.FileSystems[0] 103 log.Printf("[DEBUG] current status of %q: %q", *fs.FileSystemId, *fs.LifeCycleState) 104 return fs, *fs.LifeCycleState, nil 105 }, 106 Timeout: 10 * time.Minute, 107 Delay: 2 * time.Second, 108 MinTimeout: 3 * time.Second, 109 } 110 111 _, err = stateConf.WaitForState() 112 if err != nil { 113 return fmt.Errorf("Error waiting for EFS file system (%q) to create: %q", 114 d.Id(), err.Error()) 115 } 116 log.Printf("[DEBUG] EFS file system %q created.", d.Id()) 117 118 return resourceAwsEfsFileSystemUpdate(d, meta) 119 } 120 121 func resourceAwsEfsFileSystemUpdate(d *schema.ResourceData, meta interface{}) error { 122 conn := meta.(*AWSClient).efsconn 123 err := setTagsEFS(conn, d) 124 if err != nil { 125 return fmt.Errorf("Error setting EC2 tags for EFS file system (%q): %q", 126 d.Id(), err.Error()) 127 } 128 129 return resourceAwsEfsFileSystemRead(d, meta) 130 } 131 132 func resourceAwsEfsFileSystemRead(d *schema.ResourceData, meta interface{}) error { 133 conn := meta.(*AWSClient).efsconn 134 135 resp, err := conn.DescribeFileSystems(&efs.DescribeFileSystemsInput{ 136 FileSystemId: aws.String(d.Id()), 137 }) 138 if err != nil { 139 if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "FileSystemNotFound" { 140 log.Printf("[WARN] EFS File System (%s) not found, error code (404)", d.Id()) 141 d.SetId("") 142 return nil 143 } 144 return err 145 } 146 if len(resp.FileSystems) < 1 { 147 return fmt.Errorf("EFS file system %q not found", d.Id()) 148 } 149 150 tagsResp, err := conn.DescribeTags(&efs.DescribeTagsInput{ 151 FileSystemId: aws.String(d.Id()), 152 }) 153 if err != nil { 154 return fmt.Errorf("Error retrieving EC2 tags for EFS file system (%q): %q", 155 d.Id(), err.Error()) 156 } 157 158 d.Set("tags", tagsToMapEFS(tagsResp.Tags)) 159 160 return nil 161 } 162 163 func resourceAwsEfsFileSystemDelete(d *schema.ResourceData, meta interface{}) error { 164 conn := meta.(*AWSClient).efsconn 165 166 log.Printf("[DEBUG] Deleting EFS file system: %s", d.Id()) 167 _, err := conn.DeleteFileSystem(&efs.DeleteFileSystemInput{ 168 FileSystemId: aws.String(d.Id()), 169 }) 170 stateConf := &resource.StateChangeConf{ 171 Pending: []string{"available", "deleting"}, 172 Target: []string{}, 173 Refresh: func() (interface{}, string, error) { 174 resp, err := conn.DescribeFileSystems(&efs.DescribeFileSystemsInput{ 175 FileSystemId: aws.String(d.Id()), 176 }) 177 if err != nil { 178 efsErr, ok := err.(awserr.Error) 179 if ok && efsErr.Code() == "FileSystemNotFound" { 180 return nil, "", nil 181 } 182 return nil, "error", err 183 } 184 185 if len(resp.FileSystems) < 1 { 186 return nil, "", nil 187 } 188 189 fs := resp.FileSystems[0] 190 log.Printf("[DEBUG] current status of %q: %q", *fs.FileSystemId, *fs.LifeCycleState) 191 return fs, *fs.LifeCycleState, nil 192 }, 193 Timeout: 10 * time.Minute, 194 Delay: 2 * time.Second, 195 MinTimeout: 3 * time.Second, 196 } 197 198 _, err = stateConf.WaitForState() 199 if err != nil { 200 return fmt.Errorf("Error waiting for EFS file system (%q) to delete: %q", 201 d.Id(), err.Error()) 202 } 203 204 log.Printf("[DEBUG] EFS file system %q deleted.", d.Id()) 205 206 return nil 207 } 208 209 func validateReferenceName(v interface{}, k string) (ws []string, errors []error) { 210 value := v.(string) 211 creationToken := resource.PrefixedUniqueId(fmt.Sprintf("%s-", value)) 212 if len(creationToken) > 64 { 213 errors = append(errors, fmt.Errorf( 214 "%q cannot take the Creation Token over the limit of 64 characters: %q", k, value)) 215 } 216 return 217 } 218 219 func validatePerformanceModeType(v interface{}, k string) (ws []string, errors []error) { 220 value := v.(string) 221 if value != "generalPurpose" && value != "maxIO" { 222 errors = append(errors, fmt.Errorf( 223 "%q contains an invalid Performance Mode %q. Valid modes are either %q or %q", 224 k, value, "generalPurpose", "maxIO")) 225 } 226 return 227 }