diff --git a/terraform/deployments/tfc-configuration/aws/main.tf b/terraform/deployments/tfc-configuration/aws/main.tf new file mode 100644 index 000000000..d31e20d8b --- /dev/null +++ b/terraform/deployments/tfc-configuration/aws/main.tf @@ -0,0 +1,114 @@ +data "tls_certificate" "tfc_certificate" { + url = "https://${var.tfc_hostname}" +} + +resource "aws_iam_openid_connect_provider" "tfc_provider" { + url = data.tls_certificate.tfc_certificate.url + client_id_list = ["aws.workload.identity"] + thumbprint_list = [data.tls_certificate.tfc_certificate.certificates[0].sha1_fingerprint] +} + +resource "aws_iam_role" "tfc_role" { + name = "terraform-cloud" + + assume_role_policy = jsonencode({ + "Version" : "2012-10-17", + "Statement" : [ + { + "Effect" : "Allow", + "Principal" : { + "Federated" : "${aws_iam_openid_connect_provider.tfc_provider.arn}" + }, + "Action" : "sts:AssumeRoleWithWebIdentity", + "Condition" : { + "StringEquals" : { + "${var.tfc_hostname}:aud" : "${one(aws_iam_openid_connect_provider.tfc_provider.client_id_list)}" + }, + "StringLike" : { + "${var.tfc_hostname}:sub" : "organization:${var.tfc_organization_name}:project:*:workspace:*:run_phase:*" + } + } + } + ] + }) + + managed_policy_arns = [aws_iam_policy.tfc_policy.arn] +} + +resource "aws_iam_policy" "tfc_policy" { + name = "terraform-cloud-run" + description = "Permissions to allow Terraform Cloud to plan and apply" + + policy = jsonencode({ + "Version" : "2012-10-17", + "Statement" : [ + { + "Effect" : "Allow", + "Resource" : "*", + "Action" : [ + "autoscaling:*", + "cloudfront:*", + "cloudwatch:*", + "ec2:*", + "ecr:*", + "eks:*", + "elasticache:*", + "elasticloadbalancing:*", + "es:*", + "events:*", + "iam:*", + "kms:*", + "logs:*", + "mq:*", + "rds:*", + "route53:*", + "s3:*", + "sns:*", + "sqs:*", + "wafv2:*" + ] + }, + { + "Effect" : "Deny", + "Resource" : "*", + "Action" : [ + "aws-marketplace:*", + "aws-marketplace-management:*", + "aws-portal:*", + "budgets:*", + "config:*", + "directconnect:*", + "ec2:*Purchase*", + "ec2:*ReservedInstances*", + "iam:*Login*", + "iam:*Group*", + "iam:*PermissionsBoundary*", + "iam:*Provider*", + "iam:*User*", + "iam:CreateServiceLinkedRole", + "iam:PassRole" + ] + } + ] + }) +} + +resource "tfe_variable_set" "variable_set" { + name = "aws-credentials-${var.aws_environment}" +} + +resource "tfe_variable" "tfc_var_aws_provider_auth" { + key = "TFC_AWS_PROVIDER_AUTH" + value = "true" + category = "env" + description = "Configures Terraform Cloud to authenticate with AWS using dynamic credentials" + variable_set_id = tfe_variable_set.variable_set.id +} + +resource "tfe_variable" "tfc_var_aws_run_role_name" { + key = "TFC_AWS_RUN_ROLE_ARN" + value = aws_iam_role.tfc_role.arn + category = "env" + description = "The ARN of the role to assume in AWS" + variable_set_id = tfe_variable_set.variable_set.id +} diff --git a/terraform/deployments/tfc-configuration/aws/provider.tf b/terraform/deployments/tfc-configuration/aws/provider.tf new file mode 100644 index 000000000..0b9794d19 --- /dev/null +++ b/terraform/deployments/tfc-configuration/aws/provider.tf @@ -0,0 +1,31 @@ +terraform { + cloud { + organization = "govuk" + workspaces { + tags = ["tfc", "aws", "configuration"] + } + } + + required_version = "~> 1.4" + + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.5" + } + + tfe = { + version = "~> 0.47.0" + } + } +} + +provider "aws" { + region = "eu-west-1" +} + +provider "tfe" { + hostname = var.tfc_hostname + organization = var.tfc_organization_name +} + diff --git a/terraform/deployments/tfc-configuration/aws/variables.tf b/terraform/deployments/tfc-configuration/aws/variables.tf new file mode 100644 index 000000000..b8c851c32 --- /dev/null +++ b/terraform/deployments/tfc-configuration/aws/variables.tf @@ -0,0 +1,16 @@ +variable "aws_environment" { + type = string + description = "The name of the AWS environment" +} + +variable "tfc_hostname" { + type = string + default = "app.terraform.io" + description = "The hostname of the TFC or TFE to use with AWS" +} + +variable "tfc_organization_name" { + type = string + default = "govuk" + description = "The name of the Terraform Cloud organization" +}