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