Skip to content

Commit

Permalink
Terraform Modules migration: 0f411b0
Browse files Browse the repository at this point in the history
  • Loading branch information
Berger91 committed Feb 24, 2023
0 parents commit 1b2f055
Show file tree
Hide file tree
Showing 66 changed files with 1,847 additions and 0 deletions.
50 changes: 50 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# These are some examples of commonly ignored file patterns.
# You should customize this list as applicable to your project.
# Learn more about .gitignore:
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore

# Node artifact files
node_modules/
dist/

# Compiled Java class files
*.class

# Compiled Python bytecode
*.py[cod]

# Log files
*.log

# Package files
*.jar

# Maven
target/
dist/

# JetBrains IDE
.idea/

# Unit test reports
TEST*.xml

# Generated by MacOS
.DS_Store

# Generated by Windows
Thumbs.db

# Applications
*.app
*.exe
*.war

# Large media files
*.mp4
*.tiff
*.avi
*.flv
*.mov
*.wmv

58 changes: 58 additions & 0 deletions aws_iam_identity_provider/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# AWS IAM Identity Provider
This module configures the identity provider for the organization.

## Requirements
* Organization must be created.
* SSO authentication must be enabled within IAM Identity Center. For details on enabling SSO authentication, see [Getting Started](https://docs.aws.amazon.com/singlesignon/latest/userguide/getting-started.html) in the AWS IAM Identity Center (successor to AWS Single Sign-On) User Guide.
* External identity provider must be set within IAM Identity Center (if you are using external provider for SSO).

## Usage
```hcl
module aws_iam_identity_provider {
source = "git::ssh://[email protected]/thesoftwarehouse/terraform-modules-bis.git//aws_iam_identity_provider"
# Configuration options
}
```
## Examples
### Create a 'AdministratorAccess' predefined permission set
```hcl
module aws_iam_identity_provider {
source = "git::ssh://[email protected]/thesoftwarehouse/terraform-modules-bis.git//aws_iam_identity_provider"
permision_sets = {
"AdministratorAccess" = {
session_duration = "PT1H"
predefined_permission_set = "AdministratorAccess"
}
}
}
```

### Create a custom permission set with permission to describe EC2 instances
```hcl
module aws_iam_identity_provider {
source = "git::ssh://[email protected]/thesoftwarehouse/terraform-modules-bis.git//aws_iam_identity_provider"
permission_sets = {
"DescribeEC2" = {
session_duration = "PT2H"
relay_state = "https://eu-central-1.console.aws.amazon.com/ec2/"
description = "This policy grants permissions to describe EC2 instances."
custom_permission_set = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ec2:Describe*",
]
Effect = "Allow"
Resource = "*"
},
]
})
}
}
}
```
50 changes: 50 additions & 0 deletions aws_iam_identity_provider/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
locals {
default_session_duration = "PT1H"

predefined_permission_sets = { for name, permission_set in var.permission_sets : name => {
predefined_permission_set = permission_set.predefined_permission_set
description = permission_set.description != null ? permission_set.description : local.predefined_permission_set_definitions[permission_set.predefined_permission_set].description
relay_state = permission_set.relay_state
session_duration = permission_set.session_duration != null ? permission_set.session_duration : local.default_session_duration
} if try(permission_set.predefined_permission_set, null) != null }

custom_permission_sets = { for name, permission_set in var.permission_sets : name => {
custom_permission_set = permission_set.custom_permission_set
description = permission_set.description
relay_state = permission_set.relay_state
session_duration = permission_set.session_duration != null ? permission_set.session_duration : local.default_session_duration
} if try(permission_set.custom_permission_set, null) != null }

predefined_permission_set_definitions = {
"AdministratorAccess" = {
description = "Provides full access to AWS services and resources."
}
"Billing" = {
description = "Grants permissions for billing and cost management. This includes viewing account usage and viewing and modifying budgets and payment methods."
}
"DatabaseAdministrator" = {
description = "Grants full access permissions to AWS services and actions required to set up and configure AWS database services."
}
"DataScientist" = {
description = "Grants permissions to AWS data analytics services."
}
"NetworkAdministrator" = {
description = "Grants full access permissions to AWS services and actions required to set up and configure AWS network resources."
}
"PowerUserAccess" = {
description = "Provides full access to AWS services and resources, but does not allow management of Users and groups."
}
"SecurityAudit" = {
description = "The security audit template grants access to read security configuration metadata. It is useful for software that audits the configuration of an AWS account."
}
"SupportUser" = {
description = "This policy grants permissions to troubleshoot and resolve issues in an AWS account. This policy also enables the user to contact AWS support to create and manage cases."
}
"SystemAdministrator" = {
description = "Grants full access permissions necessary for resources required for application and development operations."
}
"ViewOnlyAccess" = {
description = "This policy grants permissions to view resources and basic metadata across all AWS services."
}
}
}
50 changes: 50 additions & 0 deletions aws_iam_identity_provider/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
data "aws_ssoadmin_instances" "this" {}

# Predefined permision set
data "aws_iam_policy" "predefined" {
for_each = local.predefined_permission_set_definitions
name = each.key
}

resource "aws_ssoadmin_permission_set" "predefined" {
for_each = local.predefined_permission_sets
name = each.key
description = each.value["description"]
relay_state = each.value["relay_state"]
session_duration = each.value["session_duration"]
instance_arn = tolist(data.aws_ssoadmin_instances.this.arns)[0]
}

resource "aws_ssoadmin_managed_policy_attachment" "predefined" {
for_each = local.predefined_permission_sets
instance_arn = tolist(data.aws_ssoadmin_instances.this.arns)[0]
managed_policy_arn = data.aws_iam_policy.predefined[each.value["predefined_permission_set"]].arn
permission_set_arn = aws_ssoadmin_permission_set.predefined[each.key].arn
}

# Custom permission set
resource "aws_iam_policy" "custom" {
for_each = local.custom_permission_sets
name = format("%s_PermissionSet", each.key)
description = each.value["description"]
policy = each.value["custom_permission_set"]
}

resource "aws_ssoadmin_permission_set" "custom" {
for_each = local.custom_permission_sets
name = each.key
description = each.value["description"]
relay_state = each.value["relay_state"]
session_duration = each.value["session_duration"]
instance_arn = tolist(data.aws_ssoadmin_instances.this.arns)[0]
}

resource "aws_ssoadmin_customer_managed_policy_attachment" "custom" {
for_each = local.custom_permission_sets
instance_arn = aws_ssoadmin_permission_set.custom[each.key].instance_arn
permission_set_arn = aws_ssoadmin_permission_set.custom[each.key].arn
customer_managed_policy_reference {
name = aws_iam_policy.custom[each.key].name
path = "/"
}
}
4 changes: 4 additions & 0 deletions aws_iam_identity_provider/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "permission_set_arns" {
value = merge({ for i in aws_ssoadmin_permission_set.predefined : i.name => i.arn }, { for i in aws_ssoadmin_permission_set.custom : i.name => i.arn })
description = "A map of permission set ARNs."
}
34 changes: 34 additions & 0 deletions aws_iam_identity_provider/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
variable "permission_sets" {
type = map(object(
{
description = optional(string)
relay_state = optional(string)
session_duration = optional(string)
predefined_permission_set = optional(string)
custom_permission_set = optional(string)
}
))
description = "A map of permission sets to be created in the organization."

validation {
condition = alltrue([for i in var.permission_sets : i.custom_permission_set == null if try(i.predefined_permission_set, null) != null])
error_message = "A predefined_permission_set cannot be set together with a custom_permission_set in the same object."
}

# Predefined permision set
validation { # Predefined permission set must be one of the AWS managed policy (predefined permission set list)
condition = alltrue([for i in var.permission_sets : contains(["AdministratorAccess", "Billing", "DatabaseAdministrator", "DataScientist", "NetworkAdministrator", "PowerUserAccess", "SecurityAudit", "SupportUser", "SystemAdministrator", "ViewOnlyAccess"], i.predefined_permission_set) if try(i.predefined_permission_set, null) != null])
error_message = "A predefined_permission_set value must be one of the following: 'AdministratorAccess', 'Billing', 'DatabaseAdministrator', 'DataScientist', 'NetworkAdministrator', 'PowerUserAccess', 'SecurityAudit', 'SupportUser', 'SystemAdministrator', 'ViewOnlyAccess'."
}

validation {
condition = length([for i in var.permission_sets : i.predefined_permission_set if try(i.predefined_permission_set, null) != null]) == length(distinct([for i in var.permission_sets : i.predefined_permission_set if try(i.predefined_permission_set, null) != null]))
error_message = "All predefined_permission_set values must be unique."
}

# Custom permision set
validation { # Policy must be JSON code
condition = alltrue([for i in var.permission_sets : can(jsondecode(i.custom_permission_set)) if try(i.custom_permission_set, null) != null])
error_message = "A custom_permission_set value must be valid JSON code."
}
}
Empty file.
24 changes: 24 additions & 0 deletions aws_identity_providers/modules/bitbucket_oidc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# AWS Bitbucket OIDC Provider

Terraform module which creates OIDC provider and access roles for specific Bitbucket repositories.

## Usage

```hcl
module "aws-bitbucket-oidc-provider" {
source = "git::ssh://[email protected]/thesoftwarehouse/terraform-modules.git//aws_bitbucket_oidc_provider?ref=main"
# Open a Bitbucket repository and go to Repository settings -> OpenID Connect in the Pipelines section to get all the details.
identity_provider_url = "<PROVIDER_URL>"
audience = "<AUDIENCE>"
thumbprints = ["<THUMBPRINT>"]
roles = {
"<ROLE_NAME>" = {
create = true
repository_uuids = ["{<REPOSITORY_UUID>}"]
}
}
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AssumeRole",
"Effect": "Allow",
"Action": [
"sts:GetSessionToken",
"sts:AssumeRole",
"sts:GetFederationToken",
"sts:GetAccessKeyInfo",
"sts:GetCallerIdentity",
"sts:GetServiceBearerToken",
"sts:AssumeRoleWithWebIdentity"
],
"Resource": "*"
}
]
}
9 changes: 9 additions & 0 deletions aws_identity_providers/modules/bitbucket_oidc/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
locals {
common = {
tags = {
created_by = "Terraform"
}
}

bitbucket_oidc_policy = file("${path.module}/json/bitbucket_oidc_policy.json")
}
43 changes: 43 additions & 0 deletions aws_identity_providers/modules/bitbucket_oidc/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module "iam_iam-assumable-role-with-oidc" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "5.8.0"
for_each = var.roles

create_role = true
role_name = each.key # ^[\w+=,.@-]{1,64}$
role_description = "Role that can be assumed using Bitbucket Pipelines with OIDC provider."
aws_account_id = data.aws_caller_identity.current.account_id
provider_url = trimprefix(var.identity_providers[each.value["provider"]].identity_provider_url, "https://")
role_policy_arns = [module.iam_iam-policy.arn]
oidc_subjects_with_wildcards = formatlist("%s:*", each.value["repository_uuids"])

# tags = merge(
# local.common.tags,
# {
# Project = each.key
# }
# )
}

data "aws_caller_identity" "current" {}

resource "aws_iam_openid_connect_provider" "this" {
for_each = var.identity_providers
url = each.value["identity_provider_url"]
client_id_list = [each.value["audience"]]
thumbprint_list = each.value["thumbprints"]

# tags = local.common.tags
}

module "iam_iam-policy" {
source = "terraform-aws-modules/iam/aws//modules/iam-policy"
version = "5.9.0"

create_policy = true
name = "BitbucketOIDCPolicy"
description = "Allows to assume a role by BitbucketOIDC roles."
path = "/"
policy = local.bitbucket_oidc_policy
# tags = local.common.tags
}
35 changes: 35 additions & 0 deletions aws_identity_providers/modules/bitbucket_oidc/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
variable "identity_providers" {
type = map(object(
{
identity_provider_url = string
audience = string
thumbprints = list(string)
}
))
description = ""

validation {
condition = alltrue([for provider in var.identity_providers : startswith(provider.identity_provider_url, "https://")])
error_message = "The identity_provider_url must begin with 'https://'."
}

validation {
condition = alltrue([for provider in var.identity_providers : length(provider.thumbprints) <= 5 && length(provider.thumbprints) == length(distinct(provider.thumbprints))])
error_message = "All thumbprints must be unique. The maximum number is 5."
}
}

variable "roles" {
type = map(object(
{
provider = string
repository_uuids = list(string)
}
))
description = ""

validation {
condition = alltrue([for role in var.roles : can([for repo in role.repository_uuids : regex("^{([0-9a-z]+[-])+([0-9a-z]+)}$", repo)])])
error_message = "The repository_uuid must consist of characters in the ranges [a-z], [0-9] and '-'. The repository_uuid must start with '{' and end with '}' characters."
}
}
Loading

0 comments on commit 1b2f055

Please sign in to comment.