diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..168b16a --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,23 @@ +name: Terraform Validate + +on: + push: + branches: ["develop"] + pull_request: + branches: ["main", "develop"] + +jobs: + validate: + runs-on: ubuntu-latest + name: Validate Terraform module + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + - name: Initialize Terraform + run: terraform init + - name: Validate Terraform + run: terraform validate -no-color + - name: Validate Format + run: terraform fmt -recursive -list=true -check \ No newline at end of file diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..6209085 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @MefistoBaal \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..9913738 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | > 1.1.7 | +| [aws](#requirement\_aws) | ~> 4.67.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | ~> 4.67.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_access_key.admin_access_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_access_key) | resource | +| [aws_iam_access_key.atlantis_access_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_access_key) | resource | +| [aws_iam_user.admin_user](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user) | resource | +| [aws_iam_user.atlantis_user](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user) | resource | +| [aws_iam_user_policy.admin_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user_policy) | resource | +| [aws_iam_user_policy.atlantis_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user_policy) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [admin\_role\_name](#input\_admin\_role\_name) | The name of the role in the target accounts that the administrator user can assume. | `string` | `""` | no | +| [admin\_username](#input\_admin\_username) | The username for the administrator user in the master account. | `string` | `""` | no | +| [atlantis\_role\_name](#input\_atlantis\_role\_name) | The name of the role in the target accounts that the Atlantis user can assume. | `string` | `""` | no | +| [atlantis\_username](#input\_atlantis\_username) | The username for the Atlantis user in the master account. | `string` | `""` | no | +| [tags](#input\_tags) | Map of tags to assign to the created resources. | `map(string)` | `{}` | no | +| [target\_account\_ids](#input\_target\_account\_ids) | A list of target account IDs where roles will be assumed. | `list(string)` | `""` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [admin\_access\_key\_id](#output\_admin\_access\_key\_id) | Access Key ID of the admin user | +| [admin\_user\_arn](#output\_admin\_user\_arn) | ARN of the admin user | +| [atlantis\_access\_key\_id](#output\_atlantis\_access\_key\_id) | Access Key ID of the Atlantis user | +| [atlantis\_user\_arn](#output\_atlantis\_user\_arn) | ARN of the Atlantis user | diff --git a/locals.tf b/locals.tf new file mode 100644 index 0000000..6875427 --- /dev/null +++ b/locals.tf @@ -0,0 +1,9 @@ +locals { + # ARNs are generated for the roles that each user will be able to assume + admin_assume_role_arns = [ + for account in var.target_account_ids : "arn:aws:iam::${account}:role/${var.admin_role_name}" + ] + atlantis_assume_role_arns = [ + for account in var.target_account_ids : "arn:aws:iam::${account}:role/${var.atlantis_role_name}" + ] +} diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..71a2a7a --- /dev/null +++ b/main.tf @@ -0,0 +1,89 @@ +# Creation of the admin user +resource "aws_iam_user" "admin_user" { + name = var.admin_username + force_destroy = true + # tags = var.tags +} + +# Inline policy for the admin user that includes deployment permissions and role assumption +resource "aws_iam_user_policy" "admin_policy" { + name = "${var.admin_username}-policy" + user = aws_iam_user.admin_user.name + policy = jsonencode({ + "Version" : "2012-10-17", + "Statement" : [ + { + "Sid" : "AllowDeployAccess", + "Effect" : "Allow", + "Action" : [ + "s3:*", + "lambda:*", + "cognito-idp:*", + "cognito-sync:*", + "cognito-identity:*", + "cloudwatch:*", + "logs:*", + "iam:*", + "ec2:*" + ], + "Resource" : "*" + }, + { + "Sid" : "AllowAssumeRole", + "Effect" : "Allow", + "Action" : "sts:AssumeRole", + "Resource" : local.admin_assume_role_arns + } + ] + }) +} + +# Generation of access credentials for the admin user +resource "aws_iam_access_key" "admin_access_key" { + user = aws_iam_user.admin_user.name +} + +# Creation of the Atlantis user +resource "aws_iam_user" "atlantis_user" { + name = var.atlantis_username + force_destroy = true + # tags = var.tags +} + +# Inline policy for the Atlantis user that includes deployment permissions and role assumption +resource "aws_iam_user_policy" "atlantis_policy" { + name = "${var.atlantis_username}-policy" + user = aws_iam_user.atlantis_user.name + policy = jsonencode({ + "Version" : "2012-10-17", + "Statement" : [ + { + "Sid" : "AllowDeployAccess", + "Effect" : "Allow", + "Action" : [ + "s3:*", + "lambda:*", + "cognito-idp:*", + "cognito-sync:*", + "cognito-identity:*", + "cloudwatch:*", + "logs:*", + "iam:*", + "ec2:*" + ], + "Resource" : "*" + }, + { + "Sid" : "AllowAssumeRole", + "Effect" : "Allow", + "Action" : "sts:AssumeRole", + "Resource" : local.atlantis_assume_role_arns + } + ] + }) +} + +# Generation of access credentials for the Atlantis user +resource "aws_iam_access_key" "atlantis_access_key" { + user = aws_iam_user.atlantis_user.name +} diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..6ab41e0 --- /dev/null +++ b/outputs.tf @@ -0,0 +1,19 @@ +output "admin_user_arn" { + value = aws_iam_user.admin_user.arn + description = "ARN of the admin user" +} + +output "admin_access_key_id" { + value = aws_iam_access_key.admin_access_key.id + description = "Access Key ID of the admin user" +} + +output "atlantis_user_arn" { + value = aws_iam_user.atlantis_user.arn + description = "ARN of the Atlantis user" +} + +output "atlantis_access_key_id" { + value = aws_iam_access_key.atlantis_access_key.id + description = "Access Key ID of the Atlantis user" +} diff --git a/provider.tf b/provider.tf new file mode 100644 index 0000000..18dacd6 --- /dev/null +++ b/provider.tf @@ -0,0 +1,9 @@ +terraform { + required_version = "> 1.1.7" + + required_providers { + aws = { + version = "~> 5.29" + } + } +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..af2d04a --- /dev/null +++ b/variables.tf @@ -0,0 +1,35 @@ +variable "admin_username" { + type = string + default = "" + description = "The username for the administrator user in the master account." +} + +variable "atlantis_username" { + type = string + default = "" + description = "The username for the Atlantis user in the master account." +} + +variable "target_account_ids" { + type = list(string) + default = [] + description = "A list of target account IDs where roles will be assumed." +} + +variable "admin_role_name" { + type = string + default = "" + description = "The name of the role in the target accounts that the administrator user can assume." +} + +variable "atlantis_role_name" { + type = string + default = "" + description = "The name of the role in the target accounts that the Atlantis user can assume." +} + +variable "tags" { + description = "Map of tags to assign to the created resources." + type = map(string) + default = {} +}