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 }