mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Allowing at-rest encryption when using S3
This change allows the user to specify `-backend-config="encrypt=1"` to tell S3 to encrypt the data that's in the bucket when using S3 for remote config storage. The encryption uses "Amazon S3-managed encryption keys" so it should not require any further user intervention. A line was added to the unit test just for coverage. The acceptance test was modified to: a) Use encryption b) Push some test data up to the bucket created to ensure that Amazon accepts the header.
This commit is contained in:
parent
f045e9e8d1
commit
ad17cf55a0
@ -32,6 +32,12 @@ func s3Factory(conf map[string]string) (Client, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serverSideEncryption := false
|
||||||
|
_, ok = conf["encrypt"]
|
||||||
|
if ok {
|
||||||
|
serverSideEncryption = true
|
||||||
|
}
|
||||||
|
|
||||||
accessKeyId := conf["access_key"]
|
accessKeyId := conf["access_key"]
|
||||||
secretAccessKey := conf["secret_key"]
|
secretAccessKey := conf["secret_key"]
|
||||||
|
|
||||||
@ -63,6 +69,7 @@ func s3Factory(conf map[string]string) (Client, error) {
|
|||||||
nativeClient: nativeClient,
|
nativeClient: nativeClient,
|
||||||
bucketName: bucketName,
|
bucketName: bucketName,
|
||||||
keyName: keyName,
|
keyName: keyName,
|
||||||
|
serverSideEncryption: serverSideEncryption,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +77,7 @@ type S3Client struct {
|
|||||||
nativeClient *s3.S3
|
nativeClient *s3.S3
|
||||||
bucketName string
|
bucketName string
|
||||||
keyName string
|
keyName string
|
||||||
|
serverSideEncryption bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *S3Client) Get() (*Payload, error) {
|
func (c *S3Client) Get() (*Payload, error) {
|
||||||
@ -113,13 +121,20 @@ func (c *S3Client) Put(data []byte) error {
|
|||||||
contentType := "application/octet-stream"
|
contentType := "application/octet-stream"
|
||||||
contentLength := int64(len(data))
|
contentLength := int64(len(data))
|
||||||
|
|
||||||
_, err := c.nativeClient.PutObject(&s3.PutObjectInput{
|
i := &s3.PutObjectInput{
|
||||||
ContentType: &contentType,
|
ContentType: &contentType,
|
||||||
ContentLength: &contentLength,
|
ContentLength: &contentLength,
|
||||||
Body: bytes.NewReader(data),
|
Body: bytes.NewReader(data),
|
||||||
Bucket: &c.bucketName,
|
Bucket: &c.bucketName,
|
||||||
Key: &c.keyName,
|
Key: &c.keyName,
|
||||||
})
|
}
|
||||||
|
|
||||||
|
if c.serverSideEncryption {
|
||||||
|
e := "AES256"
|
||||||
|
i.ServerSideEncryption = &e
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := c.nativeClient.PutObject(i)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -28,6 +28,7 @@ func TestS3Factory(t *testing.T) {
|
|||||||
config["region"] = "us-west-1"
|
config["region"] = "us-west-1"
|
||||||
config["bucket"] = "foo"
|
config["bucket"] = "foo"
|
||||||
config["key"] = "bar"
|
config["key"] = "bar"
|
||||||
|
config["encrypt"] = "1"
|
||||||
// For this test we'll provide the credentials as config. The
|
// For this test we'll provide the credentials as config. The
|
||||||
// acceptance tests implicitly test passing credentials as
|
// acceptance tests implicitly test passing credentials as
|
||||||
// environment variables.
|
// environment variables.
|
||||||
@ -80,11 +81,13 @@ func TestS3Client(t *testing.T) {
|
|||||||
|
|
||||||
bucketName := fmt.Sprintf("terraform-remote-s3-test-%x", time.Now().Unix())
|
bucketName := fmt.Sprintf("terraform-remote-s3-test-%x", time.Now().Unix())
|
||||||
keyName := "testState"
|
keyName := "testState"
|
||||||
|
testData := []byte(`testing data`)
|
||||||
|
|
||||||
config := make(map[string]string)
|
config := make(map[string]string)
|
||||||
config["region"] = regionName
|
config["region"] = regionName
|
||||||
config["bucket"] = bucketName
|
config["bucket"] = bucketName
|
||||||
config["key"] = keyName
|
config["key"] = keyName
|
||||||
|
config["encrypt"] = "1"
|
||||||
|
|
||||||
client, err := s3Factory(config)
|
client, err := s3Factory(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -105,6 +108,13 @@ func TestS3Client(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Skipf("Failed to create test S3 bucket, so skipping")
|
t.Skipf("Failed to create test S3 bucket, so skipping")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure we can perform a PUT request with the encryption header
|
||||||
|
err = s3Client.Put(testData)
|
||||||
|
if err != nil {
|
||||||
|
t.Logf("WARNING: Failed to send test data to S3 bucket. (error was %s)", err)
|
||||||
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
deleteBucketReq := &s3.DeleteBucketInput{
|
deleteBucketReq := &s3.DeleteBucketInput{
|
||||||
Bucket: &bucketName,
|
Bucket: &bucketName,
|
||||||
|
Loading…
Reference in New Issue
Block a user