Skip to content

Commit

Permalink
feat: biohub s3 readonly role (#669)
Browse files Browse the repository at this point in the history
* feat: biohub s3 readonly role

* removed mention of cloudfront

* test file

* updated type for s3 prefix

* changed variable s3 prefix to s3 name
  • Loading branch information
naihsuanshao authored Oct 31, 2024
1 parent f77c9a1 commit d64e240
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 0 deletions.
51 changes: 51 additions & 0 deletions aws-iam-role-s3-readonly/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# AWS IAM Role S3 Readonly

This module will create a role which is granted readonly control over AWS S3 buckets.

<!-- START -->
## Requirements

No requirements.

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | n/a |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_assume_role_policy"></a> [assume\_role\_policy](#module\_assume\_role\_policy) | ../aws-assume-role-policy | n/a |

## Resources

| Name | Type |
|------|------|
| [aws_iam_policy.s3](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role.role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.s3](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_policy_document.s3](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_env"></a> [env](#input\_env) | Env for tagging and naming. See [doc](../README.md#consistent-tagging) | `string` | n/a | yes |
| <a name="input_iam_path"></a> [iam\_path](#input\_iam\_path) | n/a | `string` | `"/"` | no |
| <a name="input_owner"></a> [owner](#input\_owner) | Owner for tagging and naming. See [doc](../README.md#consistent-tagging) | `string` | n/a | yes |
| <a name="input_project"></a> [project](#input\_project) | Project for tagging and naming. See [doc](../README.md#consistent-tagging) | `string` | n/a | yes |
| <a name="input_role_name"></a> [role\_name](#input\_role\_name) | Name of the role to create | `string` | n/a | yes |
| <a name="input_s3_bucket_prefixes"></a> [s3\_bucket\_prefixes](#input\_s3\_bucket\_prefixes) | Limits role permissions to buckets with specific prefixes. Empty for all buckets. | `list(any)` | <pre>[<br> ""<br>]</pre> | no |
| <a name="input_saml_idp_arns"></a> [saml\_idp\_arns](#input\_saml\_idp\_arns) | The AWS SAML IDP arns to establish a trust relationship. Ignored if empty or not provided. | `set(string)` | `[]` | no |
| <a name="input_service"></a> [service](#input\_service) | Service for tagging and naming. See [doc](../README.md#consistent-tagging) | `string` | n/a | yes |
| <a name="input_source_account_ids"></a> [source\_account\_ids](#input\_source\_account\_ids) | The source AWS account IDs to establish a trust relationship. Ignored if empty or not provided. | `set(string)` | `[]` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_role_arn"></a> [role\_arn](#output\_role\_arn) | n/a |
| <a name="output_role_name"></a> [role\_name](#output\_role\_name) | n/a |
<!-- END -->
67 changes: 67 additions & 0 deletions aws-iam-role-s3-readonly/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
locals {
tags = {
env = var.env
owner = var.owner
service = var.service
project = var.project
}
}

module "assume_role_policy" {
source = "../aws-assume-role-policy"
source_account_ids = var.source_account_ids
saml_idp_arns = var.saml_idp_arns
env = var.env
owner = var.owner
service = var.service
project = var.project
}

resource "aws_iam_role" "role" {
name = var.role_name
assume_role_policy = module.assume_role_policy.json
tags = local.tags
}

data "aws_iam_policy_document" "s3-bucket-readonly" {
statement {
sid = "GetFiles"
effect = "Allow"
actions = [
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersion"
]
resources = formatlist("arn:aws:s3:::%s*/*", var.s3_bucket_names)
}
statement {
sid = "ListBucket"
effect = "Allow"
actions = [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:ListBucketMultipartUploads"
]
resources = formatlist("arn:aws:s3:::%s*/*", var.s3_bucket_names)
}
statement {
sid = "ShowAllowedBuckets"
effect = "Allow"
actions = [
"s3:ListAllMyBuckets"
]
resources = toset(formatlist("arn:aws:s3:::%s", var.s3_bucket_names), formatlist("arn:aws:s3:::%s/*", var.s3_bucket_prefixes))
}
}

resource "aws_iam_policy" "s3" {
name = "${var.role_name}-s3"
description = "Provide access to s3 resources for a distribution ${var.role_name}"
policy = data.aws_iam_policy_document.s3-bucket-readonly.json
}

resource "aws_iam_role_policy_attachment" "s3" {
role = aws_iam_role.role.name
policy_arn = aws_iam_policy.s3.arn
}
42 changes: 42 additions & 0 deletions aws-iam-role-s3-readonly/module_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package test

import (
"fmt"
"testing"

"github.com/chanzuckerberg/go-misc/tftest"
"github.com/gruntwork-io/terratest/modules/random"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/require"
)

func TestAWSIAMRoleS3Readonly(t *testing.T) {
test := tftest.Test{
Setup: func(t *testing.T) *terraform.Options {
curAcct := tftest.AWSCurrentAccountID(t)

return tftest.Options(
tftest.IAMRegion,

map[string]interface{}{
"role_name": random.UniqueId(),
"iam_path": fmt.Sprintf("/%s/", random.UniqueId()),
"source_account_ids": []string{curAcct},
},
)
},
Validate: func(t *testing.T, options *terraform.Options) {
r := require.New(t)
region := options.EnvVars["AWS_DEFAULT_REGION"]
r.NotEmpty(region)
outputs := terraform.OutputAll(t, options)
r.NotEmpty(outputs)
roleName := outputs["role_name"].(string)
r.NotEmpty(roleName)
roleARN := outputs["role_arn"].(string)
r.NotEmpty(roleARN)
},
}

test.Run(t)
}
7 changes: 7 additions & 0 deletions aws-iam-role-s3-readonly/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "role_name" {
value = aws_iam_role.role.name
}

output "role_arn" {
value = aws_iam_role.role.arn
}
50 changes: 50 additions & 0 deletions aws-iam-role-s3-readonly/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
variable "role_name" {
type = string
description = "Name of the role to create"
}

variable "s3_bucket_names" {
type = set(string)
description = "Limits role permissions to buckets with specific prefixes. Empty for all buckets."

default = [
"",
]
}

variable "iam_path" {
type = string
default = "/"
}

variable "source_account_ids" {
type = set(string)
default = []
description = "The source AWS account IDs to establish a trust relationship. Ignored if empty or not provided."
}

variable "saml_idp_arns" {
type = set(string)
default = []
description = "The AWS SAML IDP arns to establish a trust relationship. Ignored if empty or not provided."
}

variable "project" {
type = string
description = "Project for tagging and naming. See [doc](../README.md#consistent-tagging)"
}

variable "env" {
type = string
description = "Env for tagging and naming. See [doc](../README.md#consistent-tagging)"
}

variable "service" {
type = string
description = "Service for tagging and naming. See [doc](../README.md#consistent-tagging)"
}

variable "owner" {
type = string
description = "Owner for tagging and naming. See [doc](../README.md#consistent-tagging)"
}

0 comments on commit d64e240

Please sign in to comment.