provider/aws: New Resource aws_ebs_snapshot (#10017)
* provider/aws: Add ability to create aws_ebs_snapshot ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSEBSSnapshot_' ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2016/11/10 14:18:36 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSEBSSnapshot_ -timeout 120m === RUN TestAccAWSEBSSnapshot_basic --- PASS: TestAccAWSEBSSnapshot_basic (31.56s) === RUN TestAccAWSEBSSnapshot_withDescription --- PASS: TestAccAWSEBSSnapshot_withDescription (189.35s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws220.928s ``` * docs/aws: Addition of the docs for aws_ebs_snapshot resource * provider/aws: Creation of shared schema funcs for common AWS data source patterns * provider/aws: Create aws_ebs_snapshot datasource Fixes #8828 This data source will use a number of filters, owner_ids, snapshot_ids and restorable_by_user_ids in order to find the correct snapshot. The data source has no real use case for most_recent and will error on no snapshots found or greater than 1 snapshot found ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSEbsSnapshotDataSource_' ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2016/11/10 14:34:33 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSEbsSnapshotDataSource_ -timeout 120m === RUN TestAccAWSEbsSnapshotDataSource_basic --- PASS: TestAccAWSEbsSnapshotDataSource_basic (192.66s) === RUN TestAccAWSEbsSnapshotDataSource_multipleFilters --- PASS: TestAccAWSEbsSnapshotDataSource_multipleFilters (33.84s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws226.522s ``` * docs/aws: Addition of docs for the aws_ebs_snapshot data source Adds the new resource `aws_ebs_snapshot`
This commit is contained in:
parent
a79092b86c
commit
7fde952d02
|
@ -8,7 +8,6 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
"github.com/hashicorp/terraform/helper/hashcode"
|
"github.com/hashicorp/terraform/helper/hashcode"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
@ -19,31 +18,13 @@ func dataSourceAwsAmi() *schema.Resource {
|
||||||
Read: dataSourceAwsAmiRead,
|
Read: dataSourceAwsAmiRead,
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
|
"filter": dataSourceFiltersSchema(),
|
||||||
"executable_users": {
|
"executable_users": {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
},
|
},
|
||||||
"filter": {
|
|
||||||
Type: schema.TypeSet,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"values": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Required: true,
|
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"name_regex": {
|
"name_regex": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
@ -186,23 +167,7 @@ func dataSourceAwsAmi() *schema.Resource {
|
||||||
Type: schema.TypeMap,
|
Type: schema.TypeMap,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
},
|
},
|
||||||
"tags": {
|
"tags": dataSourceTagsSchema(),
|
||||||
Type: schema.TypeSet,
|
|
||||||
Computed: true,
|
|
||||||
Set: amiTagsHash,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"key": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,7 +190,7 @@ func dataSourceAwsAmiRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
params.ExecutableUsers = expandStringList(executableUsers.([]interface{}))
|
params.ExecutableUsers = expandStringList(executableUsers.([]interface{}))
|
||||||
}
|
}
|
||||||
if filtersOk {
|
if filtersOk {
|
||||||
params.Filters = buildAmiFilters(filters.(*schema.Set))
|
params.Filters = buildAwsDataSourceFilters(filters.(*schema.Set))
|
||||||
}
|
}
|
||||||
if ownersOk {
|
if ownersOk {
|
||||||
params.Owners = expandStringList(owners.([]interface{}))
|
params.Owners = expandStringList(owners.([]interface{}))
|
||||||
|
@ -280,23 +245,6 @@ func dataSourceAwsAmiRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
return amiDescriptionAttributes(d, image)
|
return amiDescriptionAttributes(d, image)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a slice of AMI filter options from the filters provided.
|
|
||||||
func buildAmiFilters(set *schema.Set) []*ec2.Filter {
|
|
||||||
var filters []*ec2.Filter
|
|
||||||
for _, v := range set.List() {
|
|
||||||
m := v.(map[string]interface{})
|
|
||||||
var filterValues []*string
|
|
||||||
for _, e := range m["values"].([]interface{}) {
|
|
||||||
filterValues = append(filterValues, aws.String(e.(string)))
|
|
||||||
}
|
|
||||||
filters = append(filters, &ec2.Filter{
|
|
||||||
Name: aws.String(m["name"].(string)),
|
|
||||||
Values: filterValues,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return filters
|
|
||||||
}
|
|
||||||
|
|
||||||
type imageSort []*ec2.Image
|
type imageSort []*ec2.Image
|
||||||
|
|
||||||
func (a imageSort) Len() int { return len(a) }
|
func (a imageSort) Len() int { return len(a) }
|
||||||
|
@ -361,7 +309,7 @@ func amiDescriptionAttributes(d *schema.ResourceData, image *ec2.Image) error {
|
||||||
if err := d.Set("state_reason", amiStateReason(image.StateReason)); err != nil {
|
if err := d.Set("state_reason", amiStateReason(image.StateReason)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := d.Set("tags", amiTags(image.Tags)); err != nil {
|
if err := d.Set("tags", dataSourceTags(image.Tags)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -433,21 +381,6 @@ func amiStateReason(m *ec2.StateReason) map[string]interface{} {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a set of tags.
|
|
||||||
func amiTags(m []*ec2.Tag) *schema.Set {
|
|
||||||
s := &schema.Set{
|
|
||||||
F: amiTagsHash,
|
|
||||||
}
|
|
||||||
for _, v := range m {
|
|
||||||
tag := map[string]interface{}{
|
|
||||||
"key": *v.Key,
|
|
||||||
"value": *v.Value,
|
|
||||||
}
|
|
||||||
s.Add(tag)
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a hash for the set hash function used by the block_device_mappings
|
// Generates a hash for the set hash function used by the block_device_mappings
|
||||||
// attribute.
|
// attribute.
|
||||||
func amiBlockDeviceMappingHash(v interface{}) int {
|
func amiBlockDeviceMappingHash(v interface{}) int {
|
||||||
|
@ -488,17 +421,6 @@ func amiProductCodesHash(v interface{}) int {
|
||||||
return hashcode.String(buf.String())
|
return hashcode.String(buf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates a hash for the set hash function used by the tags
|
|
||||||
// attribute.
|
|
||||||
func amiTagsHash(v interface{}) int {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
m := v.(map[string]interface{})
|
|
||||||
// All keys added in alphabetical order.
|
|
||||||
buf.WriteString(fmt.Sprintf("%s-", m["key"].(string)))
|
|
||||||
buf.WriteString(fmt.Sprintf("%s-", m["value"].(string)))
|
|
||||||
return hashcode.String(buf.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateNameRegex(v interface{}, k string) (ws []string, errors []error) {
|
func validateNameRegex(v interface{}, k string) (ws []string, errors []error) {
|
||||||
value := v.(string)
|
value := v.(string)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
|
"github.com/hashicorp/terraform/helper/hashcode"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func dataSourceTagsHash(v interface{}) int {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
m := v.(map[string]interface{})
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["key"].(string)))
|
||||||
|
buf.WriteString(fmt.Sprintf("%s-", m["value"].(string)))
|
||||||
|
return hashcode.String(buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceTags(m []*ec2.Tag) *schema.Set {
|
||||||
|
s := &schema.Set{
|
||||||
|
F: dataSourceTagsHash,
|
||||||
|
}
|
||||||
|
for _, v := range m {
|
||||||
|
tag := map[string]interface{}{
|
||||||
|
"key": *v.Key,
|
||||||
|
"value": *v.Value,
|
||||||
|
}
|
||||||
|
s.Add(tag)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildAwsDataSourceFilters(set *schema.Set) []*ec2.Filter {
|
||||||
|
var filters []*ec2.Filter
|
||||||
|
for _, v := range set.List() {
|
||||||
|
m := v.(map[string]interface{})
|
||||||
|
var filterValues []*string
|
||||||
|
for _, e := range m["values"].([]interface{}) {
|
||||||
|
filterValues = append(filterValues, aws.String(e.(string)))
|
||||||
|
}
|
||||||
|
filters = append(filters, &ec2.Filter{
|
||||||
|
Name: aws.String(m["name"].(string)),
|
||||||
|
Values: filterValues,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return filters
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceFiltersSchema() *schema.Schema {
|
||||||
|
return &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"values": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Required: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceTagsSchema() *schema.Schema {
|
||||||
|
return &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Computed: true,
|
||||||
|
Set: dataSourceTagsHash,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"key": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func dataSourceAwsEbsSnapshot() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Read: dataSourceAwsEbsSnapshotRead,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
//selection criteria
|
||||||
|
"filter": dataSourceFiltersSchema(),
|
||||||
|
|
||||||
|
"owners": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
"snapshot_ids": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
"restorable_by_user_ids": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
//Computed values returned
|
||||||
|
"snapshot_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"volume_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"owner_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"owner_alias": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"encrypted": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"volume_size": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"kms_key_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"data_encryption_key_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"tags": dataSourceTagsSchema(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAwsEbsSnapshotRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
restorableUsers, restorableUsersOk := d.GetOk("restorable_by_user_ids")
|
||||||
|
filters, filtersOk := d.GetOk("filter")
|
||||||
|
snapshotIds, snapshotIdsOk := d.GetOk("snapshot_ids")
|
||||||
|
owners, ownersOk := d.GetOk("owners")
|
||||||
|
|
||||||
|
if restorableUsers == false && filtersOk == false && snapshotIds == false && ownersOk == false {
|
||||||
|
return fmt.Errorf("One of snapshot_ids, filters, restorable_by_user_ids, or owners must be assigned")
|
||||||
|
}
|
||||||
|
|
||||||
|
params := &ec2.DescribeSnapshotsInput{}
|
||||||
|
if restorableUsersOk {
|
||||||
|
params.RestorableByUserIds = expandStringList(restorableUsers.([]interface{}))
|
||||||
|
}
|
||||||
|
if filtersOk {
|
||||||
|
params.Filters = buildAwsDataSourceFilters(filters.(*schema.Set))
|
||||||
|
}
|
||||||
|
if ownersOk {
|
||||||
|
params.OwnerIds = expandStringList(owners.([]interface{}))
|
||||||
|
}
|
||||||
|
if snapshotIdsOk {
|
||||||
|
params.SnapshotIds = expandStringList(snapshotIds.([]interface{}))
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := conn.DescribeSnapshots(params)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(resp.Snapshots) < 1 {
|
||||||
|
return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(resp.Snapshots) > 1 {
|
||||||
|
return fmt.Errorf("Your query returned more than one result. Please try a more specific search criteria.")
|
||||||
|
}
|
||||||
|
|
||||||
|
//Single Snapshot found so set to state
|
||||||
|
return snapshotDescriptionAttributes(d, resp.Snapshots[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func snapshotDescriptionAttributes(d *schema.ResourceData, snapshot *ec2.Snapshot) error {
|
||||||
|
d.SetId(*snapshot.SnapshotId)
|
||||||
|
d.Set("snapshot_id", snapshot.SnapshotId)
|
||||||
|
d.Set("volume_id", snapshot.VolumeId)
|
||||||
|
d.Set("data_encryption_key_id", snapshot.DataEncryptionKeyId)
|
||||||
|
d.Set("description", snapshot.Description)
|
||||||
|
d.Set("encrypted", snapshot.Encrypted)
|
||||||
|
d.Set("kms_key_id", snapshot.KmsKeyId)
|
||||||
|
d.Set("volume_size", snapshot.VolumeSize)
|
||||||
|
d.Set("state", snapshot.State)
|
||||||
|
d.Set("owner_id", snapshot.OwnerId)
|
||||||
|
d.Set("owner_alias", snapshot.OwnerAlias)
|
||||||
|
|
||||||
|
if err := d.Set("tags", dataSourceTags(snapshot.Tags)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccAWSEbsSnapshotDataSource_basic(t *testing.T) {
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccCheckAwsEbsSnapshotDataSourceConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAwsEbsSnapshotDataSourceID("data.aws_ebs_snapshot.snapshot"),
|
||||||
|
resource.TestCheckResourceAttr("data.aws_ebs_snapshot.snapshot", "volume_size", "40"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSEbsSnapshotDataSource_multipleFilters(t *testing.T) {
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccCheckAwsEbsSnapshotDataSourceConfigWithMultipleFilters,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAwsEbsSnapshotDataSourceID("data.aws_ebs_snapshot.snapshot"),
|
||||||
|
resource.TestCheckResourceAttr("data.aws_ebs_snapshot.snapshot", "volume_size", "10"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAwsEbsSnapshotDataSourceID(n string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Can't find Volume data source: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("Snapshot data source ID not set")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccCheckAwsEbsSnapshotDataSourceConfig = `
|
||||||
|
resource "aws_ebs_volume" "example" {
|
||||||
|
availability_zone = "us-west-2a"
|
||||||
|
type = "gp2"
|
||||||
|
size = 40
|
||||||
|
tags {
|
||||||
|
Name = "External Volume"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_ebs_snapshot" "snapshot" {
|
||||||
|
volume_id = "${aws_ebs_volume.example.id}"
|
||||||
|
}
|
||||||
|
|
||||||
|
data "aws_ebs_snapshot" "snapshot" {
|
||||||
|
snapshot_ids = ["${aws_ebs_snapshot.snapshot.id}"]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccCheckAwsEbsSnapshotDataSourceConfigWithMultipleFilters = `
|
||||||
|
resource "aws_ebs_volume" "external1" {
|
||||||
|
availability_zone = "us-west-2a"
|
||||||
|
type = "gp2"
|
||||||
|
size = 10
|
||||||
|
tags {
|
||||||
|
Name = "External Volume 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_ebs_snapshot" "snapshot" {
|
||||||
|
volume_id = "${aws_ebs_volume.external1.id}"
|
||||||
|
}
|
||||||
|
|
||||||
|
data "aws_ebs_snapshot" "snapshot" {
|
||||||
|
snapshot_ids = ["${aws_ebs_snapshot.snapshot.id}"]
|
||||||
|
filter {
|
||||||
|
name = "volume-size"
|
||||||
|
values = ["10"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
|
@ -1,15 +1,12 @@
|
||||||
package aws
|
package aws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/hashicorp/terraform/helper/hashcode"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,25 +15,7 @@ func dataSourceAwsEbsVolume() *schema.Resource {
|
||||||
Read: dataSourceAwsEbsVolumeRead,
|
Read: dataSourceAwsEbsVolumeRead,
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"filter": {
|
"filter": dataSourceFiltersSchema(),
|
||||||
Type: schema.TypeSet,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"values": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Required: true,
|
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"most_recent": {
|
"most_recent": {
|
||||||
Type: schema.TypeBool,
|
Type: schema.TypeBool,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
@ -75,23 +54,7 @@ func dataSourceAwsEbsVolume() *schema.Resource {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
},
|
},
|
||||||
"tags": {
|
"tags": dataSourceTagsSchema(),
|
||||||
Type: schema.TypeSet,
|
|
||||||
Computed: true,
|
|
||||||
Set: volumeTagsHash,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"key": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +66,7 @@ func dataSourceAwsEbsVolumeRead(d *schema.ResourceData, meta interface{}) error
|
||||||
|
|
||||||
params := &ec2.DescribeVolumesInput{}
|
params := &ec2.DescribeVolumesInput{}
|
||||||
if filtersOk {
|
if filtersOk {
|
||||||
params.Filters = buildVolumeFilters(filters.(*schema.Set))
|
params.Filters = buildAwsDataSourceFilters(filters.(*schema.Set))
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := conn.DescribeVolumes(params)
|
resp, err := conn.DescribeVolumes(params)
|
||||||
|
@ -138,22 +101,6 @@ func dataSourceAwsEbsVolumeRead(d *schema.ResourceData, meta interface{}) error
|
||||||
return volumeDescriptionAttributes(d, volume)
|
return volumeDescriptionAttributes(d, volume)
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildVolumeFilters(set *schema.Set) []*ec2.Filter {
|
|
||||||
var filters []*ec2.Filter
|
|
||||||
for _, v := range set.List() {
|
|
||||||
m := v.(map[string]interface{})
|
|
||||||
var filterValues []*string
|
|
||||||
for _, e := range m["values"].([]interface{}) {
|
|
||||||
filterValues = append(filterValues, aws.String(e.(string)))
|
|
||||||
}
|
|
||||||
filters = append(filters, &ec2.Filter{
|
|
||||||
Name: aws.String(m["name"].(string)),
|
|
||||||
Values: filterValues,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return filters
|
|
||||||
}
|
|
||||||
|
|
||||||
type volumeSort []*ec2.Volume
|
type volumeSort []*ec2.Volume
|
||||||
|
|
||||||
func (a volumeSort) Len() int { return len(a) }
|
func (a volumeSort) Len() int { return len(a) }
|
||||||
|
@ -181,31 +128,9 @@ func volumeDescriptionAttributes(d *schema.ResourceData, volume *ec2.Volume) err
|
||||||
d.Set("snapshot_id", volume.SnapshotId)
|
d.Set("snapshot_id", volume.SnapshotId)
|
||||||
d.Set("volume_type", volume.VolumeType)
|
d.Set("volume_type", volume.VolumeType)
|
||||||
|
|
||||||
if err := d.Set("tags", volumeTags(volume.Tags)); err != nil {
|
if err := d.Set("tags", dataSourceTags(volume.Tags)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func volumeTags(m []*ec2.Tag) *schema.Set {
|
|
||||||
s := &schema.Set{
|
|
||||||
F: volumeTagsHash,
|
|
||||||
}
|
|
||||||
for _, v := range m {
|
|
||||||
tag := map[string]interface{}{
|
|
||||||
"key": *v.Key,
|
|
||||||
"value": *v.Value,
|
|
||||||
}
|
|
||||||
s.Add(tag)
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func volumeTagsHash(v interface{}) int {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
m := v.(map[string]interface{})
|
|
||||||
buf.WriteString(fmt.Sprintf("%s-", m["key"].(string)))
|
|
||||||
buf.WriteString(fmt.Sprintf("%s-", m["value"].(string)))
|
|
||||||
return hashcode.String(buf.String())
|
|
||||||
}
|
|
||||||
|
|
|
@ -152,6 +152,7 @@ func Provider() terraform.ResourceProvider {
|
||||||
"aws_billing_service_account": dataSourceAwsBillingServiceAccount(),
|
"aws_billing_service_account": dataSourceAwsBillingServiceAccount(),
|
||||||
"aws_caller_identity": dataSourceAwsCallerIdentity(),
|
"aws_caller_identity": dataSourceAwsCallerIdentity(),
|
||||||
"aws_cloudformation_stack": dataSourceAwsCloudFormationStack(),
|
"aws_cloudformation_stack": dataSourceAwsCloudFormationStack(),
|
||||||
|
"aws_ebs_snapshot": dataSourceAwsEbsSnapshot(),
|
||||||
"aws_ebs_volume": dataSourceAwsEbsVolume(),
|
"aws_ebs_volume": dataSourceAwsEbsVolume(),
|
||||||
"aws_ecs_container_definition": dataSourceAwsEcsContainerDefinition(),
|
"aws_ecs_container_definition": dataSourceAwsEcsContainerDefinition(),
|
||||||
"aws_elb_service_account": dataSourceAwsElbServiceAccount(),
|
"aws_elb_service_account": dataSourceAwsElbServiceAccount(),
|
||||||
|
@ -223,6 +224,7 @@ func Provider() terraform.ResourceProvider {
|
||||||
"aws_db_subnet_group": resourceAwsDbSubnetGroup(),
|
"aws_db_subnet_group": resourceAwsDbSubnetGroup(),
|
||||||
"aws_directory_service_directory": resourceAwsDirectoryServiceDirectory(),
|
"aws_directory_service_directory": resourceAwsDirectoryServiceDirectory(),
|
||||||
"aws_dynamodb_table": resourceAwsDynamoDbTable(),
|
"aws_dynamodb_table": resourceAwsDynamoDbTable(),
|
||||||
|
"aws_ebs_snapshot": resourceAwsEbsSnapshot(),
|
||||||
"aws_ebs_volume": resourceAwsEbsVolume(),
|
"aws_ebs_volume": resourceAwsEbsVolume(),
|
||||||
"aws_ecr_repository": resourceAwsEcrRepository(),
|
"aws_ecr_repository": resourceAwsEcrRepository(),
|
||||||
"aws_ecr_repository_policy": resourceAwsEcrRepositoryPolicy(),
|
"aws_ecr_repository_policy": resourceAwsEcrRepositoryPolicy(),
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceAwsEbsSnapshot() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceAwsEbsSnapshotCreate,
|
||||||
|
Read: resourceAwsEbsSnapshotRead,
|
||||||
|
Delete: resourceAwsEbsSnapshotDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"volume_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"owner_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"owner_alias": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"encrypted": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"volume_size": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"kms_key_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"data_encryption_key_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsEbsSnapshotCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
request := &ec2.CreateSnapshotInput{
|
||||||
|
VolumeId: aws.String(d.Get("volume_id").(string)),
|
||||||
|
}
|
||||||
|
if v, ok := d.GetOk("description"); ok {
|
||||||
|
request.Description = aws.String(v.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := conn.CreateSnapshot(request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(*res.SnapshotId)
|
||||||
|
|
||||||
|
err = resourceAwsEbsSnapshotWaitForAvailable(d.Id(), conn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceAwsEbsSnapshotRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsEbsSnapshotRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
req := &ec2.DescribeSnapshotsInput{
|
||||||
|
SnapshotIds: []*string{aws.String(d.Id())},
|
||||||
|
}
|
||||||
|
res, err := conn.DescribeSnapshots(req)
|
||||||
|
if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidSnapshotID.NotFound" {
|
||||||
|
log.Printf("Snapshot %q Not found - removing from state", d.Id())
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshot := res.Snapshots[0]
|
||||||
|
|
||||||
|
d.Set("description", snapshot.Description)
|
||||||
|
d.Set("owner_id", snapshot.OwnerId)
|
||||||
|
d.Set("encrypted", snapshot.Encrypted)
|
||||||
|
d.Set("owner_alias", snapshot.OwnerAlias)
|
||||||
|
d.Set("volume_id", snapshot.VolumeId)
|
||||||
|
d.Set("data_encryption_key_id", snapshot.DataEncryptionKeyId)
|
||||||
|
d.Set("kms_keey_id", snapshot.KmsKeyId)
|
||||||
|
d.Set("volume_size", snapshot.VolumeSize)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsEbsSnapshotDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
return resource.Retry(5*time.Minute, func() *resource.RetryError {
|
||||||
|
request := &ec2.DeleteSnapshotInput{
|
||||||
|
SnapshotId: aws.String(d.Id()),
|
||||||
|
}
|
||||||
|
_, err := conn.DeleteSnapshot(request)
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ebsErr, ok := err.(awserr.Error)
|
||||||
|
if ebsErr.Code() == "SnapshotInUse" {
|
||||||
|
return resource.RetryableError(fmt.Errorf("EBS SnapshotInUse - trying again while it detaches"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return resource.NonRetryableError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resource.NonRetryableError(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsEbsSnapshotWaitForAvailable(id string, conn *ec2.EC2) error {
|
||||||
|
log.Printf("Waiting for Snapshot %s to become available...", id)
|
||||||
|
|
||||||
|
req := &ec2.DescribeSnapshotsInput{
|
||||||
|
SnapshotIds: []*string{aws.String(id)},
|
||||||
|
}
|
||||||
|
err := conn.WaitUntilSnapshotCompleted(req)
|
||||||
|
return err
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccAWSEBSSnapshot_basic(t *testing.T) {
|
||||||
|
var v ec2.Snapshot
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAwsEbsSnapshotConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckSnapshotExists("aws_ebs_snapshot.test", &v),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSEBSSnapshot_withDescription(t *testing.T) {
|
||||||
|
var v ec2.Snapshot
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAwsEbsSnapshotConfigWithDescription,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckSnapshotExists("aws_ebs_snapshot.test", &v),
|
||||||
|
resource.TestCheckResourceAttr("aws_ebs_snapshot.test", "description", "EBS Snapshot Acceptance Test"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckSnapshotExists(n string, v *ec2.Snapshot) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
request := &ec2.DescribeSnapshotsInput{
|
||||||
|
SnapshotIds: []*string{aws.String(rs.Primary.ID)},
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := conn.DescribeSnapshots(request)
|
||||||
|
if err == nil {
|
||||||
|
if response.Snapshots != nil && len(response.Snapshots) > 0 {
|
||||||
|
*v = *response.Snapshots[0]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Error finding EC2 Snapshot %s", rs.Primary.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccAwsEbsSnapshotConfig = `
|
||||||
|
resource "aws_ebs_volume" "test" {
|
||||||
|
availability_zone = "us-west-2a"
|
||||||
|
size = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_ebs_snapshot" "test" {
|
||||||
|
volume_id = "${aws_ebs_volume.test.id}"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccAwsEbsSnapshotConfigWithDescription = `
|
||||||
|
resource "aws_ebs_volume" "description_test" {
|
||||||
|
availability_zone = "us-west-2a"
|
||||||
|
size = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_ebs_snapshot" "test" {
|
||||||
|
volume_id = "${aws_ebs_volume.description_test.id}"
|
||||||
|
description = "EBS Snapshot Acceptance Test"
|
||||||
|
}
|
||||||
|
`
|
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
layout: "aws"
|
||||||
|
page_title: "AWS: aws_ebs_snapshot"
|
||||||
|
sidebar_current: "docs-aws-datasource-ebs-snapshot"
|
||||||
|
description: |-
|
||||||
|
Get information on an EBS Snapshot.
|
||||||
|
---
|
||||||
|
|
||||||
|
# aws\_ebs\_snapshot
|
||||||
|
|
||||||
|
Use this data source to get information about an EBS Snapshot for use when provisioning EBS Volumes
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
data "aws_ebs_snapshot" "ebs_volume" {
|
||||||
|
owners = ["self"]
|
||||||
|
filter {
|
||||||
|
name = "volume-size"
|
||||||
|
values = ["40"]
|
||||||
|
}
|
||||||
|
filter {
|
||||||
|
name = "tag:Name"
|
||||||
|
values = ["Example"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `owners` - (Optional) Returns the snapshots owned by the specified owner id. Multiple owners can be specified.
|
||||||
|
|
||||||
|
* `snapshot_ids` - (Optional) Returns information on a specific snapshot_id.
|
||||||
|
|
||||||
|
* `restorable_by_user_ids` - (Optional) One or more AWS accounts IDs that can create volumes from the snapshot.
|
||||||
|
|
||||||
|
* `filter` - (Optional) One or more name/value pairs to filter off of. There are
|
||||||
|
several valid keys, for a full reference, check out
|
||||||
|
[describe-volumes in the AWS CLI reference][1].
|
||||||
|
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `id` - The snapshot ID (e.g. snap-59fcb34e).
|
||||||
|
* `snapshot_id` - The snapshot ID (e.g. snap-59fcb34e).
|
||||||
|
* `description` - A description for the snapshot
|
||||||
|
* `owner_id` - The AWS account ID of the EBS snapshot owner.
|
||||||
|
* `owner_alias` - Value from an Amazon-maintained list (`amazon`, `aws-marketplace`, `microsoft`) of snapshot owners.
|
||||||
|
* `volume_id` - The volume ID (e.g. vol-59fcb34e).
|
||||||
|
* `encrypted` - Whether the snapshot is encrypted.
|
||||||
|
* `volume_size` - The size of the drive in GiBs.
|
||||||
|
* `kms_key_id` - The ARN for the KMS encryption key.
|
||||||
|
* `data_encryption_key_id` - The data encryption key identifier for the snapshot.
|
||||||
|
* `state` - The snapshot state.
|
||||||
|
* `tags` - A mapping of tags for the resource.
|
||||||
|
|
||||||
|
[1]: http://docs.aws.amazon.com/cli/latest/reference/ec2/describe-snapshots.html
|
|
@ -0,0 +1,48 @@
|
||||||
|
---
|
||||||
|
layout: "aws"
|
||||||
|
page_title: "AWS: aws_ebs_snapshot"
|
||||||
|
sidebar_current: "docs-aws-resource-ebs-snapshot"
|
||||||
|
description: |-
|
||||||
|
Provides an elastic block storage snapshot resource.
|
||||||
|
---
|
||||||
|
|
||||||
|
# aws\_ebs\_snapshot
|
||||||
|
|
||||||
|
Creates a Snapshot of an EBS Volume.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "aws_ebs_volume" "example" {
|
||||||
|
availability_zone = "us-west-2a"
|
||||||
|
size = 40
|
||||||
|
tags {
|
||||||
|
Name = "HelloWorld"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_ebs_snapshot" "example_snapshot" {
|
||||||
|
volume_id = "${aws_ebs_volume.example.id}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `volume_id` - (Required) The Volume ID of which to make a snapshot.
|
||||||
|
* `description` - (Optional) A description of what the snapshot is.
|
||||||
|
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `id` - The snapshot ID (e.g. snap-59fcb34e).
|
||||||
|
* `owner_id` - The AWS account ID of the EBS snapshot owner.
|
||||||
|
* `owner_alias` - Value from an Amazon-maintained list (`amazon`, `aws-marketplace`, `microsoft`) of snapshot owners.
|
||||||
|
* `encrypted` - Whether the snapshot is encrypted.
|
||||||
|
* `volume_size` - The size of the drive in GiBs.
|
||||||
|
* `kms_key_id` - The ARN for the KMS encryption key.
|
||||||
|
* `data_encryption_key_id` - The data encryption key identifier for the snapshot.
|
||||||
|
* `tags` - A mapping of tags for the resource.
|
|
@ -20,6 +20,7 @@
|
||||||
<li<%= sidebar_current("docs-aws-datasource-alb") %>>
|
<li<%= sidebar_current("docs-aws-datasource-alb") %>>
|
||||||
<a href="/docs/providers/aws/d/alb.html">aws_alb</a>
|
<a href="/docs/providers/aws/d/alb.html">aws_alb</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-aws-datasource-ami") %>>
|
<li<%= sidebar_current("docs-aws-datasource-ami") %>>
|
||||||
<a href="/docs/providers/aws/d/ami.html">aws_ami</a>
|
<a href="/docs/providers/aws/d/ami.html">aws_ami</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -38,6 +39,9 @@
|
||||||
<li<%= sidebar_current("docs-aws-datasource-cloudformation-stack") %>>
|
<li<%= sidebar_current("docs-aws-datasource-cloudformation-stack") %>>
|
||||||
<a href="/docs/providers/aws/d/cloudformation_stack.html">aws_cloudformation_stack</a>
|
<a href="/docs/providers/aws/d/cloudformation_stack.html">aws_cloudformation_stack</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li<%= sidebar_current("docs-aws-datasource-ebs-snapshot") %>>
|
||||||
|
<a href="/docs/providers/aws/d/ebs_snapshot.html">aws_ebs_snapshot</a>
|
||||||
|
</li>
|
||||||
<li<%= sidebar_current("docs-aws-datasource-ebs-volume") %>>
|
<li<%= sidebar_current("docs-aws-datasource-ebs-volume") %>>
|
||||||
<a href="/docs/providers/aws/d/ebs_volume.html">aws_ebs_volume</a>
|
<a href="/docs/providers/aws/d/ebs_volume.html">aws_ebs_volume</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -304,10 +308,6 @@
|
||||||
<a href="/docs/providers/aws/r/autoscaling_group.html">aws_autoscaling_group</a>
|
<a href="/docs/providers/aws/r/autoscaling_group.html">aws_autoscaling_group</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-aws-resource-autoscaling-attachment") %>>
|
|
||||||
<a href="/docs/providers/aws/r/autoscaling_attachment.html">aws_autoscaling_attachment</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-aws-resource-autoscaling-lifecycle-hook") %>>
|
<li<%= sidebar_current("docs-aws-resource-autoscaling-lifecycle-hook") %>>
|
||||||
<a href="/docs/providers/aws/r/autoscaling_lifecycle_hooks.html">aws_autoscaling_lifecycle_hook</a>
|
<a href="/docs/providers/aws/r/autoscaling_lifecycle_hooks.html">aws_autoscaling_lifecycle_hook</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -324,6 +324,10 @@
|
||||||
<a href="/docs/providers/aws/r/autoscaling_schedule.html">aws_autoscaling_schedule</a>
|
<a href="/docs/providers/aws/r/autoscaling_schedule.html">aws_autoscaling_schedule</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-aws-resource-ebs-snapshot") %>>
|
||||||
|
<a href="/docs/providers/aws/r/ebs_snapshot.html">aws_ebs_snapshot</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-aws-resource-ebs-volume") %>>
|
<li<%= sidebar_current("docs-aws-resource-ebs-volume") %>>
|
||||||
<a href="/docs/providers/aws/r/ebs_volume.html">aws_ebs_volume</a>
|
<a href="/docs/providers/aws/r/ebs_volume.html">aws_ebs_volume</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -819,11 +823,11 @@
|
||||||
<li<%= sidebar_current("docs-aws-resource-waf-webacl") %>>
|
<li<%= sidebar_current("docs-aws-resource-waf-webacl") %>>
|
||||||
<a href="/docs/providers/aws/r/waf_web_acl.html">aws_waf_web_acl</a>
|
<a href="/docs/providers/aws/r/waf_web_acl.html">aws_waf_web_acl</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-aws-resource-waf-bytematchset") %>>
|
<li<%= sidebar_current("docs-aws-resource-waf-bytematchset") %>>
|
||||||
<a href="/docs/providers/aws/r/waf_byte_match_set.html">aws_waf_byte_match_set</a>
|
<a href="/docs/providers/aws/r/waf_byte_match_set.html">aws_waf_byte_match_set</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-aws-resource-waf-size-constraint-set") %>>
|
<li<%= sidebar_current("docs-aws-resource-waf-size-constraint-set") %>>
|
||||||
<a href="/docs/providers/aws/r/waf_size_constraint_set.html">aws_waf_size_constraint_set</a>
|
<a href="/docs/providers/aws/r/waf_size_constraint_set.html">aws_waf_size_constraint_set</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -835,7 +839,7 @@
|
||||||
<li<%= sidebar_current("docs-aws-resource-waf-ipset") %>>
|
<li<%= sidebar_current("docs-aws-resource-waf-ipset") %>>
|
||||||
<a href="/docs/providers/aws/r/waf_ipset.html">aws_waf_ipset</a>
|
<a href="/docs/providers/aws/r/waf_ipset.html">aws_waf_ipset</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-aws-resource-waf-xss-match-set") %>>
|
<li<%= sidebar_current("docs-aws-resource-waf-xss-match-set") %>>
|
||||||
<a href="/docs/providers/aws/r/waf_xss_match_set.html">aws_waf_xss_match_set</a>
|
<a href="/docs/providers/aws/r/waf_xss_match_set.html">aws_waf_xss_match_set</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
Loading…
Reference in New Issue