github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_lightsail_key_pair.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/lightsail"
    11  	"github.com/hashicorp/terraform/helper/encryption"
    12  	"github.com/hashicorp/terraform/helper/resource"
    13  	"github.com/hashicorp/terraform/helper/schema"
    14  )
    15  
    16  func resourceAwsLightsailKeyPair() *schema.Resource {
    17  	return &schema.Resource{
    18  		Create: resourceAwsLightsailKeyPairCreate,
    19  		Read:   resourceAwsLightsailKeyPairRead,
    20  		Delete: resourceAwsLightsailKeyPairDelete,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"name": {
    24  				Type:          schema.TypeString,
    25  				Optional:      true,
    26  				Computed:      true,
    27  				ForceNew:      true,
    28  				ConflictsWith: []string{"name_prefix"},
    29  			},
    30  			"name_prefix": {
    31  				Type:     schema.TypeString,
    32  				Optional: true,
    33  				ForceNew: true,
    34  			},
    35  
    36  			// optional fields
    37  			"pgp_key": {
    38  				Type:     schema.TypeString,
    39  				Optional: true,
    40  				ForceNew: true,
    41  			},
    42  
    43  			// additional info returned from the API
    44  			"arn": {
    45  				Type:     schema.TypeString,
    46  				Computed: true,
    47  			},
    48  
    49  			// fields returned from CreateKey
    50  			"fingerprint": {
    51  				Type:     schema.TypeString,
    52  				Computed: true,
    53  			},
    54  			"public_key": {
    55  				Type:     schema.TypeString,
    56  				Computed: true,
    57  				Optional: true,
    58  				ForceNew: true,
    59  			},
    60  			"private_key": {
    61  				Type:     schema.TypeString,
    62  				Computed: true,
    63  			},
    64  
    65  			// encrypted fields if pgp_key is given
    66  			"encrypted_fingerprint": {
    67  				Type:     schema.TypeString,
    68  				Computed: true,
    69  			},
    70  			"encrypted_private_key": {
    71  				Type:     schema.TypeString,
    72  				Computed: true,
    73  			},
    74  		},
    75  	}
    76  }
    77  
    78  func resourceAwsLightsailKeyPairCreate(d *schema.ResourceData, meta interface{}) error {
    79  	conn := meta.(*AWSClient).lightsailconn
    80  
    81  	var kName string
    82  	if v, ok := d.GetOk("name"); ok {
    83  		kName = v.(string)
    84  	} else if v, ok := d.GetOk("name_prefix"); ok {
    85  		kName = resource.PrefixedUniqueId(v.(string))
    86  	} else {
    87  		kName = resource.UniqueId()
    88  	}
    89  
    90  	var pubKey string
    91  	var op *lightsail.Operation
    92  	if pubKeyInterface, ok := d.GetOk("public_key"); ok {
    93  		pubKey = pubKeyInterface.(string)
    94  	}
    95  
    96  	if pubKey == "" {
    97  		// creating new key
    98  		resp, err := conn.CreateKeyPair(&lightsail.CreateKeyPairInput{
    99  			KeyPairName: aws.String(kName),
   100  		})
   101  		if err != nil {
   102  			return err
   103  		}
   104  		if resp.Operation == nil {
   105  			return fmt.Errorf("[ERR] No operation found for CreateKeyPair response")
   106  		}
   107  		if resp.KeyPair == nil {
   108  			return fmt.Errorf("[ERR] No KeyPair information found for CreateKeyPair response")
   109  		}
   110  		d.SetId(kName)
   111  
   112  		// private_key and public_key are only available in the response from
   113  		// CreateKey pair. Here we set the public_key, and encrypt the private_key
   114  		// if a pgp_key is given, else we store the private_key in state
   115  		d.Set("public_key", resp.PublicKeyBase64)
   116  
   117  		// encrypt private key if pgp_key is given
   118  		pgpKey, err := encryption.RetrieveGPGKey(d.Get("pgp_key").(string))
   119  		if err != nil {
   120  			return err
   121  		}
   122  		if pgpKey != "" {
   123  			fingerprint, encrypted, err := encryption.EncryptValue(pgpKey, *resp.PrivateKeyBase64, "Lightsail Private Key")
   124  			if err != nil {
   125  				return err
   126  			}
   127  
   128  			d.Set("encrypted_fingerprint", fingerprint)
   129  			d.Set("encrypted_private_key", encrypted)
   130  		} else {
   131  			d.Set("private_key", resp.PrivateKeyBase64)
   132  		}
   133  
   134  		op = resp.Operation
   135  	} else {
   136  		// importing key
   137  		resp, err := conn.ImportKeyPair(&lightsail.ImportKeyPairInput{
   138  			KeyPairName:     aws.String(kName),
   139  			PublicKeyBase64: aws.String(pubKey),
   140  		})
   141  
   142  		if err != nil {
   143  			log.Printf("[ERR] Error importing key: %s", err)
   144  			return err
   145  		}
   146  		d.SetId(kName)
   147  
   148  		op = resp.Operation
   149  	}
   150  
   151  	stateConf := &resource.StateChangeConf{
   152  		Pending:    []string{"Started"},
   153  		Target:     []string{"Completed", "Succeeded"},
   154  		Refresh:    resourceAwsLightsailOperationRefreshFunc(op.Id, meta),
   155  		Timeout:    10 * time.Minute,
   156  		Delay:      5 * time.Second,
   157  		MinTimeout: 3 * time.Second,
   158  	}
   159  
   160  	_, err := stateConf.WaitForState()
   161  	if err != nil {
   162  		// We don't return an error here because the Create call succeded
   163  		log.Printf("[ERR] Error waiting for KeyPair (%s) to become ready: %s", d.Id(), err)
   164  	}
   165  
   166  	return resourceAwsLightsailKeyPairRead(d, meta)
   167  }
   168  
   169  func resourceAwsLightsailKeyPairRead(d *schema.ResourceData, meta interface{}) error {
   170  	conn := meta.(*AWSClient).lightsailconn
   171  
   172  	resp, err := conn.GetKeyPair(&lightsail.GetKeyPairInput{
   173  		KeyPairName: aws.String(d.Id()),
   174  	})
   175  
   176  	if err != nil {
   177  		log.Printf("[WARN] Error getting KeyPair (%s): %s", d.Id(), err)
   178  		// check for known not found error
   179  		if awsErr, ok := err.(awserr.Error); ok {
   180  			if awsErr.Code() == "NotFoundException" {
   181  				log.Printf("[WARN] Lightsail KeyPair (%s) not found, removing from state", d.Id())
   182  				d.SetId("")
   183  				return nil
   184  			}
   185  		}
   186  		return err
   187  	}
   188  
   189  	d.Set("arn", resp.KeyPair.Arn)
   190  	d.Set("name", resp.KeyPair.Name)
   191  	d.Set("fingerprint", resp.KeyPair.Fingerprint)
   192  
   193  	return nil
   194  }
   195  
   196  func resourceAwsLightsailKeyPairDelete(d *schema.ResourceData, meta interface{}) error {
   197  	conn := meta.(*AWSClient).lightsailconn
   198  	resp, err := conn.DeleteKeyPair(&lightsail.DeleteKeyPairInput{
   199  		KeyPairName: aws.String(d.Id()),
   200  	})
   201  
   202  	if err != nil {
   203  		return err
   204  	}
   205  
   206  	op := resp.Operation
   207  	stateConf := &resource.StateChangeConf{
   208  		Pending:    []string{"Started"},
   209  		Target:     []string{"Completed", "Succeeded"},
   210  		Refresh:    resourceAwsLightsailOperationRefreshFunc(op.Id, meta),
   211  		Timeout:    10 * time.Minute,
   212  		Delay:      5 * time.Second,
   213  		MinTimeout: 3 * time.Second,
   214  	}
   215  
   216  	_, err = stateConf.WaitForState()
   217  	if err != nil {
   218  		return fmt.Errorf(
   219  			"Error waiting for KeyPair (%s) to become destroyed: %s",
   220  			d.Id(), err)
   221  	}
   222  
   223  	d.SetId("")
   224  	return nil
   225  }