Skip to content

Commit

Permalink
Update large inputs to objects with optional attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
Nuru committed Aug 26, 2023
1 parent 2419a03 commit 93d3b13
Show file tree
Hide file tree
Showing 9 changed files with 268 additions and 257 deletions.
90 changes: 33 additions & 57 deletions README.md

Large diffs are not rendered by default.

76 changes: 26 additions & 50 deletions README.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,31 +69,42 @@ description: |-
This module creates an S3 bucket with support for versioning, lifecycles, object locks, replication, encryption, ACL,
bucket object policies, and static website hosting.
If `user_enabled` variable is set to `true`, the module will provision a basic IAM user with permissions to access the bucket.
This basic IAM system user is suitable for CI/CD systems (_e.g._ TravisCI, CircleCI) or systems which are *external* to AWS that cannot leverage
[AWS IAM Instance Profiles](http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html)
or [AWS OIDC](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html) to authenticate and
do not already have IAM credentials. Users or systems that have IAM credentials should either be granted access directly based on
their IAM identity via `privileged_principal_arns` or be allowed to assume an IAM role with access.
We do not recommend creating IAM users this way for any other purpose.
For backward compatibility, it sets the S3 bucket ACL to `private` and the `s3_object_ownership`
to `ObjectWriter`. Moving forward, setting `s3_object_ownership` to `BucketOwnerEnforced` is recommended,
and doing so automatically disables the ACL.
This module blocks public access to the bucket by default. See `block_public_acls`, `block_public_policy`,
`ignore_public_acls`, and `restrict_public_buckets` to change the settings. See [AWS documentation](https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html)
for more details.
for more details.
This module can optionally create an IAM User with access to the S3 bucket. This is inherently insecure in that
to enable anyone to become the User, access keys must be generated, and anything generated by Terraform is stored
unencrypted in the Terraform state. See the [Terraform documentation](https://www.terraform.io/docs/state/sensitive-data.html) for more details
The best way to grant access to the bucket is to grant one or more IAM Roles access to the bucket via `privileged_principal_arns`.
This IAM Role can be assumed by EC2 instances via their Instance Profile, or Kubernetes (EKS) services using
[IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html).
Entities outside of AWS can assume the Role via [OIDC](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html).
(See [this example of connecting GitHub](https://aws.amazon.com/blogs/security/use-iam-roles-to-connect-github-actions-to-actions-in-aws/)
to enable GitHub actions to assume AWS IAM roles, or use [this Cloud Posse component](https://github.com/cloudposse/terraform-aws-components/tree/main/modules/github-oidc-provider)
if you are already using the Cloud Posse reference architecture.)
If neither of those approaches work, then as a last resort you can set `user_enabled = true` and
this module will provision a basic IAM user with permissions to access the bucket.
We do not recommend creating IAM users this way for any other purpose.
If an IAM user is created, the IAM user name is constructed using [terraform-null-label](https://github.com/cloudposse/terraform-null-label)
and some input is required. The simplest input is `name`. By default the name will be converted to lower case
and all non-alphanumeric characters except for hyphen will be removed. See the documentation for `terraform-null-label`
to learn how to override these defaults if desired.
If an AWS Access Key is created, it is stored either in SSM Parameter Store or is provided as a module output,
but not both. Using SSM Parameter Store is recommended because module outputs are stored in plaintext in
the Terraform state file.
but not both. Using SSM Parameter Store is recommended because that will keep the secret from being easily accessible
via Terraform remote state lookup, but the key will still be stored unencrypted in the Terraform state in any case.
# How to use this project
usage: |-
Using a [canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html).
Using [BucketOwnerEnforced](https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html#object-ownership-overview)
```hcl
module "s3_bucket" {
Expand All @@ -104,7 +115,7 @@ usage: |-
stage = "test"
namespace = "eg"
acl = "private"
s3_object_ownership = "BucketOwnerEnforced"
enabled = true
user_enabled = false
versioning_enabled = false
Expand Down Expand Up @@ -156,41 +167,6 @@ usage: |-
}
```
Using [grants](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html) to enable access
to another account and for logging, and incorporating the above lifecycle configuration.
```hcl
module "s3_bucket" {
source = "cloudposse/s3-bucket/aws"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"
name = "app"
stage = "test"
namespace = "eg"
acl = ""
enabled = true
user_enabled = false
versioning_enabled = true
lifecycle_configuration_rules = local.lifecycle_configuration_rules
grants = [
{
id = "012abc345def678ghi901" # Canonical user or account id
type = "CanonicalUser"
permissions = ["FULL_CONTROL"]
uri = null
},
{
id = null
type = "Group"
permissions = ["READ", "WRITE"]
uri = "http://acs.amazonaws.com/groups/s3/LogDelivery"
},
]
}
```
Allowing specific principal ARNs to perform actions on the bucket:
Expand All @@ -199,7 +175,7 @@ usage: |-
source = "cloudposse/s3-bucket/aws"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"
acl = "private"
s3_object_ownership = "BucketOwnerEnforced"
enabled = true
user_enabled = true
versioning_enabled = false
Expand Down
16 changes: 8 additions & 8 deletions docs/terraform.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/complete/versions.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
terraform {
required_version = ">= 1.0"
required_version = ">= 1.3.0"

required_providers {
aws = {
Expand Down
6 changes: 4 additions & 2 deletions lifecycle.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
locals {
/*
# full_lifecycle_rule_schema is just for documentation, not actually used.
full_lifecycle_rule_schema = {
enabled = true # bool
Expand All @@ -23,7 +24,7 @@ locals {
}
transition = [{
date = null # string
days = null # integer >= 0
days = null # integer > 0
storage_class = null # string/enum, one of GLACIER, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, DEEP_ARCHIVE, GLACIER_IR.
}]
noncurrent_version_transition = [{
Expand All @@ -32,6 +33,7 @@ locals {
storage_class = null # string/enum, one of GLACIER, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, DEEP_ARCHIVE, GLACIER_IR.
}]
}
*/

lifecycle_configuration_rules = var.lifecycle_configuration_rules == null ? [] : var.lifecycle_configuration_rules
# Normalize the input, filling in missing fields
Expand Down Expand Up @@ -156,7 +158,7 @@ locals {

resource "aws_s3_bucket_lifecycle_configuration" "default" {
count = local.enabled && length(local.lc_rules) > 0 ? 1 : 0
bucket = join("", aws_s3_bucket.default[*].id)
bucket = local.bucket_id

dynamic "rule" {
for_each = local.lc_rules
Expand Down
Loading

0 comments on commit 93d3b13

Please sign in to comment.