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  }