diff --git a/.gitignore b/.gitignore index 1a8ea9029..176ac00dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,164 +1,33 @@ -_notes/* -tmp/* -tmp* -state.tf -report.json -report.csv -report.md -Pipfile.lock -*.sqlite3-journal -# Created by https://www.gitignore.io/api/macos,python,pycharm,jetbrains,visualstudiocode -# Edit at https://www.gitignore.io/?templates=macos,python,pycharm,jetbrains,visualstudiocode - -### JetBrains ### -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -.idea/* -.vscode/* - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# *.iml -# *.ipr - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml +# Repository specific +terraform_module/demo/template.json -# Cursive Clojure plugin -.idea/replstate.xml +# IDEs +.idea +.vscode -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -### JetBrains Patch ### -# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 - -# *.iml -# modules.xml -# .idea/misc.xml -# *.ipr - -# Sonarlint plugin -.idea/sonarlint - -### macOS ### -# General +# Mac OS X .DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk -### PyCharm ### -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 +# Serverless framework +.serverless +.requirements.zip +node_modules/ -# User-specific stuff - -# Generated files - -# Sensitive or high-churn files - -# Gradle - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/modules.xml -# .idea/*.iml -# .idea/modules -# *.iml -# *.ipr - -# CMake - -# Mongo Explorer plugin - -# File-based project format - -# IntelliJ - -# mpeltonen/sbt-idea plugin - -# JIRA plugin - -# Cursive Clojure plugin - -# Crashlytics plugin (for Android Studio and IntelliJ) - -# Editor-based Rest Client - -# Android studio 3.1+ serialized cache file - -### PyCharm Patch ### -# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 - -# *.iml -# modules.xml -# .idea/misc.xml -# *.ipr +# Working directories +tmp +!.gitkeep +_notes/* -# Sonarlint plugin +# Static HTML generated documentation +site/* -### Python ### -# Byte-compiled / optimized / DLL files +# Python +.coverage +.Python __pycache__/ *.py[cod] *$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python +env/ build/ develop-eggs/ dist/ @@ -170,23 +39,10 @@ lib64/ parts/ sdist/ var/ -wheels/ -pip-wheel-metadata/ -share/python-wheels/ +venv/ *.egg-info/ .installed.cfg *.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ @@ -201,124 +57,17 @@ coverage.xml .hypothesis/ .pytest_cache/ -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -.python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# celery beat schedule file -celerybeat-schedule - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -### VisualStudioCode ### -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json - -### VisualStudioCode Patch ### -# Ignore all local history of files -.history - -# End of https://www.gitignore.io/api/macos,python,pycharm,jetbrains,visualstudiocode -.vscode/settings.json - -# Created by https://www.gitignore.io/api/terraform -# Edit at https://www.gitignore.io/?templates=terraform - -### Terraform ### -# Local .terraform directories +# HashiCorp **/.terraform/* - -# .tfstate files +*.plan *.tfstate *.tfstate.* +*.tfvars +!terraform.tfvars +.vagrant +packer_cache/ +*.box -# Crash log files -crash.log - -# Ignore any .tfvars files that are generated automatically for each Terraform run. Most -# .tfvars files are managed as part of configuration and so should be included in -# version control. -# -# example.tfvars - -# Ignore override files as they are usually used to override resources locally and so -# are not checked in -override.tf -override.tf.json -*_override.tf -*_override.tf.json - -# Include override files you do wish to add to version control using negated pattern -# !example_override.tf - -# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan -# example: *tfplan* - -# End of https://www.gitignore.io/api/terraform +#### Other +*.log +*.pem diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..24fb17be4 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,6 @@ +- repo: git://github.com/antonbabenko/pre-commit-terraform + rev: v1.44.0 # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases + hooks: + - id: terraform_fmt + - id: terraform_docs +# args: ['--sort-by-required', '--no-providers'] diff --git a/terraform_module/README.md b/terraform_module/README.md new file mode 100644 index 000000000..e066e4e4b --- /dev/null +++ b/terraform_module/README.md @@ -0,0 +1,129 @@ +# terraform-aws-policy-sentry + +Builds secure IAM Policies with resource constraints. For more information on Policy Sentry, see [the documentation](https://policy-sentry.readthedocs.io/en/latest/). + +## Prerequisites + +* You must have Policy Sentry 0.10.0 installed beforehand and it must be executable from your `$PATH`. Follow the installation instructions [here](https://policy-sentry.readthedocs.io/en/latest/user-guide/installation.html) + * This module currently requires Terraform 0.12.8 + +## Usage + +### Example + +* Install Terraform 0.12.8 + +```bash +# tfenv is a Terraform version manager +brew install tfenv +tfenv install 0.12.8 +``` + +* Install Policy Sentry + +```bash +brew tap salesforce/policy_sentry https://github.com/salesforce/policy_sentry +brew install policy_sentry +``` + +* Use the module as shown in [main.tf](./demo/main.tf): + +```hcl +module "policy_sentry_demo" { + source = "github.com/salesforce/policy_sentry.git?ref=master//terraform_module/" + name = var.name + read_access_level = var.read_access_level + write_access_level = var.write_access_level + list_access_level = var.list_access_level + tagging_access_level = var.tagging_access_level + permissions_management_access_level = var.permissions_management_access_level + wildcard_only_single_actions = var.wildcard_only_actions + minimize = var.minimize +} +``` + +Assuming you have your [variables.tf](./demo/variables.tf) file set properly (redacted from this README for readability), provide the following in your `terraform.tfvars` file. + +* [terraform.tfvars](./demo/terraform.tfvars): + +```hcl +name = "PolicySentryTest" + +list_access_level = [ + "arn:aws:s3:::example-org", +] + +read_access_level = [ + "arn:aws:kms:us-east-1:123456789012:key/shaq" +] + +write_access_level = [ + "arn:aws:kms:us-east-1:123456789012:key/shaq" +] +``` + + +## Requirements + +| Name | Version | +|------|---------| +| terraform | ~> 0.12.8 | +| aws | ~> 2.48.0 | +| external | ~> 1.2 | +| local | ~> 1.3 | +| null | ~> 2.1 | +| template | ~> 2.1.2 | + +## Providers + +No provider. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| description | The description to include for the IAM policy. | `string` | `"Generated by Policy Sentry"` | no | +| list\_access\_level | Provide a list of Amazon Resource Names (ARNs) that your role needs LIST access to. | `list(string)` | `[]` | no | +| minimize | If set to true, it will minimize the size of the IAM Policy file. Defaults to false. | `bool` | `false` | no | +| name | The name of the rendered policy file (no file extension). | `string` | n/a | yes | +| permissions\_management\_access\_level | Provide a list of Amazon Resource Names (ARNs) that your role needs PERMISSIONS MANAGEMENT access to. | `list(string)` | `[]` | no | +| read\_access\_level | Provide a list of Amazon Resource Names (ARNs) that your role needs READ access to. | `list(string)` | `[]` | no | +| region | The AWS region for these resources. Defaults to us-east-1 | `string` | `"us-east-1"` | no | +| tagging\_access\_level | Provide a list of Amazon Resource Names (ARNs) that your role needs TAGGING access to. | `list(string)` | `[]` | no | +| wildcard\_only\_list\_service | To generate a list of AWS service actions that (1) are at the LIST access level and (2) do not support resource constraints, list the service prefix here. | `list(string)` | `[]` | no | +| wildcard\_only\_permissions\_management\_service | To generate a list of AWS service actions that (1) are at the PERMISSIONS MANAGEMENT access level and (2) do not support resource constraints, list the service prefix here. | `list(string)` | `[]` | no | +| wildcard\_only\_read\_service | To generate a list of AWS service actions that (1) are at the READ access level and (2) do not support resource constraints, list the service prefix here. | `list(string)` | `[]` | no | +| wildcard\_only\_single\_actions | Individual actions that do not support resource constraints. For example, s3:ListAllMyBuckets | `list(string)` | `[]` | no | +| wildcard\_only\_tagging\_service | To generate a list of AWS service actions that (1) are at the TAGGING access level and (2) do not support resource constraints, list the service prefix here. | `list(string)` | `[]` | no | +| wildcard\_only\_write\_service | To generate a list of AWS service actions that (1) are at the WRITE access level and (2) do not support resource constraints, list the service prefix here. | `list(string)` | `[]` | no | +| write\_access\_level | Provide a list of Amazon Resource Names (ARNs) that your role needs WRITE access to. | `list(string)` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| iam\_policy\_arn | The ARN assigned by AWS to this policy. | +| iam\_policy\_document | The policy document. | +| iam\_policy\_id | The policy's ID. | +| iam\_policy\_name | The name of the policy. | +| iam\_policy\_path | The path of the policy in IAM | + + + +## Maintenance + +* [Pre-commit hook](https://github.com/antonbabenko/pre-commit-terraform#4-run) + +Run this every time before you push to Git. + +``` +pre-commit run -a +``` + + +## Todo +* Publish this on Terraform module registry + +## License + +Copyright: © 2020 Kinnaird McQuade diff --git a/terraform_module/demo/main.tf b/terraform_module/demo/main.tf new file mode 100644 index 000000000..956b7183c --- /dev/null +++ b/terraform_module/demo/main.tf @@ -0,0 +1,15 @@ +module "policy_sentry_demo" { + source = "../" + name = var.name + read_access_level = var.read_access_level + write_access_level = var.write_access_level + list_access_level = var.list_access_level + tagging_access_level = var.tagging_access_level + permissions_management_access_level = var.permissions_management_access_level + wildcard_only_single_actions = var.wildcard_only_single_actions + minimize = var.minimize +} + +terraform { + required_version = "~> 0.12.8" +} diff --git a/terraform_module/demo/terraform.tfvars b/terraform_module/demo/terraform.tfvars new file mode 100644 index 000000000..d60e3c1f3 --- /dev/null +++ b/terraform_module/demo/terraform.tfvars @@ -0,0 +1,12 @@ +name = "PolicySentryTest" + +list_access_level = [ + "arn:aws:s3:::list-org", + "arn:aws:s3:::sup-org", +] +read_access_level = [ + "arn:aws:s3:::bruh", +] +write_access_level = [ + "arn:aws:kms:us-east-1:123456789012:key/shaq" +] \ No newline at end of file diff --git a/terraform_module/demo/variables.tf b/terraform_module/demo/variables.tf new file mode 100644 index 000000000..136843d33 --- /dev/null +++ b/terraform_module/demo/variables.tf @@ -0,0 +1,76 @@ +variable "name" { + description = "The name of the rendered policy file (no file extension)." + type = string +} + +variable "minimize" { + description = "If set to true, it will minimize the size of the IAM Policy file. Defaults to false." + default = false + type = bool +} + +variable "read_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs READ access to." + type = list(string) + default = [] +} + +variable "write_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs WRITE access to." + type = list(string) + default = [] +} + +variable "list_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs LIST access to." + type = list(string) + default = [] +} + +variable "tagging_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs TAGGING access to." + type = list(string) + default = [] +} + +variable "permissions_management_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs PERMISSIONS MANAGEMENT access to." + type = list(string) + default = [] +} + +variable "wildcard_only_single_actions" { + description = "Individual actions that do not support resource constraints. For example, s3:ListAllMyBuckets" + type = list(string) + default = [] +} + +variable "wildcard_only_read_service" { + description = "To generate a list of AWS service actions that (1) are at the READ access level and (2) do not support resource constraints, list the service prefix here." + type = list(string) + default = [] +} + +variable "wildcard_only_write_service" { + description = "To generate a list of AWS service actions that (1) are at the WRITE access level and (2) do not support resource constraints, list the service prefix here." + type = list(string) + default = [] +} + +variable "wildcard_only_list_service" { + description = "To generate a list of AWS service actions that (1) are at the LIST access level and (2) do not support resource constraints, list the service prefix here." + type = list(string) + default = [] +} + +variable "wildcard_only_tagging_service" { + description = "To generate a list of AWS service actions that (1) are at the TAGGING access level and (2) do not support resource constraints, list the service prefix here." + type = list(string) + default = [] +} + +variable "wildcard_only_permissions_management_service" { + description = "To generate a list of AWS service actions that (1) are at the PERMISSIONS MANAGEMENT access level and (2) do not support resource constraints, list the service prefix here." + type = list(string) + default = [] +} diff --git a/terraform_module/iam-policies/README.md b/terraform_module/iam-policies/README.md new file mode 100644 index 000000000..40b6c3626 --- /dev/null +++ b/terraform_module/iam-policies/README.md @@ -0,0 +1,50 @@ +# generate-iam-policies + +This generates IAM policies based on JSON files in a specified folder. This is ideal for usage with IAM Policies generated by policy sentry. + +## Usage + +From the `environments/iam-resources/` directory, which shows the example usage of this. + +```hcl-terraform +module "policies" { + source = "../../modules/generate-iam-policies" + relative_path_to_json_policy_files = "files" +} +``` + + +## Requirements + +| Name | Version | +|------|---------| +| terraform | ~> 0.12.8 | +| aws | ~> 2.48.0 | +| template | ~> 2.1.2 | + +## Providers + +| Name | Version | +|------|---------| +| aws | ~> 2.48.0 | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| description | The description to include for the IAM policy. | `string` | `"Generated by Policy Sentry"` | no | +| name | Name of the JSON policy file, minus the file extension. For example, 'result' instead of 'result.json' | `any` | n/a | yes | +| policy\_json | The policy document in json | `any` | n/a | yes | +| region | The AWS region for these resources, such as us-east-1. | `any` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| iam\_policy\_arn | The ARN assigned by AWS to this policy. | +| iam\_policy\_document | The policy document. | +| iam\_policy\_id | The policy's ID. | +| iam\_policy\_name | The name of the policy. | +| iam\_policy\_path | The path of the policy in IAM | + + diff --git a/terraform_module/iam-policies/main.tf b/terraform_module/iam-policies/main.tf new file mode 100644 index 000000000..4c23c8d9e --- /dev/null +++ b/terraform_module/iam-policies/main.tf @@ -0,0 +1,12 @@ +# Takes the relative path to the .json policy; remove the folder name and the extension. This will be our policy name +resource "aws_iam_policy" "policy" { + name = var.name + path = "/" + description = var.description + policy = data.aws_iam_policy_document.policy.json +} + +data "aws_iam_policy_document" "policy" { + source_json = var.policy_json +} + diff --git a/terraform_module/iam-policies/outputs.tf b/terraform_module/iam-policies/outputs.tf new file mode 100644 index 000000000..30bf69aa5 --- /dev/null +++ b/terraform_module/iam-policies/outputs.tf @@ -0,0 +1,24 @@ +output "iam_policy_id" { + description = "The policy's ID." + value = aws_iam_policy.policy.*.id +} + +output "iam_policy_arn" { + description = "The ARN assigned by AWS to this policy." + value = aws_iam_policy.policy.*.arn +} + +output "iam_policy_name" { + description = "The name of the policy." + value = aws_iam_policy.policy.*.name +} + +output "iam_policy_path" { + description = "The path of the policy in IAM" + value = aws_iam_policy.policy.*.path +} + +output "iam_policy_document" { + description = "The policy document." + value = aws_iam_policy.policy.*.policy +} diff --git a/terraform_module/iam-policies/provider.tf b/terraform_module/iam-policies/provider.tf new file mode 100644 index 000000000..cc5cf283c --- /dev/null +++ b/terraform_module/iam-policies/provider.tf @@ -0,0 +1,12 @@ +terraform { + required_version = "~> 0.12.8" +} + +provider "aws" { + version = "~> 2.48.0" + region = var.region +} + +provider "template" { + version = "~> 2.1.2" +} diff --git a/terraform_module/iam-policies/variables.tf b/terraform_module/iam-policies/variables.tf new file mode 100644 index 000000000..0b414f8d3 --- /dev/null +++ b/terraform_module/iam-policies/variables.tf @@ -0,0 +1,16 @@ +variable "name" { + description = "Name of the JSON policy file, minus the file extension. For example, 'result' instead of 'result.json'" +} + +variable "region" { + description = "The AWS region for these resources, such as us-east-1." +} + +variable "description" { + description = "The description to include for the IAM policy." + default = "Generated by Policy Sentry" +} + +variable "policy_json" { + description = "The policy document in json" +} diff --git a/terraform_module/main.tf b/terraform_module/main.tf new file mode 100644 index 000000000..148f11b72 --- /dev/null +++ b/terraform_module/main.tf @@ -0,0 +1,19 @@ +module "create_template" { + source = "./ps-template/" + name = var.name + read_access_level = var.read_access_level + write_access_level = var.write_access_level + list_access_level = var.list_access_level + tagging_access_level = var.tagging_access_level + permissions_management_access_level = var.permissions_management_access_level + wildcard_only_single_actions = var.wildcard_only_single_actions + minimize = var.minimize +} + +module "create_iam" { + source = "./iam-policies/" + region = var.region + name = var.name + description = var.description + policy_json = module.create_template.policy_json +} diff --git a/terraform_module/outputs.tf b/terraform_module/outputs.tf new file mode 100644 index 000000000..d00710b91 --- /dev/null +++ b/terraform_module/outputs.tf @@ -0,0 +1,24 @@ +output "iam_policy_id" { + description = "The policy's ID." + value = module.create_iam.iam_policy_id +} + +output "iam_policy_arn" { + description = "The ARN assigned by AWS to this policy." + value = module.create_iam.iam_policy_arn +} + +output "iam_policy_name" { + description = "The name of the policy." + value = module.create_iam.iam_policy_name +} + +output "iam_policy_path" { + description = "The path of the policy in IAM" + value = module.create_iam.iam_policy_path +} + +output "iam_policy_document" { + description = "The policy document." + value = module.create_iam.iam_policy_document +} diff --git a/terraform_module/provider.tf b/terraform_module/provider.tf new file mode 100644 index 000000000..ed2f7f65a --- /dev/null +++ b/terraform_module/provider.tf @@ -0,0 +1,24 @@ +terraform { + required_version = "~> 0.12.8" +} + +provider "aws" { + version = "~> 2.48.0" + region = var.region +} + +provider "template" { + version = "~> 2.1.2" +} + +provider "local" { + version = "~> 1.3" +} + +provider "null" { + version = "~> 2.1" +} + +provider "external" { + version = "~> 1.2" +} diff --git a/terraform_module/ps-template/README.md b/terraform_module/ps-template/README.md new file mode 100644 index 000000000..7d322a669 --- /dev/null +++ b/terraform_module/ps-template/README.md @@ -0,0 +1,46 @@ +# ps-template + +This generates the JSON policy file with Policy Sentry. + + +## Requirements + +| Name | Version | +|------|---------| +| terraform | ~> 0.12.8 | +| local | ~> 1.3 | + +## Providers + +| Name | Version | +|------|---------| +| external | n/a | +| local | ~> 1.3 | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| list\_access\_level | Provide a list of Amazon Resource Names (ARNs) that your role needs LIST access to. | `list` |
[| no | +| minimize | If set to true, it will minimize the size of the IAM Policy file. Defaults to false. | `bool` | `false` | no | +| name | The name of the rendered policy file (no file extension). | `string` | n/a | yes | +| permissions\_management\_access\_level | Provide a list of Amazon Resource Names (ARNs) that your role needs PERMISSIONS MANAGEMENT access to. | `list` |
""
]
[| no | +| read\_access\_level | Provide a list of Amazon Resource Names (ARNs) that your role needs READ access to. | `list` |
""
]
[| no | +| tagging\_access\_level | Provide a list of Amazon Resource Names (ARNs) that your role needs TAGGING access to. | `list` |
""
]
[| no | +| wildcard\_only\_list\_service | To generate a list of AWS service actions that (1) are at the LIST access level and (2) do not support resource constraints, list the service prefix here. | `list` |
""
]
[| no | +| wildcard\_only\_permissions\_management\_service | To generate a list of AWS service actions that (1) are at the PERMISSIONS MANAGEMENT access level and (2) do not support resource constraints, list the service prefix here. | `list` |
""
]
[| no | +| wildcard\_only\_read\_service | To generate a list of AWS service actions that (1) are at the READ access level and (2) do not support resource constraints, list the service prefix here. | `list` |
""
]
[| no | +| wildcard\_only\_single\_actions | Individual actions that do not support resource constraints. For example, s3:ListAllMyBuckets | `list` |
""
]
[| no | +| wildcard\_only\_tagging\_service | To generate a list of AWS service actions that (1) are at the TAGGING access level and (2) do not support resource constraints, list the service prefix here. | `list` |
""
]
[| no | +| wildcard\_only\_write\_service | To generate a list of AWS service actions that (1) are at the WRITE access level and (2) do not support resource constraints, list the service prefix here. | `list` |
""
]
[| no | +| write\_access\_level | Provide a list of Amazon Resource Names (ARNs) that your role needs WRITE access to. | `list` |
""
]
[| no | + +## Outputs + +| Name | Description | +|------|-------------| +| file\_name | The path of the file. | +| policy\_json | The contents of the policy | +| policy\_sentry\_template\_contents | The contents of the Policy Sentry template | + + diff --git a/terraform_module/ps-template/main.tf b/terraform_module/ps-template/main.tf new file mode 100644 index 000000000..16b1665ff --- /dev/null +++ b/terraform_module/ps-template/main.tf @@ -0,0 +1,37 @@ +# --------------------------------------------------------------------------------------------------------------------- +# Locals to create the policies +# --------------------------------------------------------------------------------------------------------------------- + +locals { + file = "${var.name}.json" + policy_sentry_template = { + "mode" : "crud", + "read" : var.read_access_level, + "write" : var.write_access_level, + "list" : var.list_access_level, + "tagging" : var.tagging_access_level + "permissions-management" : var.permissions_management_access_level, + "wildcard-only" : { + "single-actions" : var.wildcard_only_single_actions, + "service-read" : var.wildcard_only_read_service, + "service-write" : var.wildcard_only_write_service, + "service-list" : var.wildcard_only_list_service, + "service-tagging" : var.wildcard_only_tagging_service, + "service-permissions-management" : var.wildcard_only_permissions_management_service, + } + } + rendered_template = jsonencode(local.policy_sentry_template) + decoded_template = jsondecode(jsonencode(local.policy_sentry_template)) + policy_sentry = ["policy_sentry", "write-policy", "--fmt", "terraform"] + command = var.minimize ? concat(local.policy_sentry, ["--minimize"]) : local.policy_sentry +} + +resource "local_file" "template" { + filename = "template.json" + content = local.rendered_template +} + +data "external" "policy" { + program = concat(local.command, ["--input-file", local_file.template.filename]) +} + diff --git a/terraform_module/ps-template/outputs.tf b/terraform_module/ps-template/outputs.tf new file mode 100644 index 000000000..42cb236b1 --- /dev/null +++ b/terraform_module/ps-template/outputs.tf @@ -0,0 +1,14 @@ +output "file_name" { + value = "${var.name}.json" + description = "The path of the file." +} + +output "policy_sentry_template_contents" { + description = "The contents of the Policy Sentry template" + value = local.rendered_template +} + +output "policy_json" { + description = "The contents of the policy" + value = data.external.policy.result.policy +} diff --git a/terraform_module/ps-template/provider.tf b/terraform_module/ps-template/provider.tf new file mode 100644 index 000000000..ecea8ab50 --- /dev/null +++ b/terraform_module/ps-template/provider.tf @@ -0,0 +1,7 @@ +terraform { + required_version = "~> 0.12.8" +} + +provider "local" { + version = "~> 1.3" +} diff --git a/terraform_module/ps-template/variables.tf b/terraform_module/ps-template/variables.tf new file mode 100644 index 000000000..8019bc1d2 --- /dev/null +++ b/terraform_module/ps-template/variables.tf @@ -0,0 +1,76 @@ +variable "name" { + description = "The name of the rendered policy file (no file extension)." + type = string +} + +variable "minimize" { + description = "If set to true, it will minimize the size of the IAM Policy file. Defaults to false." + default = false + type = bool +} + +variable "read_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs READ access to." + type = list + default = [""] +} + +variable "write_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs WRITE access to." + type = list + default = [""] +} + +variable "list_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs LIST access to." + type = list + default = [""] +} + +variable "tagging_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs TAGGING access to." + type = list + default = [""] +} + +variable "permissions_management_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs PERMISSIONS MANAGEMENT access to." + type = list + default = [""] +} + +variable "wildcard_only_single_actions" { + description = "Individual actions that do not support resource constraints. For example, s3:ListAllMyBuckets" + type = list + default = [""] +} + +variable "wildcard_only_read_service" { + description = "To generate a list of AWS service actions that (1) are at the READ access level and (2) do not support resource constraints, list the service prefix here." + type = list + default = [""] +} + +variable "wildcard_only_write_service" { + description = "To generate a list of AWS service actions that (1) are at the WRITE access level and (2) do not support resource constraints, list the service prefix here." + type = list + default = [""] +} + +variable "wildcard_only_list_service" { + description = "To generate a list of AWS service actions that (1) are at the LIST access level and (2) do not support resource constraints, list the service prefix here." + type = list + default = [""] +} + +variable "wildcard_only_tagging_service" { + description = "To generate a list of AWS service actions that (1) are at the TAGGING access level and (2) do not support resource constraints, list the service prefix here." + type = list + default = [""] +} + +variable "wildcard_only_permissions_management_service" { + description = "To generate a list of AWS service actions that (1) are at the PERMISSIONS MANAGEMENT access level and (2) do not support resource constraints, list the service prefix here." + type = list + default = [""] +} diff --git a/terraform_module/variables.tf b/terraform_module/variables.tf new file mode 100644 index 000000000..dc740c2e8 --- /dev/null +++ b/terraform_module/variables.tf @@ -0,0 +1,86 @@ +variable "name" { + description = "The name of the rendered policy file (no file extension)." + type = string +} + +variable "description" { + description = "The description to include for the IAM policy." + default = "Generated by Policy Sentry" +} + +variable "region" { + description = "The AWS region for these resources. Defaults to us-east-1" + default = "us-east-1" +} + +variable "minimize" { + description = "If set to true, it will minimize the size of the IAM Policy file. Defaults to false." + default = false + type = bool +} + +variable "read_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs READ access to." + type = list(string) + default = [] +} + +variable "write_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs WRITE access to." + type = list(string) + default = [] +} + +variable "list_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs LIST access to." + type = list(string) + default = [] +} + +variable "tagging_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs TAGGING access to." + type = list(string) + default = [] +} + +variable "permissions_management_access_level" { + description = "Provide a list of Amazon Resource Names (ARNs) that your role needs PERMISSIONS MANAGEMENT access to." + type = list(string) + default = [] +} + +variable "wildcard_only_single_actions" { + description = "Individual actions that do not support resource constraints. For example, s3:ListAllMyBuckets" + type = list(string) + default = [] +} + +variable "wildcard_only_read_service" { + description = "To generate a list of AWS service actions that (1) are at the READ access level and (2) do not support resource constraints, list the service prefix here." + type = list(string) + default = [] +} + +variable "wildcard_only_write_service" { + description = "To generate a list of AWS service actions that (1) are at the WRITE access level and (2) do not support resource constraints, list the service prefix here." + type = list(string) + default = [] +} + +variable "wildcard_only_list_service" { + description = "To generate a list of AWS service actions that (1) are at the LIST access level and (2) do not support resource constraints, list the service prefix here." + type = list(string) + default = [] +} + +variable "wildcard_only_tagging_service" { + description = "To generate a list of AWS service actions that (1) are at the TAGGING access level and (2) do not support resource constraints, list the service prefix here." + type = list(string) + default = [] +} + +variable "wildcard_only_permissions_management_service" { + description = "To generate a list of AWS service actions that (1) are at the PERMISSIONS MANAGEMENT access level and (2) do not support resource constraints, list the service prefix here." + type = list(string) + default = [] +}
""
]