github.com/mohanarpit/terraform@v0.6.16-0.20160909104007-291f29853544/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  				ForceNew:     true,
    31  				ValidateFunc: validateMaxLength(64),
    32  			},
    33  
    34  			"reference_name": {
    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": {
    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 hasEmptyFileSystems(resp) {
    99  				return nil, "not-found", fmt.Errorf("EFS file system %q could not be 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: %s",
   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): %s",
   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) could not be found.", d.Id())
   141  			d.SetId("")
   142  			return nil
   143  		}
   144  		return err
   145  	}
   146  
   147  	if hasEmptyFileSystems(resp) {
   148  		return fmt.Errorf("EFS file system %q could not be found.", d.Id())
   149  	}
   150  
   151  	tagsResp, err := conn.DescribeTags(&efs.DescribeTagsInput{
   152  		FileSystemId: aws.String(d.Id()),
   153  	})
   154  	if err != nil {
   155  		return fmt.Errorf("Error retrieving EC2 tags for EFS file system (%q): %s",
   156  			d.Id(), err.Error())
   157  	}
   158  
   159  	err = d.Set("tags", tagsToMapEFS(tagsResp.Tags))
   160  	if err != nil {
   161  		return err
   162  	}
   163  
   164  	return nil
   165  }
   166  
   167  func resourceAwsEfsFileSystemDelete(d *schema.ResourceData, meta interface{}) error {
   168  	conn := meta.(*AWSClient).efsconn
   169  
   170  	log.Printf("[DEBUG] Deleting EFS file system: %s", d.Id())
   171  	_, err := conn.DeleteFileSystem(&efs.DeleteFileSystemInput{
   172  		FileSystemId: aws.String(d.Id()),
   173  	})
   174  	stateConf := &resource.StateChangeConf{
   175  		Pending: []string{"available", "deleting"},
   176  		Target:  []string{},
   177  		Refresh: func() (interface{}, string, error) {
   178  			resp, err := conn.DescribeFileSystems(&efs.DescribeFileSystemsInput{
   179  				FileSystemId: aws.String(d.Id()),
   180  			})
   181  			if err != nil {
   182  				efsErr, ok := err.(awserr.Error)
   183  				if ok && efsErr.Code() == "FileSystemNotFound" {
   184  					return nil, "", nil
   185  				}
   186  				return nil, "error", err
   187  			}
   188  
   189  			if hasEmptyFileSystems(resp) {
   190  				return nil, "", nil
   191  			}
   192  
   193  			fs := resp.FileSystems[0]
   194  			log.Printf("[DEBUG] current status of %q: %q", *fs.FileSystemId, *fs.LifeCycleState)
   195  			return fs, *fs.LifeCycleState, nil
   196  		},
   197  		Timeout:    10 * time.Minute,
   198  		Delay:      2 * time.Second,
   199  		MinTimeout: 3 * time.Second,
   200  	}
   201  
   202  	_, err = stateConf.WaitForState()
   203  	if err != nil {
   204  		return fmt.Errorf("Error waiting for EFS file system (%q) to delete: %s",
   205  			d.Id(), err.Error())
   206  	}
   207  
   208  	log.Printf("[DEBUG] EFS file system %q deleted.", d.Id())
   209  
   210  	return nil
   211  }
   212  
   213  func validateReferenceName(v interface{}, k string) (ws []string, errors []error) {
   214  	value := v.(string)
   215  	creationToken := resource.PrefixedUniqueId(fmt.Sprintf("%s-", value))
   216  	if len(creationToken) > 64 {
   217  		errors = append(errors, fmt.Errorf(
   218  			"%q cannot take the Creation Token over the limit of 64 characters: %q", k, value))
   219  	}
   220  	return
   221  }
   222  
   223  func validatePerformanceModeType(v interface{}, k string) (ws []string, errors []error) {
   224  	value := v.(string)
   225  	if value != efs.PerformanceModeGeneralPurpose && value != efs.PerformanceModeMaxIo {
   226  		errors = append(errors, fmt.Errorf(
   227  			"%q contains an invalid Performance Mode %q. Valid modes are either %q or %q.",
   228  			k, value, efs.PerformanceModeGeneralPurpose, efs.PerformanceModeMaxIo))
   229  	}
   230  	return
   231  }
   232  
   233  func hasEmptyFileSystems(fs *efs.DescribeFileSystemsOutput) bool {
   234  	if fs != nil && len(fs.FileSystems) > 0 {
   235  		return false
   236  	}
   237  	return true
   238  }