Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow aws_s3_bucket_object to be imported #10036

Merged
merged 6 commits into from
Jul 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions aws/resource_aws_s3_bucket_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ func resourceAwsS3BucketObject() *schema.Resource {
Update: resourceAwsS3BucketObjectUpdate,
Delete: resourceAwsS3BucketObjectDelete,

Importer: &schema.ResourceImporter{
State: resourceAwsS3BucketObjectImport,
},

CustomizeDiff: customdiff.Sequence(
resourceAwsS3BucketObjectCustomizeDiff,
SetTagsDiff,
Expand Down Expand Up @@ -532,6 +536,29 @@ func resourceAwsS3BucketObjectDelete(d *schema.ResourceData, meta interface{}) e
return nil
}

func resourceAwsS3BucketObjectImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
id := d.Id()

if strings.HasPrefix(id, "s3://") {
id = strings.TrimPrefix(id, "s3://")
}

parts := strings.Split(id, "/")

if len(parts) < 2 {
return []*schema.ResourceData{d}, fmt.Errorf("id %s should be in format <bucket>/<key> or s3://<bucket>/<key>", id)
}

bucket := parts[0]
key := strings.Join(parts[1:], "/")

d.SetId(key)
d.Set("bucket", bucket)
d.Set("key", key)

return []*schema.ResourceData{d}, nil
}

func resourceAwsS3BucketObjectSetKMS(d *schema.ResourceData, meta interface{}, sseKMSKeyId *string) error {
// Only set non-default KMS key ID (one that doesn't match default)
if sseKMSKeyId != nil {
Expand Down
105 changes: 105 additions & 0 deletions aws/resource_aws_s3_bucket_object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,13 @@ func TestAccAWSS3BucketObject_empty(t *testing.T) {
testAccCheckAWSS3BucketObjectBody(&obj, ""),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"acl", "force_destroy"},
ImportStateId: fmt.Sprintf("s3://%s/test-key", rName),
},
},
})
}
Expand All @@ -171,6 +178,13 @@ func TestAccAWSS3BucketObject_source(t *testing.T) {
testAccCheckAWSS3BucketObjectBody(&obj, "{anything will do }"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"acl", "source", "force_destroy"},
ImportStateId: fmt.Sprintf("s3://%s/test-key", rName),
},
},
})
}
Expand All @@ -194,6 +208,13 @@ func TestAccAWSS3BucketObject_content(t *testing.T) {
testAccCheckAWSS3BucketObjectBody(&obj, "some_bucket_content"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"acl", "content", "content_base64", "force_destroy"},
ImportStateId: fmt.Sprintf("s3://%s/test-key", rName),
},
},
})
}
Expand All @@ -220,6 +241,13 @@ func TestAccAWSS3BucketObject_etagEncryption(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "etag", "7b006ff4d70f68cc65061acf2f802e6f"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"acl", "source", "force_destroy"},
ImportStateId: fmt.Sprintf("s3://%s/test-key", rName),
},
},
})
}
Expand Down Expand Up @@ -292,6 +320,13 @@ func TestAccAWSS3BucketObject_sourceHashTrigger(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "source_hash", "cffc5e20de2d21764145b1124c9b337b"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"acl", "content", "content_base64", "force_destroy", "source", "source_hash"},
ImportStateId: fmt.Sprintf("s3://%s/test-key", rName),
},
},
})
}
Expand Down Expand Up @@ -344,6 +379,13 @@ func TestAccAWSS3BucketObject_nonVersioned(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "version_id", ""),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"acl", "source"},
ImportStateId: fmt.Sprintf("s3://%s/test-key", rName),
},
},
})
}
Expand Down Expand Up @@ -386,6 +428,13 @@ func TestAccAWSS3BucketObject_updates(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", ""),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"acl", "source", "force_destroy"},
ImportStateId: fmt.Sprintf("s3://%s/updateable-key", rName),
},
},
})
}
Expand Down Expand Up @@ -470,6 +519,13 @@ func TestAccAWSS3BucketObject_updatesWithVersioning(t *testing.T) {
testAccCheckAWSS3BucketObjectVersionIdDiffers(&modifiedObj, &originalObj),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"acl", "source", "force_destroy"},
ImportStateId: fmt.Sprintf("s3://%s/updateable-key", rName),
},
},
})
}
Expand Down Expand Up @@ -536,6 +592,13 @@ func TestAccAWSS3BucketObject_kms(t *testing.T) {
testAccCheckAWSS3BucketObjectBody(&obj, "{anything will do }"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"acl", "source", "force_destroy"},
ImportStateId: fmt.Sprintf("s3://%s/test-key", rName),
},
},
})
}
Expand Down Expand Up @@ -563,6 +626,13 @@ func TestAccAWSS3BucketObject_sse(t *testing.T) {
testAccCheckAWSS3BucketObjectBody(&obj, "{anything will do }"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"acl", "source", "force_destroy"},
ImportStateId: fmt.Sprintf("s3://%s/test-key", rName),
},
},
})
}
Expand Down Expand Up @@ -607,6 +677,13 @@ func TestAccAWSS3BucketObject_acl(t *testing.T) {
testAccCheckAWSS3BucketObjectAcl(resourceName, []string{"FULL_CONTROL"}),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"acl", "content", "force_destroy"},
ImportStateId: fmt.Sprintf("s3://%s/test-key", rName),
},
},
})
}
Expand Down Expand Up @@ -647,6 +724,13 @@ func TestAccAWSS3BucketObject_metadata(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "metadata.%", "0"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"acl", "force_destroy"},
ImportStateId: fmt.Sprintf("s3://%s/test-key", rName),
},
},
})
}
Expand Down Expand Up @@ -703,6 +787,13 @@ func TestAccAWSS3BucketObject_storageClass(t *testing.T) {
testAccCheckAWSS3BucketObjectStorageClass(resourceName, "DEEP_ARCHIVE"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"content", "acl", "force_destroy"},
ImportStateId: fmt.Sprintf("s3://%s/test-key", rName),
},
},
})
}
Expand Down Expand Up @@ -768,6 +859,13 @@ func TestAccAWSS3BucketObject_tags(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "tags.Key3", "CCC"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"content", "acl", "force_destroy"},
ImportStateId: fmt.Sprintf("s3://%s/%s", rName, key),
},
},
})
}
Expand Down Expand Up @@ -833,6 +931,13 @@ func TestAccAWSS3BucketObject_tagsLeadingSingleSlash(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "tags.Key3", "CCC"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"content", "acl", "force_destroy"},
ImportStateId: fmt.Sprintf("s3://%s/%s", rName, key),
},
},
})
}
Expand Down
16 changes: 15 additions & 1 deletion website/docs/r/s3_bucket_object.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,18 @@ In addition to all arguments above, the following attributes are exported:
* `etag` - ETag generated for the object (an MD5 sum of the object content). For plaintext objects or objects encrypted with an AWS-managed key, the hash is an MD5 digest of the object data. For objects encrypted with a KMS key or objects created by either the Multipart Upload or Part Copy operation, the hash is not an MD5 digest, regardless of the method of encryption. More information on possible values can be found on [Common Response Headers](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonResponseHeaders.html).
* `id` - `key` of the resource supplied above
* `tags_all` - Map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block).
* `version_id` - Unique version ID value for the object, if bucket versioning is enabled.
* `version_id` - Unique version ID value for the object, if bucket versioning is enabled.

## Import

Objects can be imported using the `id`. The `id` is the bucket name and the key together e.g.

```
$ terraform import aws_s3_bucket_object.object some-bucket-name/some/key.txt
```

Additionally, s3 url syntax can be used, e.g.

```
$ terraform import aws_s3_bucket_object.object s3://some-bucket-name/some/key.txt
```