Skip to content

Commit 916ab6b

Browse files
airizarryDBalexott
andauthored
Added support for AWS Govcloud DoD shard (#4594)
## Changes <!-- Summary of your changes that are easy to understand --> Added support for AWS Govcloud DoD shard ## Tests <!-- How is this tested? Please see the checklist below and also describe any other relevant tests --> - [x] `make test` run locally - [x] relevant change in `docs/` folder - [ ] covered with integration tests in `internal/acceptance` - [ ] using Go SDK - [ ] using TF Plugin Framework --------- Co-authored-by: Alex Ott <[email protected]>
1 parent 4199b7a commit 916ab6b

17 files changed

+297
-51
lines changed

NEXT_CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### New Features and Improvements
66

77
* Mark GKE-related fields for `databricks_mws_workspaces` and `databricks_mws_networks` as deprecated([#4531](https://github.com/databricks/terraform-provider-databricks/pull/4531)).
8+
* Add support for `aws-us-gov-dod` (AWS Govcloud DoD shard) ([#4594](https://github.com/databricks/terraform-provider-databricks/pull/4594/commits/5ac01118f546070ae5b8938f06807c8325d0f5d7))
89

910
### Bug Fixes
1011

aws/constants.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,23 @@ package aws
33
var AwsConfig = map[string]map[string]string{
44
"aws": {
55
"accountId": "414351767826",
6+
"awsNamespace": "aws",
67
"logDeliveryIamArn": "arn:aws:iam::414351767826:role/SaasUsageDeliveryRole-prod-IAMRole-3PLHICCRR1TK",
78
"unityCatalogueIamArn": "arn:aws:iam::414351767826:role/unity-catalog-prod-UCMasterRole-14S5ZJVKOTYTL",
89
},
910
"aws-us-gov": {
1011
"accountId": "044793339203",
12+
"awsNamespace": "aws-us-gov",
1113
"logDeliveryIamArn": "arn:aws-us-gov:iam::044793339203:role/SaasUsageDeliveryRole-prod-aws-gov-IAMRole-L4QM0RCHYQ1G",
1214
"unityCatalogueIamArn": "arn:aws-us-gov:iam::044793339203:role/unity-catalog-prod-UCMasterRole-1QRFA8SGY15OJ",
1315
},
16+
"aws-us-gov-dod": {
17+
"accountId": "170661010020",
18+
"awsNamespace": "aws-us-gov",
19+
"logDeliveryIamArn": "arn:aws-us-gov:iam::170661010020:role/SaasUsageDeliveryRole-prod-aws-gov-dod-IAMRole-1DMEHBYR8VC5P",
20+
"unityCatalogueIamArn": "arn:aws-us-gov:iam::170661010020:role/unity-catalog-prod-UCMasterRole-1DI6DL6ZP26AS",
21+
},
1422
}
1523

16-
var AwsPartitions = []string{"aws", "aws-us-gov"}
17-
var AwsPartitionsValidationError = "aws_partition must be either 'aws' or 'aws-us-gov'"
24+
var AwsPartitions = []string{"aws", "aws-us-gov", "aws-us-gov-dod"}
25+
var AwsPartitionsValidationError = "aws_partition must be either 'aws' or 'aws-us-gov' or 'aws-us-gov-dod'"

aws/data_aws_assume_role_policy.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ func DataAwsAssumeRolePolicy() common.Resource {
3434
externalID := d.Get("external_id").(string)
3535
awsPartition := d.Get("aws_partition").(string)
3636
databricksAwsAccountId := d.Get("databricks_account_id").(string)
37+
awsNamespace := AwsConfig[awsPartition]["awsNamespace"]
3738

3839
if databricksAwsAccountId == "" {
3940
databricksAwsAccountId = AwsConfig[awsPartition]["accountId"]
@@ -51,7 +52,7 @@ func DataAwsAssumeRolePolicy() common.Resource {
5152
},
5253
},
5354
Principal: map[string]string{
54-
"AWS": fmt.Sprintf("arn:%s:iam::%s:root", awsPartition, databricksAwsAccountId),
55+
"AWS": fmt.Sprintf("arn:%s:iam::%s:root", awsNamespace, databricksAwsAccountId),
5556
},
5657
},
5758
},

aws/data_aws_assume_role_policy_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,22 @@ func TestDataAwsAssumeRolePolicyGov(t *testing.T) {
3636
assert.Lenf(t, j, 306, "Strange length for policy: %s", j)
3737
}
3838

39+
func TestDataAwsAssumeRolePolicyGovDoD(t *testing.T) {
40+
d, err := qa.ResourceFixture{
41+
Read: true,
42+
Resource: DataAwsAssumeRolePolicy(),
43+
NonWritable: true,
44+
ID: ".",
45+
HCL: `
46+
aws_partition = "aws-us-gov-dod"
47+
external_id = "abc"
48+
`,
49+
}.Apply(t)
50+
assert.NoError(t, err)
51+
j := d.Get("json")
52+
assert.Lenf(t, j, 306, "Strange length for policy: %s", j)
53+
}
54+
3955
func TestDataAwsAssumeRolePolicyLogDelivery(t *testing.T) {
4056
d, err := qa.ResourceFixture{
4157
Read: true,
@@ -68,3 +84,20 @@ func TestDataAwsAssumeRolePolicyLogDeliveryGov(t *testing.T) {
6884
j := d.Get("json")
6985
assert.Lenf(t, j, 362, "Strange length for policy: %s", j)
7086
}
87+
88+
func TestDataAwsAssumeRolePolicyLogDeliveryGovDoD(t *testing.T) {
89+
d, err := qa.ResourceFixture{
90+
Read: true,
91+
Resource: DataAwsAssumeRolePolicy(),
92+
NonWritable: true,
93+
ID: ".",
94+
HCL: `
95+
aws_partition = "aws-us-gov-dod"
96+
external_id = "abc"
97+
for_log_delivery = true
98+
`,
99+
}.Apply(t)
100+
assert.NoError(t, err)
101+
j := d.Get("json")
102+
assert.Lenf(t, j, 367, "Strange length for policy: %s", j)
103+
}

aws/data_aws_bucket_policy.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ func DataAwsBucketPolicy() common.Resource {
1818
bucket := d.Get("bucket").(string)
1919
awsPartition := d.Get("aws_partition").(string)
2020
databricksAwsAccountId := AwsConfig[awsPartition]["accountId"]
21+
awsNamespace := AwsConfig[awsPartition]["awsNamespace"]
2122

2223
if databricksAwsAccountId == "" {
2324
databricksAwsAccountId = AwsConfig[awsPartition]["accountId"]
@@ -37,11 +38,11 @@ func DataAwsBucketPolicy() common.Resource {
3738
"s3:GetBucketLocation",
3839
},
3940
Resources: []string{
40-
fmt.Sprintf("arn:%s:s3:::%s/*", awsPartition, bucket),
41-
fmt.Sprintf("arn:%s:s3:::%s", awsPartition, bucket),
41+
fmt.Sprintf("arn:%s:s3:::%s/*", awsNamespace, bucket),
42+
fmt.Sprintf("arn:%s:s3:::%s", awsNamespace, bucket),
4243
},
4344
Principal: map[string]string{
44-
"AWS": fmt.Sprintf("arn:%s:iam::%s:root", awsPartition, databricksAwsAccountId),
45+
"AWS": fmt.Sprintf("arn:%s:iam::%s:root", awsNamespace, databricksAwsAccountId),
4546
},
4647
},
4748
},

aws/data_aws_bucket_policy_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,19 @@ func TestDataAwsBucketPolicyPartitionGov(t *testing.T) {
6969
j := d.Get("json")
7070
assert.Lenf(t, j, 461, "Strange length for policy: %s", j)
7171
}
72+
73+
func TestDataAwsBucketPolicyPartitionGovDoD(t *testing.T) {
74+
d, err := qa.ResourceFixture{
75+
Read: true,
76+
Resource: DataAwsBucketPolicy(),
77+
NonWritable: true,
78+
ID: ".",
79+
HCL: `
80+
bucket = "abc"
81+
aws_partition = "aws-us-gov-dod"
82+
`,
83+
}.Apply(t)
84+
assert.NoError(t, err)
85+
j := d.Get("json")
86+
assert.Lenf(t, j, 461, "Strange length for policy: %s", j)
87+
}

aws/data_aws_crossaccount_policy.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ func DataAwsCrossaccountPolicy() common.Resource {
4949
return fmt.Errorf("security_group_id must begin with 'sg-'")
5050
}
5151
}
52+
awsNamespace := AwsConfig[data.AwsPartition]["awsNamespace"]
5253
// non resource-based permissions
5354
actions := []string{
5455
"ec2:AssignPrivateIpAddresses",
@@ -151,7 +152,7 @@ func DataAwsCrossaccountPolicy() common.Resource {
151152
"iam:CreateServiceLinkedRole",
152153
"iam:PutRolePolicy",
153154
},
154-
Resources: fmt.Sprintf("arn:%s:iam::*:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot", data.AwsPartition),
155+
Resources: fmt.Sprintf("arn:%s:iam::*:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot", awsNamespace),
155156
Condition: map[string]map[string]string{
156157
"StringLike": {
157158
"iam:AWSServiceName": "spot.amazonaws.com",
@@ -174,7 +175,6 @@ func DataAwsCrossaccountPolicy() common.Resource {
174175
if data.PolicyType == "restricted" {
175176
region := data.Region
176177
aws_account_id := data.AwsAccountId
177-
awsPartition := data.AwsPartition
178178
vpc_id := data.VpcId
179179
security_group_id := data.SecurityGroupId
180180
policy.Statements = append(policy.Statements,
@@ -186,7 +186,7 @@ func DataAwsCrossaccountPolicy() common.Resource {
186186
"ec2:DisassociateIamInstanceProfile",
187187
"ec2:ReplaceIamInstanceProfileAssociation",
188188
},
189-
Resources: fmt.Sprintf("arn:%s:ec2:%s:%s:instance/*", awsPartition, region, aws_account_id),
189+
Resources: fmt.Sprintf("arn:%s:ec2:%s:%s:instance/*", awsNamespace, region, aws_account_id),
190190
Condition: map[string]map[string]string{
191191
"StringEquals": {
192192
"ec2:ResourceTag/Vendor": "Databricks",
@@ -198,8 +198,8 @@ func DataAwsCrossaccountPolicy() common.Resource {
198198
Effect: "Allow",
199199
Actions: "ec2:RunInstances",
200200
Resources: []string{
201-
fmt.Sprintf("arn:%s:ec2:%s:%s:volume/*", awsPartition, region, aws_account_id),
202-
fmt.Sprintf("arn:%s:ec2:%s:%s:instance/*", awsPartition, region, aws_account_id),
201+
fmt.Sprintf("arn:%s:ec2:%s:%s:volume/*", awsNamespace, region, aws_account_id),
202+
fmt.Sprintf("arn:%s:ec2:%s:%s:instance/*", awsNamespace, region, aws_account_id),
203203
},
204204
Condition: map[string]map[string]string{
205205
"StringEquals": {
@@ -211,7 +211,7 @@ func DataAwsCrossaccountPolicy() common.Resource {
211211
Sid: "AllowEc2RunInstanceImagePerTag",
212212
Effect: "Allow",
213213
Actions: "ec2:RunInstances",
214-
Resources: fmt.Sprintf("arn:%s:ec2:%s:%s:image/*", awsPartition, region, aws_account_id),
214+
Resources: fmt.Sprintf("arn:%s:ec2:%s:%s:image/*", awsNamespace, region, aws_account_id),
215215
Condition: map[string]map[string]string{
216216
"StringEquals": {
217217
"aws:ResourceTag/Vendor": "Databricks",
@@ -223,13 +223,13 @@ func DataAwsCrossaccountPolicy() common.Resource {
223223
Effect: "Allow",
224224
Actions: "ec2:RunInstances",
225225
Resources: []string{
226-
fmt.Sprintf("arn:%s:ec2:%s:%s:network-interface/*", awsPartition, region, aws_account_id),
227-
fmt.Sprintf("arn:%s:ec2:%s:%s:subnet/*", awsPartition, region, aws_account_id),
228-
fmt.Sprintf("arn:%s:ec2:%s:%s:security-group/*", awsPartition, region, aws_account_id),
226+
fmt.Sprintf("arn:%s:ec2:%s:%s:network-interface/*", awsNamespace, region, aws_account_id),
227+
fmt.Sprintf("arn:%s:ec2:%s:%s:subnet/*", awsNamespace, region, aws_account_id),
228+
fmt.Sprintf("arn:%s:ec2:%s:%s:security-group/*", awsNamespace, region, aws_account_id),
229229
},
230230
Condition: map[string]map[string]string{
231231
"StringEquals": {
232-
"ec2:vpc": fmt.Sprintf("arn:%s:ec2:%s:%s:vpc/%s", awsPartition, region, aws_account_id, vpc_id),
232+
"ec2:vpc": fmt.Sprintf("arn:%s:ec2:%s:%s:vpc/%s", awsNamespace, region, aws_account_id, vpc_id),
233233
},
234234
},
235235
},
@@ -238,19 +238,19 @@ func DataAwsCrossaccountPolicy() common.Resource {
238238
Effect: "Allow",
239239
Actions: "ec2:RunInstances",
240240
NotResources: []string{
241-
fmt.Sprintf("arn:%s:ec2:%s:%s:image/*", awsPartition, region, aws_account_id),
242-
fmt.Sprintf("arn:%s:ec2:%s:%s:network-interface/*", awsPartition, region, aws_account_id),
243-
fmt.Sprintf("arn:%s:ec2:%s:%s:subnet/*", awsPartition, region, aws_account_id),
244-
fmt.Sprintf("arn:%s:ec2:%s:%s:security-group/*", awsPartition, region, aws_account_id),
245-
fmt.Sprintf("arn:%s:ec2:%s:%s:volume/*", awsPartition, region, aws_account_id),
246-
fmt.Sprintf("arn:%s:ec2:%s:%s:instance/*", awsPartition, region, aws_account_id),
241+
fmt.Sprintf("arn:%s:ec2:%s:%s:image/*", awsNamespace, region, aws_account_id),
242+
fmt.Sprintf("arn:%s:ec2:%s:%s:network-interface/*", awsNamespace, region, aws_account_id),
243+
fmt.Sprintf("arn:%s:ec2:%s:%s:subnet/*", awsNamespace, region, aws_account_id),
244+
fmt.Sprintf("arn:%s:ec2:%s:%s:security-group/*", awsNamespace, region, aws_account_id),
245+
fmt.Sprintf("arn:%s:ec2:%s:%s:volume/*", awsNamespace, region, aws_account_id),
246+
fmt.Sprintf("arn:%s:ec2:%s:%s:instance/*", awsNamespace, region, aws_account_id),
247247
},
248248
},
249249
&awsIamPolicyStatement{
250250
Sid: "EC2TerminateInstancesTag",
251251
Effect: "Allow",
252252
Actions: "ec2:TerminateInstances",
253-
Resources: fmt.Sprintf("arn:%s:ec2:%s:%s:instance/*", awsPartition, region, aws_account_id),
253+
Resources: fmt.Sprintf("arn:%s:ec2:%s:%s:instance/*", awsNamespace, region, aws_account_id),
254254
Condition: map[string]map[string]string{
255255
"StringEquals": {
256256
"ec2:ResourceTag/Vendor": "Databricks",
@@ -265,8 +265,8 @@ func DataAwsCrossaccountPolicy() common.Resource {
265265
"ec2:DetachVolume",
266266
},
267267
Resources: []string{
268-
fmt.Sprintf("arn:%s:ec2:%s:%s:instance/*", awsPartition, region, aws_account_id),
269-
fmt.Sprintf("arn:%s:ec2:%s:%s:volume/*", awsPartition, region, aws_account_id),
268+
fmt.Sprintf("arn:%s:ec2:%s:%s:instance/*", awsNamespace, region, aws_account_id),
269+
fmt.Sprintf("arn:%s:ec2:%s:%s:volume/*", awsNamespace, region, aws_account_id),
270270
},
271271
Condition: map[string]map[string]string{
272272
"StringEquals": {
@@ -278,7 +278,7 @@ func DataAwsCrossaccountPolicy() common.Resource {
278278
Sid: "EC2CreateVolumeByTag",
279279
Effect: "Allow",
280280
Actions: "ec2:CreateVolume",
281-
Resources: fmt.Sprintf("arn:%s:ec2:%s:%s:volume/*", awsPartition, region, aws_account_id),
281+
Resources: fmt.Sprintf("arn:%s:ec2:%s:%s:volume/*", awsNamespace, region, aws_account_id),
282282
Condition: map[string]map[string]string{
283283
"StringEquals": {
284284
"aws:RequestTag/Vendor": "Databricks",
@@ -290,7 +290,7 @@ func DataAwsCrossaccountPolicy() common.Resource {
290290
Effect: "Allow",
291291
Actions: "ec2:DeleteVolume",
292292
Resources: []string{
293-
fmt.Sprintf("arn:%s:ec2:%s:%s:volume/*", awsPartition, region, aws_account_id),
293+
fmt.Sprintf("arn:%s:ec2:%s:%s:volume/*", awsNamespace, region, aws_account_id),
294294
},
295295
Condition: map[string]map[string]string{
296296
"StringEquals": {
@@ -307,10 +307,10 @@ func DataAwsCrossaccountPolicy() common.Resource {
307307
"ec2:RevokeSecurityGroupEgress",
308308
"ec2:RevokeSecurityGroupIngress",
309309
},
310-
Resources: fmt.Sprintf("arn:%s:ec2:%s:%s:security-group/%s", awsPartition, region, aws_account_id, security_group_id),
310+
Resources: fmt.Sprintf("arn:%s:ec2:%s:%s:security-group/%s", awsNamespace, region, aws_account_id, security_group_id),
311311
Condition: map[string]map[string]string{
312312
"StringEquals": {
313-
"ec2:vpc": fmt.Sprintf("arn:%s:ec2:%s:%s:vpc/%s", awsPartition, region, aws_account_id, vpc_id),
313+
"ec2:vpc": fmt.Sprintf("arn:%s:ec2:%s:%s:vpc/%s", awsNamespace, region, aws_account_id, vpc_id),
314314
},
315315
},
316316
},

aws/data_aws_crossaccount_policy_test.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,13 +540,32 @@ func TestDataAwsCrossAccountRestrictedPolicyPartitionGov(t *testing.T) {
540540
aws_account_id = "123456789012"
541541
aws_partition = "aws-us-gov"
542542
vpc_id = "vpc-12345678"
543-
region = "us-west-2"
543+
region = "us-gov-west-1"
544+
security_group_id = "sg-12345678"`,
545+
ID: ".",
546+
}.Apply(t)
547+
assert.NoError(t, err)
548+
j := d.Get("json")
549+
assert.Lenf(t, j, 5963, "Strange length for policy: %s", j)
550+
}
551+
552+
func TestDataAwsCrossAccountRestrictedPolicyPartitionGovDoD(t *testing.T) {
553+
d, err := qa.ResourceFixture{
554+
Read: true,
555+
Resource: DataAwsCrossaccountPolicy(),
556+
NonWritable: true,
557+
HCL: `
558+
policy_type = "restricted"
559+
aws_account_id = "123456789012"
560+
aws_partition = "aws-us-gov-dod"
561+
vpc_id = "vpc-12345678"
562+
region = "us-gov-west-1"
544563
security_group_id = "sg-12345678"`,
545564
ID: ".",
546565
}.Apply(t)
547566
assert.NoError(t, err)
548567
j := d.Get("json")
549-
assert.Lenf(t, j, 5879, "Strange length for policy: %s", j)
568+
assert.Lenf(t, j, 5963, "Strange length for policy: %s", j)
550569
}
551570

552571
func TestDataAwsCrossAccountInvalidPolicy(t *testing.T) {

aws/data_aws_unity_catalog_assume_role_policy.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func DataAwsUnityCatalogAssumeRolePolicy() common.Resource {
2424
if !slices.Contains(AwsPartitions, data.AwsPartition) {
2525
return errors.New(AwsPartitionsValidationError)
2626
}
27-
27+
awsNamespace := AwsConfig[data.AwsPartition]["awsNamespace"]
2828
if data.UnityCatalogIamArn == "" {
2929
data.UnityCatalogIamArn = AwsConfig[data.AwsPartition]["unityCatalogueIamArn"]
3030
}
@@ -51,11 +51,11 @@ func DataAwsUnityCatalogAssumeRolePolicy() common.Resource {
5151
Actions: "sts:AssumeRole",
5252
Condition: map[string]map[string]string{
5353
"ArnLike": {
54-
"aws:PrincipalArn": fmt.Sprintf("arn:%s:iam::%s:role/%s", data.AwsPartition, data.AwsAccountId, data.RoleName),
54+
"aws:PrincipalArn": fmt.Sprintf("arn:%s:iam::%s:role/%s", awsNamespace, data.AwsAccountId, data.RoleName),
5555
},
5656
},
5757
Principal: map[string]string{
58-
"AWS": fmt.Sprintf("arn:%s:iam::%s:root", data.AwsPartition, data.AwsAccountId),
58+
"AWS": fmt.Sprintf("arn:%s:iam::%s:root", awsNamespace, data.AwsAccountId),
5959
},
6060
},
6161
},

aws/data_aws_unity_catalog_assume_role_policy_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,55 @@ func TestDataAwsUnityCatalogAssumeRolePolicyGovWithoutUcArn(t *testing.T) {
153153
compareJSON(t, j, p)
154154
}
155155

156+
func TestDataAwsUnityCatalogAssumeRolePolicyGovDoDWithoutUcArn(t *testing.T) {
157+
d, err := qa.ResourceFixture{
158+
Read: true,
159+
Resource: DataAwsUnityCatalogAssumeRolePolicy(),
160+
NonWritable: true,
161+
ID: ".",
162+
HCL: `
163+
aws_account_id = "123456789098"
164+
aws_partition = "aws-us-gov-dod"
165+
role_name = "databricks-role"
166+
external_id = "12345"
167+
`,
168+
}.Apply(t)
169+
assert.NoError(t, err)
170+
j := d.Get("json").(string)
171+
p := `{
172+
"Version": "2012-10-17",
173+
"Statement": [
174+
{
175+
"Sid": "UnityCatalogAssumeRole",
176+
"Effect": "Allow",
177+
"Action": "sts:AssumeRole",
178+
"Principal": {
179+
"AWS": "arn:aws-us-gov:iam::170661010020:role/unity-catalog-prod-UCMasterRole-1DI6DL6ZP26AS"
180+
},
181+
"Condition": {
182+
"StringEquals": {
183+
"sts:ExternalId": "12345"
184+
}
185+
}
186+
},
187+
{
188+
"Sid": "ExplicitSelfRoleAssumption",
189+
"Effect": "Allow",
190+
"Action": "sts:AssumeRole",
191+
"Principal": {
192+
"AWS": "arn:aws-us-gov:iam::123456789098:root"
193+
},
194+
"Condition": {
195+
"ArnLike": {
196+
"aws:PrincipalArn": "arn:aws-us-gov:iam::123456789098:role/databricks-role"
197+
}
198+
}
199+
}
200+
]
201+
}`
202+
compareJSON(t, j, p)
203+
}
204+
156205
func TestDataAwsUnityCatalogAssumeRolePolicyInvalidPartition(t *testing.T) {
157206
qa.ResourceFixture{
158207
Read: true,

0 commit comments

Comments
 (0)