Skip to content

Commit 6f34d77

Browse files
committed
feat: workload identity federation
1 parent a60d551 commit 6f34d77

File tree

26 files changed

+288
-26
lines changed

26 files changed

+288
-26
lines changed

.github/workflows/workflow.yaml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@ jobs:
77
name: Validate
88
runs-on: ubuntu-latest
99
steps:
10-
- name: Check out code
11-
uses: actions/checkout@v1
10+
- name: Check out code
11+
uses: actions/checkout@v1
1212

13-
- uses: hashicorp/setup-terraform@v1
14-
with:
15-
terraform_version: 1.0.10
13+
- uses: hashicorp/setup-terraform@v3
14+
with:
15+
terraform_version: "1.5"
1616

17-
# note: we can only validate the example atm. see https://github.com/hashicorp/terraform/issues/28490
18-
- run: terraform init -backend=false
19-
working-directory: examples/basic-aws-integration
17+
# note: we can only validate the example atm. see https://github.com/hashicorp/terraform/issues/28490
18+
- run: terraform init -backend=false
19+
working-directory: examples/basic-aws-integration
2020

21-
- run: terraform validate
22-
working-directory: examples/basic-aws-integration
21+
- run: terraform validate
22+
working-directory: examples/basic-aws-integration
2323

24-
- run: terraform fmt -recursive -check
24+
- run: terraform fmt -recursive -check

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- Added ARNs of managed accounts roles to output
1515
- Added meshStack access role to output
1616
- Renamed metering related parts from kraken to metering
17+
- Added workload identity federation
18+
- Added option to disable access keys
1719

1820
## [v0.1.0]
1921

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,9 @@ Before opening a Pull Request, we recommend following the below steps to get a f
165165
166166
| Name | Version |
167167
|------|---------|
168-
| <a name="provider_aws.automation"></a> [aws.automation](#provider\_aws.automation) | 5.37.0 |
169-
| <a name="provider_aws.management"></a> [aws.management](#provider\_aws.management) | 5.37.0 |
170-
| <a name="provider_aws.meshcloud"></a> [aws.meshcloud](#provider\_aws.meshcloud) | 5.37.0 |
168+
| <a name="provider_aws.automation"></a> [aws.automation](#provider\_aws.automation) | 5.41.0 |
169+
| <a name="provider_aws.management"></a> [aws.management](#provider\_aws.management) | 5.41.0 |
170+
| <a name="provider_aws.meshcloud"></a> [aws.meshcloud](#provider\_aws.meshcloud) | 5.41.0 |
171171
172172
## Modules
173173
@@ -183,6 +183,7 @@ Before opening a Pull Request, we recommend following the below steps to get a f
183183
184184
| Name | Type |
185185
|------|------|
186+
| [aws_iam_openid_connect_provider.meshstack](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_openid_connect_provider) | resource |
186187
| [aws_caller_identity.automation](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
187188
| [aws_caller_identity.management](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
188189
| [aws_caller_identity.meshcloud](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
@@ -198,11 +199,13 @@ Before opening a Pull Request, we recommend following the below steps to get a f
198199
| <a name="input_cost_explorer_management_account_service_role_name"></a> [cost\_explorer\_management\_account\_service\_role\_name](#input\_cost\_explorer\_management\_account\_service\_role\_name) | Name of the custom role in the management account used by the cost explorer user. | `string` | `"MeshCostExplorerServiceRole"` | no |
199200
| <a name="input_cost_explorer_meshcloud_account_service_user_name"></a> [cost\_explorer\_meshcloud\_account\_service\_user\_name](#input\_cost\_explorer\_meshcloud\_account\_service\_user\_name) | Name of the user using cost explorer service to collect metering data. | `string` | `"meshcloud-cost-explorer-user"` | no |
200201
| <a name="input_cost_explorer_privileged_external_id"></a> [cost\_explorer\_privileged\_external\_id](#input\_cost\_explorer\_privileged\_external\_id) | Set this variable to a random UUID version 4. The external id is a secondary key to make an AssumeRole API call. | `string` | n/a | yes |
202+
| <a name="input_create_access_keys"></a> [create\_access\_keys](#input\_create\_access\_keys) | Set to false to disable creation of any service account access keys. | `bool` | `true` | no |
201203
| <a name="input_landing_zone_ou_arns"></a> [landing\_zone\_ou\_arns](#input\_landing\_zone\_ou\_arns) | Organizational Unit ARNs that are used in Landing Zones. We recommend to explicitly list the OU ARNs that meshStack should manage. | `list(string)` | <pre>[<br> "arn:aws:organizations::*:ou/o-*/ou-*"<br>]</pre> | no |
202204
| <a name="input_management_account_service_role_name"></a> [management\_account\_service\_role\_name](#input\_management\_account\_service\_role\_name) | Name of the custom role in the management account. See https://docs.meshcloud.io/docs/meshstack.how-to.integrate-meshplatform-aws-manually.html#set-up-aws-account-2-management | `string` | `"MeshfedServiceRole"` | no |
203205
| <a name="input_meshcloud_account_service_user_name"></a> [meshcloud\_account\_service\_user\_name](#input\_meshcloud\_account\_service\_user\_name) | Name of the meshfed-service user. This user is responsible for replication. | `string` | `"meshfed-service-user"` | no |
204206
| <a name="input_replicator_privileged_external_id"></a> [replicator\_privileged\_external\_id](#input\_replicator\_privileged\_external\_id) | Set this variable to a random UUID version 4. The external id is a secondary key to make an AssumeRole API call. | `string` | n/a | yes |
205207
| <a name="input_support_root_account_via_aws_sso"></a> [support\_root\_account\_via\_aws\_sso](#input\_support\_root\_account\_via\_aws\_sso) | Set to true to allow meshStack to manage the Organization's AWS Root account's access via AWS SSO. | `bool` | `false` | no |
208+
| <a name="input_workload_identity_federation"></a> [workload\_identity\_federation](#input\_workload\_identity\_federation) | Set these options to add a trusted identity provider from meshStack to allow workload identity federation for authentication which can be used instead of access keys. | <pre>object({<br> issuer = string,<br> audience = string,<br> thumbprint = string,<br> replicator_subject = string,<br> kraken_subject = string<br> })</pre> | `null` | no |
206209
207210
## Outputs
208211
@@ -219,4 +222,5 @@ Before opening a Pull Request, we recommend following the below steps to get a f
219222
| <a name="output_replicator_aws_iam_keys"></a> [replicator\_aws\_iam\_keys](#output\_replicator\_aws\_iam\_keys) | You can access your credentials when you execute `terraform output replicator_aws_iam_keys` command |
220223
| <a name="output_replicator_management_account_role_arn"></a> [replicator\_management\_account\_role\_arn](#output\_replicator\_management\_account\_role\_arn) | Amazon Resource Name (ARN) of Management Account Role for replicator |
221224
| <a name="output_replicator_privileged_external_id"></a> [replicator\_privileged\_external\_id](#output\_replicator\_privileged\_external\_id) | Replicator privileged\_external\_id |
225+
| <a name="output_replicator_workload_identity_federation_role"></a> [replicator\_workload\_identity\_federation\_role](#output\_replicator\_workload\_identity\_federation\_role) | n/a |
222226
<!-- END_TF_DOCS -->

identity_provider.tf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# in case of workload identity federation we must add the appropriate identity provider
2+
resource "aws_iam_openid_connect_provider" "meshstack" {
3+
provider = aws.meshcloud
4+
count = var.workload_identity_federation != null ? 1 : 0
5+
6+
url = var.workload_identity_federation.issuer
7+
client_id_list = [var.workload_identity_federation.audience]
8+
thumbprint_list = [var.workload_identity_federation.thumbprint]
9+
}

main.tf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ module "meshcloud_account_metering_access" {
1717
privileged_external_id = var.cost_explorer_privileged_external_id
1818
management_account_service_role_name = var.cost_explorer_management_account_service_role_name
1919
meshcloud_account_service_user_name = var.cost_explorer_meshcloud_account_service_user_name
20+
21+
workload_identity_federation = var.workload_identity_federation == null ? null : {
22+
issuer = var.workload_identity_federation.issuer,
23+
audience = var.workload_identity_federation.audience,
24+
subject = var.workload_identity_federation.kraken_subject,
25+
identity_provider_arn = aws_iam_openid_connect_provider.meshstack[0].arn
26+
}
2027
}
2128

2229
module "meshcloud_account_replicator_access" {
@@ -30,6 +37,13 @@ module "meshcloud_account_replicator_access" {
3037
meshcloud_account_service_user_name = var.meshcloud_account_service_user_name
3138
management_account_service_role_name = var.management_account_service_role_name
3239
automation_account_service_role_name = var.automation_account_service_role_name
40+
41+
workload_identity_federation = var.workload_identity_federation == null ? null : {
42+
issuer = var.workload_identity_federation.issuer,
43+
audience = var.workload_identity_federation.audience,
44+
subject = var.workload_identity_federation.replicator_subject,
45+
identity_provider_arn = aws_iam_openid_connect_provider.meshstack[0].arn
46+
}
3347
}
3448

3549
module "management_account_metering_access" {
@@ -42,6 +56,8 @@ module "management_account_metering_access" {
4256
management_account_service_role_name = var.cost_explorer_management_account_service_role_name
4357
meshcloud_account_service_user_name = var.cost_explorer_meshcloud_account_service_user_name
4458

59+
allow_federated_role = var.workload_identity_federation != null
60+
4561
depends_on = [
4662
module.meshcloud_account_metering_access
4763
]
@@ -62,6 +78,8 @@ module "management_account_replicator_access" {
6278
management_account_service_role_name = var.management_account_service_role_name
6379
landing_zone_ou_arns = var.landing_zone_ou_arns
6480

81+
allow_federated_role = var.workload_identity_federation != null
82+
6583
depends_on = [
6684
module.meshcloud_account_replicator_access
6785
]
@@ -77,6 +95,8 @@ module "automation_account_replicator_access" {
7795
meshcloud_account_service_user_name = var.meshcloud_account_service_user_name
7896
automation_account_service_role_name = var.automation_account_service_role_name
7997

98+
allow_federated_role = var.workload_identity_federation != null
99+
80100
depends_on = [
81101
module.meshcloud_account_replicator_access
82102
]

modules/meshcloud-cost-explorer/ce-management-account-access/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
| Name | Version |
1111
|------|---------|
12-
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.37.0 |
12+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 2.7.0 |
1313

1414
## Modules
1515

@@ -31,6 +31,7 @@ No modules.
3131

3232
| Name | Description | Type | Default | Required |
3333
|------|-------------|------|---------|:--------:|
34+
| <a name="input_allow_federated_role"></a> [allow\_federated\_role](#input\_allow\_federated\_role) | n/a | `bool` | `false` | no |
3435
| <a name="input_management_account_service_role_name"></a> [management\_account\_service\_role\_name](#input\_management\_account\_service\_role\_name) | Name of the custom role in the management account used by the cost explorer user. | `string` | `"MeshCostExplorerServiceRole"` | no |
3536
| <a name="input_meshcloud_account_id"></a> [meshcloud\_account\_id](#input\_meshcloud\_account\_id) | The ID of the meshcloud AWS Account. | `string` | n/a | yes |
3637
| <a name="input_meshcloud_account_service_user_name"></a> [meshcloud\_account\_service\_user\_name](#input\_meshcloud\_account\_service\_user\_name) | Name of the user using cost explorer service to collect metering data. | `string` | `"meshcloud-cost-explorer-user"` | no |

modules/meshcloud-cost-explorer/ce-management-account-access/data.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,21 @@ data "aws_iam_policy_document" "cost_explorer_service_assume_role" {
3939
version = "2012-10-17"
4040
statement {
4141
effect = "Allow"
42+
4243
principals {
4344
type = "AWS"
4445
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${var.meshcloud_account_id}:user/${var.meshcloud_account_service_user_name}"]
4546
}
47+
48+
dynamic "principals" {
49+
for_each = var.allow_federated_role ? [true] : []
50+
51+
content {
52+
type = "AWS"
53+
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${var.meshcloud_account_id}:role/${var.meshcloud_account_service_user_name}IdentityFederation"]
54+
}
55+
}
56+
4657
actions = ["sts:AssumeRole"]
4758
condition {
4859
test = "StringEquals"

modules/meshcloud-cost-explorer/ce-management-account-access/variables.tf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,8 @@ variable "privileged_external_id" {
1919
type = string
2020
description = "Privileged external ID for the meshfed-service to use"
2121
}
22+
23+
variable "allow_federated_role" {
24+
type = bool
25+
default = false
26+
}

modules/meshcloud-cost-explorer/ce-meshcloud-account-access/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
| Name | Version |
1111
|------|---------|
12-
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.37.0 |
12+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 2.7.0 |
1313

1414
## Modules
1515

@@ -21,24 +21,30 @@ No modules.
2121
|------|------|
2222
| [aws_iam_access_key.meshcloud_cost_explorer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_access_key) | resource |
2323
| [aws_iam_policy.meshcloud_cost_explorer_user](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
24+
| [aws_iam_role.assume_cost_explorer_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
25+
| [aws_iam_role_policy_attachment.meshfed_service](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
2426
| [aws_iam_user.meshcloud_cost_explorer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user) | resource |
2527
| [aws_iam_user_policy_attachment.meshcloud_cost_explorer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user_policy_attachment) | resource |
2628
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
2729
| [aws_iam_policy_document.meshcloud_cost_explorer_user_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
30+
| [aws_iam_policy_document.workload_identity_federation](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
2831
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
2932

3033
## Inputs
3134

3235
| Name | Description | Type | Default | Required |
3336
|------|-------------|------|---------|:--------:|
37+
| <a name="input_create_access_key"></a> [create\_access\_key](#input\_create\_access\_key) | Create access key for service account | `bool` | `true` | no |
3438
| <a name="input_management_account_id"></a> [management\_account\_id](#input\_management\_account\_id) | The ID of the Management Account. | `string` | n/a | yes |
3539
| <a name="input_management_account_service_role_name"></a> [management\_account\_service\_role\_name](#input\_management\_account\_service\_role\_name) | Name of the custom role in the management account used by the cost explorer user. | `string` | `"MeshCostExplorerServiceRole"` | no |
3640
| <a name="input_meshcloud_account_service_user_name"></a> [meshcloud\_account\_service\_user\_name](#input\_meshcloud\_account\_service\_user\_name) | Name of the user using cost explorer service to collect metering data. | `string` | `"meshcloud-cost-explorer-user"` | no |
3741
| <a name="input_privileged_external_id"></a> [privileged\_external\_id](#input\_privileged\_external\_id) | Privileged external ID for the cost-explorer-service to use | `string` | n/a | yes |
42+
| <a name="input_workload_identity_federation"></a> [workload\_identity\_federation](#input\_workload\_identity\_federation) | n/a | <pre>object({<br> issuer = string,<br> audience = string,<br> subject = string,<br> identity_provider_arn = string<br> })</pre> | `null` | no |
3843

3944
## Outputs
4045

4146
| Name | Description |
4247
|------|-------------|
4348
| <a name="output_aws_iam_keys"></a> [aws\_iam\_keys](#output\_aws\_iam\_keys) | AWS access and secret keys for cost explorer user. |
49+
| <a name="output_workload_identity_federation_role"></a> [workload\_identity\_federation\_role](#output\_workload\_identity\_federation\_role) | n/a |
4450
<!-- END_TF_DOCS -->

modules/meshcloud-cost-explorer/ce-meshcloud-account-access/data.tf

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,31 @@ data "aws_iam_policy_document" "meshcloud_cost_explorer_user_assume_role" {
1919
}
2020
}
2121
}
22+
23+
data "aws_iam_policy_document" "workload_identity_federation" {
24+
count = var.workload_identity_federation == null ? 0 : 1
25+
version = "2012-10-17"
26+
27+
statement {
28+
effect = "Allow"
29+
principals {
30+
type = "Federated"
31+
identifiers = [var.workload_identity_federation.identity_provider_arn]
32+
}
33+
actions = ["sts:AssumeRoleWithWebIdentity"]
34+
35+
condition {
36+
test = "StringEquals"
37+
variable = "${trimprefix(var.workload_identity_federation.issuer, "https://")}:aud"
38+
39+
values = [var.workload_identity_federation.audience]
40+
}
41+
42+
condition {
43+
test = "StringEquals"
44+
variable = "${trimprefix(var.workload_identity_federation.issuer, "https://")}:sub"
45+
46+
values = [var.workload_identity_federation.subject]
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)