Skip to content

Commit

Permalink
Merge pull request #2 from truefoundry/iam-role
Browse files Browse the repository at this point in the history
Default support for IAM role with namespace prefix in policies
  • Loading branch information
dunefro authored Nov 28, 2023
2 parents a280413 + 010a4c6 commit cc78805
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 60 deletions.
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@ Truefoundry AWS platform features

| Name | Type |
|------|------|
| [aws_iam_access_key.truefoundry_platform_user_keys](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/resources/iam_access_key) | resource |
| [aws_iam_policy.truefoundry_platform_feature_user_ecr_policy](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/resources/iam_policy) | resource |
| [aws_iam_policy.truefoundry_platform_feature_user_s3_policy](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/resources/iam_policy) | resource |
| [aws_iam_policy.truefoundry_platform_feature_user_ssm_policy](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/resources/iam_policy) | resource |
| [aws_iam_user.truefoundry_platform_user](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/resources/iam_user) | resource |
| [aws_iam_user_policy_attachment.truefoundry_platform_user_ecr_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/resources/iam_user_policy_attachment) | resource |
| [aws_iam_user_policy_attachment.truefoundry_platform_user_s3_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/resources/iam_user_policy_attachment) | resource |
| [aws_iam_user_policy_attachment.truefoundry_platform_user_ssm_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/resources/iam_user_policy_attachment) | resource |
| [aws_iam_role.truefoundry_platform_feature_iam_role](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.truefoundry_platform_user_ecr_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.truefoundry_platform_user_s3_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.truefoundry_platform_user_ssm_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_policy_document.truefoundry_platform_feature_user_ecr_policy_document](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.truefoundry_platform_feature_user_s3_policy_document](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.truefoundry_platform_feature_user_ssm_policy_document](https://registry.terraform.io/providers/hashicorp/aws/5.14.0/docs/data-sources/iam_policy_document) | data source |
Expand All @@ -44,29 +43,30 @@ Truefoundry AWS platform features
| <a name="input_aws_account_id"></a> [aws\_account\_id](#input\_aws\_account\_id) | AWS account id | `string` | n/a | yes |
| <a name="input_aws_region"></a> [aws\_region](#input\_aws\_region) | AWS region | `string` | n/a | yes |
| <a name="input_blob_storage_cors_origins"></a> [blob\_storage\_cors\_origins](#input\_blob\_storage\_cors\_origins) | List of CORS origins for Mlfoundry bucket | `list(string)` | <pre>[<br> "*"<br>]</pre> | no |
| <a name="input_blob_storage_enable_override"></a> [blob\_storage\_enable\_override](#input\_blob\_storage\_enable\_override) | Enable overriding name of s3 bucket. This will only be used if feature\_blob\_storage\_enabled is enabled. You need to pass s3\_override\_name to pass the bucket name | `bool` | `false` | no |
| <a name="input_blob_storage_enable_override"></a> [blob\_storage\_enable\_override](#input\_blob\_storage\_enable\_override) | Enable overriding the name of s3 bucket. This will only be used if feature\_blob\_storage\_enabled is enabled. You need to pass s3\_override\_name to pass the bucket name | `bool` | `false` | no |
| <a name="input_blob_storage_encryption_algorithm"></a> [blob\_storage\_encryption\_algorithm](#input\_blob\_storage\_encryption\_algorithm) | Algorithm used for encrypting the default bucket. | `string` | `"AES256"` | no |
| <a name="input_blob_storage_encryption_key_arn"></a> [blob\_storage\_encryption\_key\_arn](#input\_blob\_storage\_encryption\_key\_arn) | ARN of the key used to encrypt the bucket. Only needed if you set aws:kms as encryption algorithm. | `string` | `null` | no |
| <a name="input_blob_storage_force_destroy"></a> [blob\_storage\_force\_destroy](#input\_blob\_storage\_force\_destroy) | Force destroy for mlfoundry s3 bucket | `bool` | `true` | no |
| <a name="input_blob_storage_override_name"></a> [blob\_storage\_override\_name](#input\_blob\_storage\_override\_name) | S3 bucket name. Only used if s3\_enable\_override is enabled | `string` | `""` | no |
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | Name of the EKS cluster | `string` | n/a | yes |
| <a name="input_control_plane_roles"></a> [control\_plane\_roles](#input\_control\_plane\_roles) | Control plane roles that can assume your platform role | `list(string)` | <pre>[<br> "arn:aws:iam::416964291864:role/tfy-ctl-euwe1-production-truefoundry-deps"<br>]</pre> | no |
| <a name="input_feature_blob_storage_enabled"></a> [feature\_blob\_storage\_enabled](#input\_feature\_blob\_storage\_enabled) | Enable blob storage feature in the platform | `bool` | `true` | no |
| <a name="input_feature_docker_registry_enabled"></a> [feature\_docker\_registry\_enabled](#input\_feature\_docker\_registry\_enabled) | Enable docker registry feature in the platform | `bool` | `true` | no |
| <a name="input_feature_secrets_enabled"></a> [feature\_secrets\_enabled](#input\_feature\_secrets\_enabled) | Enable secrets manager feature in the platform | `bool` | `true` | no |
| <a name="input_platform_feature_enabled"></a> [platform\_feature\_enabled](#input\_platform\_feature\_enabled) | Enable platform features like docker registry, secrets manager and blob storage | `bool` | `true` | no |
| <a name="input_platform_user_force_destroy"></a> [platform\_user\_force\_destroy](#input\_platform\_user\_force\_destroy) | Enable force destroy of the user | `bool` | `true` | no |
| <a name="input_platform_role_enable_override"></a> [platform\_role\_enable\_override](#input\_platform\_role\_enable\_override) | Enable overriding the platform role name. You need to pass s3\_override\_name to pass the bucket name | `bool` | `false` | no |
| <a name="input_platform_role_override_name"></a> [platform\_role\_override\_name](#input\_platform\_role\_override\_name) | Platform IAM role name which will have access to S3 bucket, SSM and ECR | `string` | `""` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_platform_user_access_key"></a> [platform\_user\_access\_key](#output\_platform\_user\_access\_key) | The user access key ID |
| <a name="output_platform_user_arn"></a> [platform\_user\_arn](#output\_platform\_user\_arn) | The user IAM resource arn |
| <a name="output_platform_iam_role_arn"></a> [platform\_iam\_role\_arn](#output\_platform\_iam\_role\_arn) | The IAM role resource arn |
| <a name="output_platform_iam_role_assume_role_arns"></a> [platform\_iam\_role\_assume\_role\_arns](#output\_platform\_iam\_role\_assume\_role\_arns) | The IAM role arns which has been assume by platform\_iam\_role |
| <a name="output_platform_iam_role_name"></a> [platform\_iam\_role\_name](#output\_platform\_iam\_role\_name) | Then name of the IAM role |
| <a name="output_platform_iam_role_policy_arns"></a> [platform\_iam\_role\_policy\_arns](#output\_platform\_iam\_role\_policy\_arns) | The list of ARNs of policies directly assigned to the IAM user |
| <a name="output_platform_user_bucket_arn"></a> [platform\_user\_bucket\_arn](#output\_platform\_user\_bucket\_arn) | The bucket's arn |
| <a name="output_platform_user_bucket_name"></a> [platform\_user\_bucket\_name](#output\_platform\_user\_bucket\_name) | The bucket's ID/name |
| <a name="output_platform_user_ecr_url"></a> [platform\_user\_ecr\_url](#output\_platform\_user\_ecr\_url) | The ECR url to connect |
| <a name="output_platform_user_name"></a> [platform\_user\_name](#output\_platform\_user\_name) | The user's name |
| <a name="output_platform_user_secret_key"></a> [platform\_user\_secret\_key](#output\_platform\_user\_secret\_key) | The user secret key |
| <a name="output_policy_arns"></a> [policy\_arns](#output\_policy\_arns) | The list of ARNs of policies directly assigned to the IAM user |
<!-- END_TF_DOCS -->
2 changes: 1 addition & 1 deletion buckets.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module "truefoundry_bucket" {
version = "3.15.0"

bucket = var.blob_storage_enable_override ? var.blob_storage_override_name : null
bucket_prefix = var.blob_storage_enable_override ? null : trimsuffix(substr(local.truefoundry_unique_name, 0, 37), "-")
bucket_prefix = var.blob_storage_enable_override ? null : trimsuffix(substr(local.bucket_name, 0, 37), "-")

force_destroy = var.blob_storage_force_destroy

Expand Down
61 changes: 36 additions & 25 deletions iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ data "aws_iam_policy_document" "truefoundry_platform_feature_user_ssm_policy_doc
"ssm:GetParameterHistory"
]
resources = [
"*"
"arn:aws:ssm:${var.aws_region}:${var.aws_account_id}:parameter/tfy-secret/*"
]
}
}
Expand All @@ -41,9 +41,7 @@ data "aws_iam_policy_document" "truefoundry_platform_feature_user_ecr_policy_doc
"ecr:GetLifecyclePolicyPreview",
"ecr:CreateRepository",
"ecr:GetDownloadUrlForLayer",
"ecr:DescribeRegistry",
"ecr:DescribeImageReplicationStatus",
"ecr:GetAuthorizationToken",
"ecr:ListTagsForResource",
"ecr:BatchGetRepositoryScanningConfiguration",
"ecr:GetRegistryScanningConfiguration",
Expand All @@ -59,12 +57,20 @@ data "aws_iam_policy_document" "truefoundry_platform_feature_user_ecr_policy_doc
"ecr:DescribeImages",
"ecr:DeleteRepository",
"ecr:UploadLayerPart",
"sts:GetServiceBearerToken"
]

resources = [
"*"
"arn:aws:ecr:${var.aws_region}:${var.aws_account_id}:repository/tfy-*"
]
}
statement {
effect = "Allow"
actions = [
"ecr:DescribeRegistry",
"ecr:GetAuthorizationToken",
"sts:GetServiceBearerToken"
]
resources = ["*"]
}
}

Expand Down Expand Up @@ -94,39 +100,44 @@ resource "aws_iam_policy" "truefoundry_platform_feature_user_ecr_policy" {


################################################################################
# IAM user
# IAM role
################################################################################

resource "aws_iam_user" "truefoundry_platform_user" {
count = var.platform_feature_enabled ? 1 : 0

name = "${local.truefoundry_unique_name}-user"
path = "/truefoundry/"
force_destroy = var.platform_user_force_destroy
tags = local.tags
}


resource "aws_iam_access_key" "truefoundry_platform_user_keys" {
count = var.platform_feature_enabled ? 1 : 0
resource "aws_iam_role" "truefoundry_platform_feature_iam_role" {
count = var.platform_feature_enabled ? 1 : 0
name = var.platform_role_enable_override ? var.platform_role_override_name : "${local.truefoundry_unique_name}-iam-role"
description = "IAM role for TrueFoundry to access S3 bucket, SSM and ECR"
force_detach_policies = true
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [for role in var.control_plane_roles : {
Action = "sts:AssumeRole"
Effect = "Allow"
Sid = ""
Principal = {
AWS = role
}
}
]
})

user = aws_iam_user.truefoundry_platform_user[0].name
tags = local.tags
}

resource "aws_iam_user_policy_attachment" "truefoundry_platform_user_s3_policy_attachment" {
resource "aws_iam_role_policy_attachment" "truefoundry_platform_user_s3_policy_attachment" {
count = var.platform_feature_enabled ? var.feature_blob_storage_enabled ? 1 : 0 : 0
user = aws_iam_user.truefoundry_platform_user[0].name
role = aws_iam_role.truefoundry_platform_feature_iam_role[0].name
policy_arn = aws_iam_policy.truefoundry_platform_feature_user_s3_policy[0].arn
}

resource "aws_iam_user_policy_attachment" "truefoundry_platform_user_ssm_policy_attachment" {
resource "aws_iam_role_policy_attachment" "truefoundry_platform_user_ssm_policy_attachment" {
count = var.platform_feature_enabled ? var.feature_secrets_enabled ? 1 : 0 : 0
user = aws_iam_user.truefoundry_platform_user[0].name
role = aws_iam_role.truefoundry_platform_feature_iam_role[0].name
policy_arn = aws_iam_policy.truefoundry_platform_feature_user_ssm_policy[0].arn
}

resource "aws_iam_user_policy_attachment" "truefoundry_platform_user_ecr_policy_attachment" {
resource "aws_iam_role_policy_attachment" "truefoundry_platform_user_ecr_policy_attachment" {
count = var.platform_feature_enabled ? var.feature_docker_registry_enabled ? 1 : 0 : 0
user = aws_iam_user.truefoundry_platform_user[0].name
role = aws_iam_role.truefoundry_platform_feature_iam_role[0].name
policy_arn = aws_iam_policy.truefoundry_platform_feature_user_ecr_policy[0].arn
}
3 changes: 2 additions & 1 deletion locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ locals {
},
var.tags
)
truefoundry_unique_name = var.blob_storage_enable_override ? var.blob_storage_override_name : "${var.cluster_name}-platform"
truefoundry_unique_name = "${var.cluster_name}-platform"
bucket_name = var.blob_storage_enable_override ? var.blob_storage_override_name : "${var.cluster_name}-ml"
policy_arns = [
var.feature_blob_storage_enabled ? aws_iam_policy.truefoundry_platform_feature_user_s3_policy[0].arn : null,
var.feature_secrets_enabled ? aws_iam_policy.truefoundry_platform_feature_user_ssm_policy[0].arn : null,
Expand Down
26 changes: 10 additions & 16 deletions output.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,22 @@
# User details
################################################################################

output "platform_user_name" {
description = "The user's name"
value = var.platform_feature_enabled ? aws_iam_user.truefoundry_platform_user[0].name : ""
output "platform_iam_role_name" {
description = "Then name of the IAM role"
value = var.platform_feature_enabled ? aws_iam_role.truefoundry_platform_feature_iam_role[0].name : ""
}

output "platform_user_arn" {
description = "The user IAM resource arn"
value = var.platform_feature_enabled ? aws_iam_user.truefoundry_platform_user[0].arn : ""
output "platform_iam_role_arn" {
description = "The IAM role resource arn"
value = var.platform_feature_enabled ? aws_iam_role.truefoundry_platform_feature_iam_role[0].arn : ""
}

output "platform_user_access_key" {
description = "The user access key ID"
value = var.platform_feature_enabled ? aws_iam_access_key.truefoundry_platform_user_keys[0].id : ""
output "platform_iam_role_assume_role_arns" {
description = "The IAM role arns which has been assume by platform_iam_role"
value = var.platform_feature_enabled ? var.control_plane_roles : []
}

output "platform_user_secret_key" {
description = "The user secret key"
value = var.platform_feature_enabled ? aws_iam_access_key.truefoundry_platform_user_keys[0].secret : ""
sensitive = true
}

output "policy_arns" {
output "platform_iam_role_policy_arns" {
description = "The list of ARNs of policies directly assigned to the IAM user"
value = local.truefoundry_platform_user_policy_arns
}
Expand Down
22 changes: 17 additions & 5 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,25 @@ variable "cluster_name" {
}

################################################################################
# IAM user
# IAM role
################################################################################

variable "platform_user_force_destroy" {
description = "Enable force destroy of the user"
variable "control_plane_roles" {
description = "Control plane roles that can assume your platform role"
type = list(string)
default = ["arn:aws:iam::416964291864:role/tfy-ctl-euwe1-production-truefoundry-deps"]
}

variable "platform_role_enable_override" {
description = "Enable overriding the platform role name. You need to pass s3_override_name to pass the bucket name"
type = bool
default = true
default = false
}

variable "platform_role_override_name" {
description = "Platform IAM role name which will have access to S3 bucket, SSM and ECR"
type = string
default = ""
}

################################################################################
Expand All @@ -50,7 +62,7 @@ variable "feature_blob_storage_enabled" {
}

variable "blob_storage_enable_override" {
description = "Enable overriding name of s3 bucket. This will only be used if feature_blob_storage_enabled is enabled. You need to pass s3_override_name to pass the bucket name"
description = "Enable overriding the name of s3 bucket. This will only be used if feature_blob_storage_enabled is enabled. You need to pass s3_override_name to pass the bucket name"
type = bool
default = false
}
Expand Down

0 comments on commit cc78805

Please sign in to comment.