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 = {}
+}