-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Geartrixy/master
initial commit
- Loading branch information
Showing
29 changed files
with
807 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
## Release Version: 0.0.1 | ||
|
||
BACKWARDS INCOMPATIBILITIES / NOTES: | ||
|
||
* Tested with terraform v0.11.7 | ||
|
||
INITIAL RELEASE: | ||
|
||
* S3 Bucket: supports object versioning, lifecycle policy (on whole bucket) to remove object versions older than X days | ||
* IAM Management Users: Admin, Sync | ||
* Standard Users: User keys (directories) with KMS encryption for uploads | ||
|
||
IMPROVEMENTS: | ||
|
||
* N/A | ||
|
||
BUG FIXES: | ||
|
||
* N/A |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,159 @@ | ||
# terraform-aws-s3-with-iam-access | ||
# AWS S3 Bucket with IAM Access Module | ||
Terraform module which creates an S3 bucket with varying levels of access for IAM users. | ||
|
||
The following resources can be created: | ||
* An S3 bucket | ||
* IAM User(s) | ||
* IAM Policies | ||
* KMS Keys | ||
|
||
## Usage | ||
### Specify this Module as Source | ||
```hcl | ||
module "s3" { | ||
source = "git::https://github.com/zoitech/terraform-aws-s3-with-iam-access.git" | ||
# Or to specifiy a particular module version: | ||
source = "git::https://github.com/zoitech/terraform-aws-s3-with-iam-access.git?ref=v0.0.1" | ||
``` | ||
### General Arguments | ||
#### Resource Creation Location | ||
The argument for the region is required to specify where the resources should be created: | ||
```hcl | ||
region = "eu-west-1" #default = "eu-central-1" | ||
``` | ||
#### PGP Key | ||
A public PGP key (in binary format) is required for encrypting the IAM secret keys and KMS keys, as these are given in output (Please see outputs below): | ||
```hcl | ||
pgp_keyname = "C123654C.pgp" | ||
``` | ||
### S3 Bucket Arguments | ||
#### Bucket Name | ||
Set the bucket name: | ||
```hcl | ||
s3_bucket_name = "my-s3-bucket" | ||
``` | ||
#### Object Versioning | ||
Enable S3 object versioning: | ||
```hcl | ||
s3_versioning_enabled = true #default = false | ||
``` | ||
#### Object Lifecycle | ||
Enable S3 object lifecycle for the whole bucket and specify a rule name. | ||
|
||
Object expiration and/or previous version deletion is specified in days: | ||
```hcl | ||
lifecycle_rule_enabled = true #default = false | ||
lifecycle_rule_id = "expire_objects_older_than_180_days_delete_previous_versions_older_than_90_days" #default = "" | ||
lifecycle_rule_expiration = 180 #default = 0 | ||
lifecycle_rule_noncurrent_version_expiration = 90 #default = 90 | ||
``` | ||
|
||
N.b. Object versioning must be enabled to expire current versions and delete previous versions of an object. | ||
|
||
#### Bucket Lifecycle Prevent Destroy | ||
By default the prevent_destroy lifecycle is to "true" to prevent accidental bucket deletion via terraform. | ||
|
||
### IAM Bucket Management Users | ||
#### IAM User(s): S3 Bucket Full Permissions | ||
Create IAM user(s) with full S3 bucket permissions (These users receive both management console and programmatic access): | ||
```hcl | ||
iam_user_s3_full_names = ["superadmin1", "superadmin2"] | ||
``` | ||
#### IAM User(s): S3 Bucket List/Delete Permissions | ||
Create IAM user(s) with limited administrative (list and delete) S3 bucket permissions (These users receive both management console and programmatic access): | ||
```hcl | ||
iam_user_s3_list_delete_names = ["admin1", "admin2"] | ||
``` | ||
#### IAM User(s): S3 Bucket Get/Delete Permissions | ||
Create IAM user(s) with limited administrative (get and delete) S3 bucket permissions (These users receive only programmatic access) | ||
|
||
Recommended as a synchronisation user: | ||
```hcl | ||
iam_user_s3_get_delete_names = ["sync_user", "sync_user2"] | ||
``` | ||
### IAM Bucket Standard Users | ||
Create IAM user(s) with their own bucket key (directory) in the S3 bucket. These users are assigned their own KMS keys which enable them to upload files in encrypted format as well as to download them and decrypt. (These users receive only programmatic access, therefore FTP client software such as CloudBerry or Cyberduck should be used): | ||
```hcl | ||
iam_user_s3_standard_names = ["Huey", "Dewey", "Louie"] | ||
``` | ||
|
||
### Outputs | ||
The following outputs are possible: | ||
* bucket_name (The name of the S3 bucket) | ||
* bucket_arn (The ARN of the S3 bucket) | ||
* s3_full_user_info (The users with full S3 bucket permissions) | ||
* s3_list_delete_user_info (The users with list/delete S3 bucket permissions) | ||
* s3_get_delete_user_info (The users with get/delete S3 bucket permissions) | ||
* standard_user_info (The users with access to their own S3 bucket keys) | ||
|
||
|
||
Example usage: | ||
```hcl | ||
#The name of the S3 bucket | ||
output "Bucket-Name" { | ||
value = "${module.s3.bucket_name}" | ||
} | ||
#The ARN of the S3 bucket | ||
output "Bucket-ARN" { | ||
value = "${module.s3.bucket_arn}" | ||
} | ||
#The users with full S3 bucket permissions | ||
output "Superadmins" { | ||
value = "${module.s3.s3_full_user_info}" | ||
} | ||
#The users with list/delete S3 bucket permissions | ||
output "Admins" { | ||
value = "${module.s3.s3_list_delete_user_info}" | ||
} | ||
#The users with get/delete S3 bucket permissions | ||
output "Sync-Users" { | ||
value = "${module.s3.s3_get_delete_user_info}" | ||
} | ||
#The users with access to their own S3 bucket keys | ||
output "User-Info" { | ||
value = "${module.s3.standard_user_info}" | ||
} | ||
``` | ||
|
||
Example output: | ||
```hcl | ||
Admins = [ | ||
"user_name: Admin", | ||
"access_key: <omitted>", | ||
"secret_key: <omitted>", | ||
"password": <omitted>" | ||
] | ||
Bucket-ARN = arn:aws:s3:::my-s3-bucket | ||
Bucket-Name = my-s3-bucket | ||
Superadmins = [ | ||
"user_name: superadmin", | ||
"access_key: <omitted>", | ||
"secret_key: <omitted>", | ||
"password": <omitted>" | ||
] | ||
Sync-Users = [ | ||
"user_name: sync-user", | ||
"access_key: <omitted>", | ||
"secret_key: <omitted>" | ||
] | ||
User-Info = [ | ||
"user_name: Huey", | ||
"access_key: <omitted>", | ||
"secret_key: <omitted>", | ||
"kms_key: <omitted>", | ||
"bucket_key: my-s3-bucket/Huey" | ||
"user_name: Dewey", | ||
"access_key: <omitted>", | ||
"secret_key: <omitted>", | ||
"kms_key: <omitted>", | ||
"bucket_key: my-s3-bucket/Dewey" | ||
"user_name: Louie", | ||
"access_key: <omitted>", | ||
"secret_key: <omitted>", | ||
"kms_key: <omitted>", | ||
"bucket_key: my-s3-bucket/Louie" | ||
] | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# template file for policy section: denying the unencrypted uploads | ||
data "template_file" "bucket_policy_for_deny_unencrypted" { | ||
template = "${file("${path.module}/templates/bucket_policies/bucket_policy_deny_unencrypted.json.tpl")}" | ||
|
||
vars { | ||
bucket-arn = "${aws_s3_bucket.s3_bucket.arn}" | ||
} | ||
} | ||
|
||
# template file for policy section: standard users | ||
data "template_file" "bucket_policy_for_a_standard_user" { | ||
count = "${length(var.iam_user_s3_standard_names)}" | ||
template = "${file("${path.module}/templates/bucket_policies/bucket_policy_user_template.json.tpl")}" | ||
|
||
vars { | ||
bucket-arn = "${aws_s3_bucket.s3_bucket.arn}" | ||
user-name = "${element(aws_iam_user.standard_user.*.name, count.index)}" | ||
kms-key = "${element(aws_kms_key.kmskey.*.key_id, count.index)}" | ||
} | ||
} | ||
|
||
# combine policy sections into one | ||
data "template_file" "bucket_policy" { | ||
template = <<JSON | ||
$${policy_start} | ||
$${deny_unencrypted_object_uploads} | ||
$${user_policies} | ||
$${policy_end} | ||
JSON | ||
|
||
vars { | ||
policy_start = "${file("${path.module}/templates/bucket_policies/bucket_policy_start.json.tpl")}" | ||
deny_unencrypted_object_uploads = "${data.template_file.bucket_policy_for_deny_unencrypted.rendered}" | ||
user_policies = "${join(",\n", data.template_file.bucket_policy_for_a_standard_user.*.rendered)}" | ||
policy_end = "${file("${path.module}/templates/bucket_policies/bucket_policy_end.json.tpl")}" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# template file for the S3 full permission user output | ||
data "template_file" "s3_full_user_output" { | ||
count = "${local.count_iam_user_s3_full_names}" | ||
template = "${file("${path.module}/templates/outputs/s3_full_users.tpl")}" | ||
|
||
vars { | ||
user-name = "${element(aws_iam_user.iam_user_s3_full_access.*.name, count.index)}" | ||
access-key = "${element(aws_iam_access_key.iam_user_s3_full_access.*.id, count.index)}" | ||
secret-key = "${element(aws_iam_access_key.iam_user_s3_full_access.*.encrypted_secret, count.index)}" | ||
password = "${element(aws_iam_user_login_profile.s3_full_login.*.encrypted_password, count.index)}" | ||
} | ||
} | ||
|
||
# combine the S3 full permission user outputs together | ||
data "template_file" "s3_full_user_outputs" { | ||
template = "$${outputs}" | ||
|
||
vars { | ||
outputs = "${join("\n\n", data.template_file.s3_full_user_output.*.rendered)}" | ||
} | ||
} | ||
|
||
# template file for the S3 list/delete permission user output | ||
data "template_file" "s3_list_delete_user_output" { | ||
count = "${local.count_iam_user_s3_list_delete_names}" | ||
template = "${file("${path.module}/templates/outputs/s3_list_delete_users.tpl")}" | ||
|
||
vars { | ||
user-name = "${element(aws_iam_user.iam_user_s3_list_delete_access.*.name, count.index)}" | ||
access-key = "${element(aws_iam_access_key.iam_user_s3_list_delete_access.*.id, count.index)}" | ||
secret-key = "${element(aws_iam_access_key.iam_user_s3_list_delete_access.*.encrypted_secret, count.index)}" | ||
password = "${element(aws_iam_user_login_profile.s3_list_delete_login.*.encrypted_password, count.index)}" | ||
} | ||
} | ||
|
||
# combine the S3 list/delete permission user outputs together | ||
data "template_file" "s3_list_delete_user_outputs" { | ||
template = "$${outputs}" | ||
|
||
vars { | ||
outputs = "${join("\n\n", data.template_file.s3_list_delete_user_output.*.rendered)}" | ||
} | ||
} | ||
|
||
# template file for the S3 get/delete permission user output | ||
data "template_file" "s3_get_delete_user_output" { | ||
count = "${local.count_iam_user_s3_get_delete_names}" | ||
template = "${file("${path.module}/templates/outputs/s3_get_delete_users.tpl")}" | ||
|
||
vars { | ||
user-name = "${element(aws_iam_user.iam_user_s3_get_delete_access.*.name, count.index)}" | ||
access-key = "${element(aws_iam_access_key.iam_user_s3_get_delete_access.*.id, count.index)}" | ||
secret-key = "${element(aws_iam_access_key.iam_user_s3_get_delete_access.*.encrypted_secret, count.index)}" | ||
} | ||
} | ||
|
||
# combine the S3 list/delete permission user outputs together | ||
data "template_file" "s3_get_delete_user_outputs" { | ||
template = "$${outputs}" | ||
|
||
vars { | ||
outputs = "${join("\n\n", data.template_file.s3_get_delete_user_output.*.rendered)}" | ||
} | ||
} | ||
|
||
# template file for the standard user output | ||
data "template_file" "standard_user_output" { | ||
count = "${local.count_standard_user}" | ||
template = "${file("${path.module}/templates/outputs/standard_users.tpl")}" | ||
|
||
vars { | ||
user-name = "${element(aws_iam_user.standard_user.*.name, count.index)}" | ||
access-key = "${element(aws_iam_access_key.iam_user_standard_access.*.id, count.index)}" | ||
secret-key = "${element(aws_iam_access_key.iam_user_standard_access.*.encrypted_secret, count.index)}" | ||
kms-key = "${element(aws_kms_key.kmskey.*.key_id, count.index)}" | ||
bucket-name = "${aws_s3_bucket.s3_bucket.id}" | ||
} | ||
} | ||
|
||
# combine the standard user outputs together | ||
data "template_file" "standard_user_outputs" { | ||
template = "$${outputs}" | ||
|
||
vars { | ||
outputs = "${join("\n\n", data.template_file.standard_user_output.*.rendered)}" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#access keys for the standard users | ||
resource "aws_iam_access_key" "iam_user_standard_access" { | ||
count = "${local.count_standard_user}" | ||
user = "${element(aws_iam_user.standard_user.*.name, count.index)}" | ||
pgp_key = "${base64encode(file("${var.pgp_keyname}"))}" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# iam policy for the standard users | ||
resource "aws_iam_policy" "iam_policy_standard_user" { | ||
count = "${local.count_standard_user}" | ||
name = "${aws_s3_bucket.s3_bucket.bucket}-${element(aws_iam_user.standard_user.*.name, count.index)}-policy" | ||
path = "/" | ||
description = "Grants ${element(aws_iam_user.standard_user.*.name, count.index)} download and upload access to the respective S3 folder for ${aws_s3_bucket.s3_bucket.bucket}" | ||
|
||
policy = <<EOF | ||
{ | ||
"Version":"2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Sid": "AllowUserToSeeBucketListInTheConsole", | ||
"Action": ["s3:ListAllMyBuckets", "s3:GetBucketLocation"], | ||
"Effect": "Allow", | ||
"Resource": ["${aws_s3_bucket.s3_bucket.arn}:*"] | ||
}, | ||
{ | ||
"Sid": "AllowRootListingOfBucket", | ||
"Action": ["s3:ListBucket"], | ||
"Effect": "Allow", | ||
"Resource": ["${aws_s3_bucket.s3_bucket.arn}"], | ||
"Condition":{"StringEquals":{"s3:prefix":["${element(aws_iam_user.standard_user.*.name, count.index)}/"],"s3:delimiter":["/"]}} | ||
}, | ||
{ | ||
"Sid": "AllowListingOfUserFolder", | ||
"Action": ["s3:ListBucket"], | ||
"Effect": "Allow", | ||
"Resource": ["${aws_s3_bucket.s3_bucket.arn}"], | ||
"Condition":{"StringLike":{"s3:prefix":["${element(aws_iam_user.standard_user.*.name, count.index)}/*"]}} | ||
}, | ||
{ | ||
"Sid": "AllowAllS3ActionsInUserFolder", | ||
"Effect": "Allow", | ||
"Action": ["s3:PutObject", "s3:GetObject"], | ||
"Resource": ["${aws_s3_bucket.s3_bucket.arn}/${element(aws_iam_user.standard_user.*.name, count.index)}/*"] | ||
} | ||
] | ||
} | ||
EOF | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# iam access keys for full permission users | ||
resource "aws_iam_access_key" "iam_user_s3_full_access" { | ||
count = "${local.count_iam_user_s3_full_names}" | ||
user = "${element(aws_iam_user.iam_user_s3_full_access.*.name, count.index)}" | ||
pgp_key = "${base64encode(file("${var.pgp_keyname}"))}" | ||
} | ||
|
||
# iam access keys for list delete permission users | ||
resource "aws_iam_access_key" "iam_user_s3_list_delete_access" { | ||
count = "${local.count_iam_user_s3_list_delete_names}" | ||
user = "${element(aws_iam_user.iam_user_s3_list_delete_access.*.name, count.index)}" | ||
pgp_key = "${base64encode(file("${var.pgp_keyname}"))}" | ||
} | ||
|
||
# iam access keys for get delete permission users | ||
resource "aws_iam_access_key" "iam_user_s3_get_delete_access" { | ||
count = "${local.count_iam_user_s3_get_delete_names}" | ||
user = "${element(aws_iam_user.iam_user_s3_get_delete_access.*.name, count.index)}" | ||
pgp_key = "${base64encode(file("${var.pgp_keyname}"))}" | ||
} |
Oops, something went wrong.