diff --git a/.github/workflows/tf-checks.yml b/.github/workflows/tf-checks.yml index 60c205a..b4a833c 100644 --- a/.github/workflows/tf-checks.yml +++ b/.github/workflows/tf-checks.yml @@ -8,4 +8,9 @@ jobs: complete-example: uses: clouddrove/github-shared-workflows/.github/workflows/tf-checks.yml@1.2.2 with: - working_directory: './_example/complete/' + working_directory: './examples/complete/' + oidc-example: + uses: clouddrove/github-shared-workflows/.github/workflows/tf-checks.yml@1.2.2 + with: + working_directory: './examples/github-oidc/' + diff --git a/_example/complete/example.tf b/examples/complete/main.tf similarity index 98% rename from _example/complete/example.tf rename to examples/complete/main.tf index d170e28..b5d8f07 100644 --- a/_example/complete/example.tf +++ b/examples/complete/main.tf @@ -3,7 +3,7 @@ provider "aws" { } locals { - name = "role" + name = "role-test" environment = "test" } @@ -48,3 +48,4 @@ data "aws_iam_policy_document" "iam-policy" { resources = ["*"] } } + diff --git a/_example/complete/outputs.tf b/examples/complete/outputs.tf similarity index 100% rename from _example/complete/outputs.tf rename to examples/complete/outputs.tf diff --git a/_example/complete/versions.tf b/examples/complete/versions.tf similarity index 100% rename from _example/complete/versions.tf rename to examples/complete/versions.tf diff --git a/examples/github-oidc/main.tf b/examples/github-oidc/main.tf new file mode 100644 index 0000000..34f686f --- /dev/null +++ b/examples/github-oidc/main.tf @@ -0,0 +1,26 @@ +provider "aws" { + region = "eu-west-1" +} + +locals { + name = "role-test" + environment = "test" +} + +##----------------------------------------------------------------------------- +## GitHub OIDC role module call. +##----------------------------------------------------------------------------- + +module "aws_github_oidc_role" { + source = "../../modules/aws_github_oidc_role" + + environment = local.environment + name = local.name + repository = "terraform-aws-iam-role" + oidc_github_repos = ["clouddrove/terraform-aws-iam-role"] + role_name = "github-oidc-terraform-role" + oidc_provider_exists = true + provider_url = "https://token.actions.githubusercontent.com" + policy_arns = ["arn:aws:iam::aws:policy/AdministratorAccess"] +} + diff --git a/examples/github-oidc/outputs.tf b/examples/github-oidc/outputs.tf new file mode 100644 index 0000000..cbdd85f --- /dev/null +++ b/examples/github-oidc/outputs.tf @@ -0,0 +1,13 @@ +# ################################################################################ +# # GitHub OIDC Provider +# ################################################################################ + +output "provider_arn" { + description = "The ARN assigned by AWS for this provider" + value = module.aws_github_oidc_role.arn +} + +output "tags" { + description = "The gets tags provided for role" + value = module.aws_github_oidc_role.tags +} diff --git a/examples/github-oidc/versions.tf b/examples/github-oidc/versions.tf new file mode 100644 index 0000000..3d21c08 --- /dev/null +++ b/examples/github-oidc/versions.tf @@ -0,0 +1,15 @@ +# Terraform version +terraform { + required_version = ">= 1.6.6" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.31.0" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.5" + } + } +} diff --git a/main.tf b/main.tf index 63a50b3..c24f174 100644 --- a/main.tf +++ b/main.tf @@ -47,3 +47,4 @@ resource "aws_iam_role_policy_attachment" "default" { role = aws_iam_role.default[0].id policy_arn = var.policy_arn } + diff --git a/modules/aws_github_oidc_role/README.md b/modules/aws_github_oidc_role/README.md new file mode 100644 index 0000000..f5fbfe5 --- /dev/null +++ b/modules/aws_github_oidc_role/README.md @@ -0,0 +1,68 @@ +# Terraform Configuration for AWS IAM GitHub OIDC Role + +Creates an IAM role that trust the IAM GitHub OIDC provider. + +## Prerequisites + +Before using this configuration, make sure you have the following prerequisites: + +- [Terraform](https://www.terraform.io/) installed on your local machine. +- Appropriate AWS credentials and permissions to create IAM resources. + +## Example +```bash + module "aws_oidc_role" { + source = "clouddrove/iam-role/aws//modules/aws_github_oidc_role" + + # Module input variables + provider_url = "https://token.actions.githubusercontent.com" + oidc_github_repos = ["username/reponame"] + role_name = "GitHub-Deploy-Role" + oidc_provider_exists = false + name = "app" #For taggs + repository = "repository-name" #For taggs + environment = "control-tower" #Environment for tag + managedby = "hello@clouddrove.com" + custom_assume_role_policy = "" # If you have your own policy add this variable + +} +``` + +4. Initialize the Terraform working directory: + + ```bash + terraform init + +5. Review the Terraform plan: + + ```bash + terraform plan + +5. Apply the configuration to create the AWS resources: + + ```bash + terraform apply + +6. Confirm the changes by typing yes when prompted. +7. The configuration will create the specified IAM Role and OpenID Connect Provider. If var.enable is set to true, it will also attach the AdministratorAccess policy to the IAM Role. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| oidc_provider_exists | Mention oidc provider exist or not in true or false. | `bool` | false | yes | +| role_name | Role name . | `string` | `GitHub-Deploy-Role` | yes | +| oidc_github_repos | GitHub repository to set IAM Role conditions . | `list(string)` | `""` | yes | +| provider_url | URL for the OIDC provider. | `string` | `https://token.actions.githubusercontent.com` | yes | +| environment | Environment for tag, (e.g. `prod`, `dev`, `staging`). | `string` | `""` | yes | +| managedby | ManagedBy for tag, eg 'CloudDrove' | `string` | `"hello@clouddrove.com"` | yes | +| name | Name for tag (e.g. `app` or `cluster`). | `string` | `""` | yes | +| repository | repsoitory name for tag| `string` | `""` | yes | +| policy_arns | A list of ARNs of policies to attach to the IAM role| `list(string)` | `["arn:aws:iam::aws:policy/AdministratorAccess"]` | yes | + +## Cleanup +1. To destroy the created resources, run: + ```bash + terraform destroy + +2. Confirm the destruction by typing yes when prompted. diff --git a/modules/aws_github_oidc_role/main.tf b/modules/aws_github_oidc_role/main.tf new file mode 100644 index 0000000..c5eae75 --- /dev/null +++ b/modules/aws_github_oidc_role/main.tf @@ -0,0 +1,88 @@ + + +##----------------------------------------------------------------------------- +## Labels module callled that will be used for naming and tags. +##----------------------------------------------------------------------------- +module "labels" { + source = "clouddrove/labels/aws" + version = "1.3.0" + + name = var.name + repository = var.repository + environment = var.environment + managedby = var.managedby + label_order = var.label_order +} + +##----------------------------------------------------------------------------- +## Data block to tls certificate. +##----------------------------------------------------------------------------- + +data "tls_certificate" "github" { + url = var.provider_url +} + +##----------------------------------------------------------------------------- +## Data block for openid connect provider +##----------------------------------------------------------------------------- + +data "aws_iam_openid_connect_provider" "github" { + count = var.oidc_provider_exists ? 1 : 0 + url = var.provider_url +} + +##----------------------------------------------------------------------------- +## Include iam openid connect provider resource here +##----------------------------------------------------------------------------- + + +resource "aws_iam_openid_connect_provider" "github" { + count = var.oidc_provider_exists ? 0 : 1 + client_id_list = ["sts.amazonaws.com"] + thumbprint_list = var.oidc_provider_exists ? [] : [data.tls_certificate.github.certificates[0].sha1_fingerprint] + url = var.provider_url + tags = module.labels.tags +} + +##----------------------------------------------------------------------------- +## Include the role resource and attachment here +##----------------------------------------------------------------------------- + +resource "aws_iam_role" "github" { + name = var.role_name + tags = module.labels.tags + assume_role_policy = var.custom_assume_role_policy != "" ? var.custom_assume_role_policy : jsonencode({ + Version = "2012-10-17", + Statement = [ + { + Effect = "Allow", + Principal = { + Federated = var.oidc_provider_exists ? data.aws_iam_openid_connect_provider.github[0].arn : aws_iam_openid_connect_provider.github[0].arn + + }, + Action = "sts:AssumeRoleWithWebIdentity", + Condition = { + StringEquals = { + "token.actions.githubusercontent.com:aud" = "sts.amazonaws.com" + }, + "ForAnyValue:StringLike" = { + "token.actions.githubusercontent.com:sub" = [ + for repo in var.oidc_github_repos : "repo:${repo}:*" + ] + } + } + + } + ] + }) +} + +##----------------------------------------------------------------------------- +## Include the iam role policy resource attachment here +##----------------------------------------------------------------------------- + +resource "aws_iam_role_policy_attachment" "github" { + count = length(var.policy_arns) + role = aws_iam_role.github.name + policy_arn = var.policy_arns[count.index] +} \ No newline at end of file diff --git a/modules/aws_github_oidc_role/outputs.tf b/modules/aws_github_oidc_role/outputs.tf new file mode 100644 index 0000000..e955bcf --- /dev/null +++ b/modules/aws_github_oidc_role/outputs.tf @@ -0,0 +1,9 @@ +output "arn" { + description = "The ARN assigned by AWS for this provider" + value = aws_iam_role.github[*].arn +} + +output "tags" { + description = "The gets tags provided for role" + value = module.labels.tags +} \ No newline at end of file diff --git a/modules/aws_github_oidc_role/variables.tf b/modules/aws_github_oidc_role/variables.tf new file mode 100644 index 0000000..e8edbcc --- /dev/null +++ b/modules/aws_github_oidc_role/variables.tf @@ -0,0 +1,66 @@ +#Module : LABEL +#Description : Terraform label module variables + +variable "name" { + type = string + description = "Name for tags" +} + +variable "repository" { + type = string + default = "https://github.com/clouddrove/terraform-aws-iam-role.git" + description = "Repository name for tags" +} + +variable "environment" { + type = string + description = "Environment name for tags" +} + +variable "managedby" { + type = string + default = "hello@clouddrove.com" + description = "Managed by for tags" +} + +variable "label_order" { + type = list(any) + default = ["name", "environment"] + description = "Label order, e.g. `name`,`application`." +} + +#Module : OIDC +#Description : Terraform github oidc module variables + +variable "provider_url" { + type = string + description = "The URL of the identity provider for the OIDC" +} + +variable "custom_assume_role_policy" { + type = string + default = "" + description = "The custom json trusted_policy for attached to the role" +} + +variable "oidc_github_repos" { + type = list(string) + description = "GitHub repository names for access" +} + +variable "role_name" { + type = string + description = "Name of the AWS IAM Role to create" +} + +variable "oidc_provider_exists" { + type = bool + default = true + description = "Mention oidc provider exist or not in true or false" +} + +variable "policy_arns" { + type = list(string) + description = "A list of policies/permissions to attach to the IAM role." +} + diff --git a/modules/aws_github_oidc_role/versions.tf b/modules/aws_github_oidc_role/versions.tf new file mode 100644 index 0000000..3d21c08 --- /dev/null +++ b/modules/aws_github_oidc_role/versions.tf @@ -0,0 +1,15 @@ +# Terraform version +terraform { + required_version = ">= 1.6.6" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.31.0" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.5" + } + } +}