From 1f01db605029a94f6c0721b7126632bc10eaa428 Mon Sep 17 00:00:00 2001 From: Soya Miyoshi Date: Tue, 27 Feb 2024 16:18:27 +0900 Subject: [PATCH] Add NotInIP statement --- README.md | 70 ++++++++++++++++++----------------------------- docs/terraform.md | 1 + main.tf | 22 +++++++++++++++ variables.tf | 7 +++++ 4 files changed, 56 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 57774ecf..d8981230 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ - -# terraform-aws-s3-bucket +# terraform-aws-s3-bucket GitHub Action TestsLatest ReleaseSlack Community @@ -64,9 +63,9 @@ via Terraform remote state lookup, but the key will still be stored unencrypted --- > [!NOTE] -> This project is part of Cloud Posse's comprehensive ["SweetOps"](https://cpco.io/sweetops) approach towards DevOps. ->
Learn More -> +> This project is part of Cloud Posse's comprehensive ["SweetOps"](https://cpco.io/homepage?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=) approach towards DevOps. +>
Learn More +> > > > @@ -77,10 +76,10 @@ via Terraform remote state lookup, but the key will still be stored unencrypted > > It's 100% Open Source and licensed under the [APACHE2](LICENSE). > -> We literally have [*hundreds of terraform modules*][terraform_modules] that are Open Source and well-maintained. Check them out! +> We literally have [*hundreds of terraform modules*](https://cpco.io/terraform-modules?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=terraform_modules) that are Open Source and well-maintained. Check them out! >
-[![README Header][readme_header_img]][readme_header_link] + @@ -315,6 +314,7 @@ Available targets: | [s3\_replication\_permissions\_boundary\_arn](#input\_s3\_replication\_permissions\_boundary\_arn) | Permissions boundary ARN for the created IAM replication role. | `string` | `null` | no | | [s3\_replication\_rules](#input\_s3\_replication\_rules) | Specifies the replication rules for S3 bucket replication if enabled. You must also set s3\_replication\_enabled to true. |
list(object({
id = optional(string)
priority = optional(number)
prefix = optional(string)
status = optional(string, "Enabled")
# delete_marker_replication { status } had been flattened for convenience
delete_marker_replication_status = optional(string, "Disabled")
# Add the configuration as it appears in the resource, for consistency
# this nested version takes precedence if both are provided.
delete_marker_replication = optional(object({
status = string
}))

# destination_bucket is specified here rather than inside the destination object because before optional
# attributes, it made it easier to work with the Terraform type system and create a list of consistent type.
# It is preserved for backward compatibility, but the nested version takes priority if both are provided.
destination_bucket = optional(string) # destination bucket ARN, overrides s3_replica_bucket_arn

destination = object({
bucket = optional(string) # destination bucket ARN, overrides s3_replica_bucket_arn
storage_class = optional(string, "STANDARD")
# replica_kms_key_id at this level is for backward compatibility, and is overridden by the one in `encryption_configuration`
replica_kms_key_id = optional(string, "")
encryption_configuration = optional(object({
replica_kms_key_id = string
}))
access_control_translation = optional(object({
owner = string
}))
# account_id is for backward compatibility, overridden by account
account_id = optional(string)
account = optional(string)
# For convenience, specifying either metrics or replication_time enables both
metrics = optional(object({
event_threshold = optional(object({
minutes = optional(number, 15) # Currently 15 is the only valid number
}), { minutes = 15 })
status = optional(string, "Enabled")
}), { status = "Disabled" })
# To preserve backward compatibility, Replication Time Control (RTC) is automatically enabled
# when metrics are enabled. To enable metrics without RTC, you must explicitly configure
# replication_time.status = "Disabled".
replication_time = optional(object({
time = optional(object({
minutes = optional(number, 15) # Currently 15 is the only valid number
}), { minutes = 15 })
status = optional(string)
}))
})

source_selection_criteria = optional(object({
replica_modifications = optional(object({
status = string # Either Enabled or Disabled
}))
sse_kms_encrypted_objects = optional(object({
status = optional(string)
}))
}))
# filter.prefix overrides top level prefix
filter = optional(object({
prefix = optional(string)
tags = optional(map(string), {})
}))
}))
| `null` | no | | [s3\_replication\_source\_roles](#input\_s3\_replication\_source\_roles) | Cross-account IAM Role ARNs that will be allowed to perform S3 replication to this bucket (for replication within the same AWS account, it's not necessary to adjust the bucket policy). | `list(string)` | `[]` | no | +| [source\_ip\_allow\_list](#input\_source\_ip\_allow\_list) | List of IP addresses to allow to perform all actions to the bucket | `list(string)` | `[]` | no | | [source\_policy\_documents](#input\_source\_policy\_documents) | List of IAM policy documents (in JSON) that are merged together into the exported document.
Statements defined in source\_policy\_documents must have unique SIDs.
Statement having SIDs that match policy SIDs generated by this module will override them. | `list(string)` | `[]` | no | | [sse\_algorithm](#input\_sse\_algorithm) | The server-side encryption algorithm to use. Valid values are `AES256` and `aws:kms` | `string` | `"AES256"` | no | | [ssm\_base\_path](#input\_ssm\_base\_path) | The base path for SSM parameters where created IAM user's access key is stored | `string` | `"/s3_user/"` | no | @@ -380,7 +380,7 @@ Please use the [issue tracker](https://github.com/cloudposse/terraform-aws-s3-bu ### πŸ’» Developing If you are interested in being a contributor and want to get involved in developing this project or help out with Cloud Posse's other projects, we would love to hear from you! -Hit us up in [Slack][slack], in the `#cloudposse` channel. +Hit us up in [Slack](https://cpco.io/slack?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=slack), in the `#cloudposse` channel. In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow. 1. Review our [Code of Conduct](https://github.com/cloudposse/terraform-aws-s3-bucket/?tab=coc-ov-file#code-of-conduct) and [Contributor Guidelines](https://github.com/cloudposse/.github/blob/main/CONTRIBUTING.md). @@ -394,35 +394,35 @@ In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow. ### 🌎 Slack Community -Join our [Open Source Community][slack] on Slack. It's **FREE** for everyone! Our "SweetOps" community is where you get to talk with others who share a similar vision for how to rollout and manage infrastructure. This is the best place to talk shop, ask questions, solicit feedback, and work together as a community to build totally *sweet* infrastructure. +Join our [Open Source Community](https://cpco.io/slack?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=slack) on Slack. It's **FREE** for everyone! Our "SweetOps" community is where you get to talk with others who share a similar vision for how to rollout and manage infrastructure. This is the best place to talk shop, ask questions, solicit feedback, and work together as a community to build totally *sweet* infrastructure. ### πŸ“° Newsletter -Sign up for [our newsletter][newsletter] and join 3,000+ DevOps engineers, CTOs, and founders who get insider access to the latest DevOps trends, so you can always stay in the know. +Sign up for [our newsletter](https://cpco.io/newsletter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=newsletter) and join 3,000+ DevOps engineers, CTOs, and founders who get insider access to the latest DevOps trends, so you can always stay in the know. Dropped straight into your Inbox every week β€” and usually a 5-minute read. -### πŸ“† Office Hours +### πŸ“† Office Hours -[Join us every Wednesday via Zoom][office_hours] for your weekly dose of insider DevOps trends, AWS news and Terraform insights, all sourced from our SweetOps community, plus a _live Q&A_ that you can’t find anywhere else. +[Join us every Wednesday via Zoom](https://cloudposse.com/office-hours?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=office_hours) for your weekly dose of insider DevOps trends, AWS news and Terraform insights, all sourced from our SweetOps community, plus a _live Q&A_ that you can’t find anywhere else. It's **FREE** for everyone! ## About -This project is maintained by [Cloud Posse, LLC][website]. - +This project is maintained by Cloud Posse, LLC. + -We are a [**DevOps Accelerator**][commercial_support] for funded startups and enterprises. +We are a [**DevOps Accelerator**](https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=commercial_support) for funded startups and enterprises. Use our ready-to-go terraform architecture blueprints for AWS to get up and running quickly. We build it with you. You own everything. Your team wins. Plus, we stick around until you succeed. -[![Learn More](https://img.shields.io/badge/learn%20more-success.svg?style=for-the-badge)][commercial_support] +Learn More *Your team can operate like a pro today.* Ensure that your team succeeds by using our proven process and turnkey blueprints. Plus, we stick around until you succeed.
- πŸ“š What's included? + πŸ“š See What's Included - **Reference Architecture.** You'll get everything you need from the ground up built using 100% infrastructure as code. - **Deployment Strategy.** You'll have a battle-tested deployment strategy using GitHub Actions that's automated and repeatable. @@ -436,16 +436,18 @@ Ensure that your team succeeds by using our proven process and turnkey blueprint - **Bug Fixes.** We'll rapidly work with you to fix any bugs in our projects.
-[![README Commercial Support][readme_commercial_support_img]][readme_commercial_support_link] + ## License -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg?style=for-the-badge)](https://opensource.org/licenses/Apache-2.0) +License
Preamble to the Apache License, Version 2.0

+ Complete license is available in the [`LICENSE`](LICENSE) file. + ```text Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file @@ -471,28 +473,8 @@ under the License. All other trademarks referenced herein are the property of their respective owners. --- Copyright Β© 2017-2024 [Cloud Posse, LLC](https://cpco.io/copyright) -[![README Footer][readme_footer_img]][readme_footer_link] -[![Beacon][beacon]][website] - - [logo]: https://cloudposse.com/logo-300x69.svg - [docs]: https://cpco.io/docs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=docs - [website]: https://cpco.io/homepage?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=website - [github]: https://cpco.io/github?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=github - [jobs]: https://cpco.io/jobs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=jobs - [hire]: https://cpco.io/hire?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=hire - [slack]: https://cpco.io/slack?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=slack - [twitter]: https://cpco.io/twitter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=twitter - [office_hours]: https://cloudposse.com/office-hours?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=office_hours - [newsletter]: https://cpco.io/newsletter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=newsletter - [email]: https://cpco.io/email?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=email - [commercial_support]: https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=commercial_support - [we_love_open_source]: https://cpco.io/we-love-open-source?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=we_love_open_source - [terraform_modules]: https://cpco.io/terraform-modules?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=terraform_modules - [readme_header_img]: https://cloudposse.com/readme/header/img - [readme_header_link]: https://cloudposse.com/readme/header/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=readme_header_link - [readme_footer_img]: https://cloudposse.com/readme/footer/img - [readme_footer_link]: https://cloudposse.com/readme/footer/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=readme_footer_link - [readme_commercial_support_img]: https://cloudposse.com/readme/commercial-support/img - [readme_commercial_support_link]: https://cloudposse.com/readme/commercial-support/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-s3-bucket&utm_content=readme_commercial_support_link - [beacon]: https://ga-beacon.cloudposse.com/UA-76589703-4/cloudposse/terraform-aws-s3-bucket?pixel&cs=github&cm=readme&an=terraform-aws-s3-bucket - + + +README footer + +Beacon diff --git a/docs/terraform.md b/docs/terraform.md index 3ff1e53a..77260f0c 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -99,6 +99,7 @@ | [s3\_replication\_permissions\_boundary\_arn](#input\_s3\_replication\_permissions\_boundary\_arn) | Permissions boundary ARN for the created IAM replication role. | `string` | `null` | no | | [s3\_replication\_rules](#input\_s3\_replication\_rules) | Specifies the replication rules for S3 bucket replication if enabled. You must also set s3\_replication\_enabled to true. |
list(object({
id = optional(string)
priority = optional(number)
prefix = optional(string)
status = optional(string, "Enabled")
# delete_marker_replication { status } had been flattened for convenience
delete_marker_replication_status = optional(string, "Disabled")
# Add the configuration as it appears in the resource, for consistency
# this nested version takes precedence if both are provided.
delete_marker_replication = optional(object({
status = string
}))

# destination_bucket is specified here rather than inside the destination object because before optional
# attributes, it made it easier to work with the Terraform type system and create a list of consistent type.
# It is preserved for backward compatibility, but the nested version takes priority if both are provided.
destination_bucket = optional(string) # destination bucket ARN, overrides s3_replica_bucket_arn

destination = object({
bucket = optional(string) # destination bucket ARN, overrides s3_replica_bucket_arn
storage_class = optional(string, "STANDARD")
# replica_kms_key_id at this level is for backward compatibility, and is overridden by the one in `encryption_configuration`
replica_kms_key_id = optional(string, "")
encryption_configuration = optional(object({
replica_kms_key_id = string
}))
access_control_translation = optional(object({
owner = string
}))
# account_id is for backward compatibility, overridden by account
account_id = optional(string)
account = optional(string)
# For convenience, specifying either metrics or replication_time enables both
metrics = optional(object({
event_threshold = optional(object({
minutes = optional(number, 15) # Currently 15 is the only valid number
}), { minutes = 15 })
status = optional(string, "Enabled")
}), { status = "Disabled" })
# To preserve backward compatibility, Replication Time Control (RTC) is automatically enabled
# when metrics are enabled. To enable metrics without RTC, you must explicitly configure
# replication_time.status = "Disabled".
replication_time = optional(object({
time = optional(object({
minutes = optional(number, 15) # Currently 15 is the only valid number
}), { minutes = 15 })
status = optional(string)
}))
})

source_selection_criteria = optional(object({
replica_modifications = optional(object({
status = string # Either Enabled or Disabled
}))
sse_kms_encrypted_objects = optional(object({
status = optional(string)
}))
}))
# filter.prefix overrides top level prefix
filter = optional(object({
prefix = optional(string)
tags = optional(map(string), {})
}))
}))
| `null` | no | | [s3\_replication\_source\_roles](#input\_s3\_replication\_source\_roles) | Cross-account IAM Role ARNs that will be allowed to perform S3 replication to this bucket (for replication within the same AWS account, it's not necessary to adjust the bucket policy). | `list(string)` | `[]` | no | +| [source\_ip\_allow\_list](#input\_source\_ip\_allow\_list) | List of IP addresses to allow to perform all actions to the bucket | `list(string)` | `[]` | no | | [source\_policy\_documents](#input\_source\_policy\_documents) | List of IAM policy documents (in JSON) that are merged together into the exported document.
Statements defined in source\_policy\_documents must have unique SIDs.
Statement having SIDs that match policy SIDs generated by this module will override them. | `list(string)` | `[]` | no | | [sse\_algorithm](#input\_sse\_algorithm) | The server-side encryption algorithm to use. Valid values are `AES256` and `aws:kms` | `string` | `"AES256"` | no | | [ssm\_base\_path](#input\_ssm\_base\_path) | The base path for SSM parameters where created IAM user's access key is stored | `string` | `"/s3_user/"` | no | diff --git a/main.tf b/main.tf index cc899c8f..a34770b9 100644 --- a/main.tf +++ b/main.tf @@ -469,6 +469,28 @@ data "aws_iam_policy_document" "bucket_policy" { } } } + + dynamic "statement" { + for_each = length(var.source_ip_allow_list) > 0 ? [1] : [] + + content { + sid = "AllowIPPrincipals" + effect = "Deny" + actions = ["s3:*"] + resources = [local.bucket_arn, "${local.bucket_arn}/*"] + principals { + identifiers = ["*"] + type = "*" + } + condition { + test = "NotIpAddress" + variable = "aws:SourceIp" + values = var.source_ip_allow_list + } + } + + } + } data "aws_iam_policy_document" "aggregated_policy" { diff --git a/variables.tf b/variables.tf index f9511615..bad11017 100644 --- a/variables.tf +++ b/variables.tf @@ -411,6 +411,13 @@ variable "privileged_principal_actions" { nullable = false } +variable "source_ip_allow_list" { + type = list(string) + default = [] + description = "List of IP addresses to allow to perform all actions to the bucket" + nullable = false +} + variable "transfer_acceleration_enabled" { type = bool default = false