From 5b3ca9c6133d9e6e870944256e52c784a85218d5 Mon Sep 17 00:00:00 2001 From: Tim Rickwood <48654585+timrickwood@users.noreply.github.com> Date: Wed, 12 Feb 2025 13:26:25 +0000 Subject: [PATCH] FDOS-142 Bootstrap repo dev (#5) * FDOS_142 Add bootstrapper stacks * FDOS-142 Add remote version --- infrastructure/common/common-variables.tf | 60 ++++++++++++++ infrastructure/common/locals.tf | 7 ++ infrastructure/common/provider.tf | 34 ++++++++ infrastructure/common/versions.tf | 13 +++ infrastructure/local/versions.tf | 13 +++ infrastructure/remote/versions.tf | 13 +++ infrastructure/stacks/account_wide/README.md | 9 +++ infrastructure/stacks/account_wide/iam.tf | 79 +++++++++++++++++++ .../stacks/account_wide/variables.tf | 3 + .../stacks/terraform_management/dynamodb.tf | 10 +++ .../stacks/terraform_management/s3.tf | 4 + .../stacks/terraform_management/variables.tf | 12 +++ scripts/workflow/bootstrapper.sh | 36 ++++----- 13 files changed, 275 insertions(+), 18 deletions(-) create mode 100644 infrastructure/common/common-variables.tf create mode 100644 infrastructure/common/locals.tf create mode 100644 infrastructure/common/provider.tf create mode 100644 infrastructure/common/versions.tf create mode 100644 infrastructure/local/versions.tf create mode 100644 infrastructure/remote/versions.tf create mode 100644 infrastructure/stacks/account_wide/README.md create mode 100644 infrastructure/stacks/account_wide/iam.tf create mode 100644 infrastructure/stacks/account_wide/variables.tf create mode 100644 infrastructure/stacks/terraform_management/dynamodb.tf create mode 100644 infrastructure/stacks/terraform_management/s3.tf create mode 100644 infrastructure/stacks/terraform_management/variables.tf diff --git a/infrastructure/common/common-variables.tf b/infrastructure/common/common-variables.tf new file mode 100644 index 0000000..fa383d8 --- /dev/null +++ b/infrastructure/common/common-variables.tf @@ -0,0 +1,60 @@ +variable "project" { + description = "The project code, typically reflecting a sub-project of the project owner" +} + +variable "project_owner" { + description = "The owner of the project, based on organisation and department codes" +} + +variable "environment" { + description = "The deployment environment e.g. dev, test, pre-prod, or prod" +} + +variable "repo_name" { + description = "The name of the GitHub repository associated with this project" +} + +variable "tag_version" { + description = "The version of the tagging policy in use, enabling evolution of the tagging strategy and supporting automation" + type = string +} + +variable "service" { + description = "The service or program that this project is associated with" + type = string +} + +variable "cost_centre" { + description = "The cost center used for consolidated billing and cost attribution to programs" + type = string +} + +variable "data_classification" { + description = "The data classification according to the Cloud Risk Model, enabling quick searches e.g. Low, Medium, High" + type = string +} + +variable "data_type" { + description = "The type of data handled by this project e.g. None, PCD, PII, Anonymized, UserAccount, Audit" + type = string +} + +variable "project_type" { + description = "The purpose of the resources e.g PoC, Pilot, Production" + type = string +} + +variable "public_facing" { + description = "Indicates if the project is accessible publicly via the internet" + type = string +} + +variable "service_category" { + description = "Identifies the service category to prioritize responses" + type = string +} + +variable "on_off_pattern" { + description = "Defines the automated schedule for turning resources on/off, applicable for non-production environments" + type = string +} diff --git a/infrastructure/common/locals.tf b/infrastructure/common/locals.tf new file mode 100644 index 0000000..ae27c8f --- /dev/null +++ b/infrastructure/common/locals.tf @@ -0,0 +1,7 @@ +locals { + account_id = data.aws_caller_identity.current.id + workspace_suffix = "${terraform.workspace}" == "default" ? "" : "-${terraform.workspace}" + prefix = "${var.project}-${var.environment}" + + deploy_databases = var.environment == terraform.workspace +} diff --git a/infrastructure/common/provider.tf b/infrastructure/common/provider.tf new file mode 100644 index 0000000..05c32e5 --- /dev/null +++ b/infrastructure/common/provider.tf @@ -0,0 +1,34 @@ +variable "aws_region" { + type = string + default = "eu-west-2" +} + +data "aws_caller_identity" "current" {} + +provider "aws" { + region = var.aws_region + + skip_metadata_api_check = true + skip_region_validation = true + skip_credentials_validation = true + skip_requesting_account_id = false + + default_tags { + tags = { + owner = var.project_owner + project = var.project + environment = "${var.environment}${local.workspace_suffix}" + workspace = terraform.workspace + terraform-base-path = replace(path.cwd, "/^.*?(${var.repo_name}\\/)/", "$1") + TagVersion = var.tag_version + service = var.service + CostCentre = var.cost_centre + data_classification = var.data_classification + DataType = var.data_type + ProjectType = var.project_type + PublicFacing = var.public_facing + ServiceCategory = var.service_category + OnOffPattern = var.on_off_pattern + } + } +} diff --git a/infrastructure/common/versions.tf b/infrastructure/common/versions.tf new file mode 100644 index 0000000..d49aa6e --- /dev/null +++ b/infrastructure/common/versions.tf @@ -0,0 +1,13 @@ +terraform { + required_version = ">= 1.5.0, < 1.7.2" + + backend "s3" { + } + + required_providers { + aws = { + source = "hashicorp/aws" + version = "5.70.0" + } + } +} diff --git a/infrastructure/local/versions.tf b/infrastructure/local/versions.tf new file mode 100644 index 0000000..d041768 --- /dev/null +++ b/infrastructure/local/versions.tf @@ -0,0 +1,13 @@ +terraform { + required_version = ">= 1.5.0, < 1.7.2" + + backend "local" { + } + + required_providers { + aws = { + source = "hashicorp/aws" + version = "5.70.0" + } + } +} diff --git a/infrastructure/remote/versions.tf b/infrastructure/remote/versions.tf new file mode 100644 index 0000000..d49aa6e --- /dev/null +++ b/infrastructure/remote/versions.tf @@ -0,0 +1,13 @@ +terraform { + required_version = ">= 1.5.0, < 1.7.2" + + backend "s3" { + } + + required_providers { + aws = { + source = "hashicorp/aws" + version = "5.70.0" + } + } +} diff --git a/infrastructure/stacks/account_wide/README.md b/infrastructure/stacks/account_wide/README.md new file mode 100644 index 0000000..80b4649 --- /dev/null +++ b/infrastructure/stacks/account_wide/README.md @@ -0,0 +1,9 @@ +# Account-Wide Infrastructure + +This is infrastructure that should only be deployed once per account. + +> **Note**: This should be deployed using the `default` workspace. + +Currently, the following resources are deployed: + +1. IAM role for GitHub Actions (via OIDC) diff --git a/infrastructure/stacks/account_wide/iam.tf b/infrastructure/stacks/account_wide/iam.tf new file mode 100644 index 0000000..e083867 --- /dev/null +++ b/infrastructure/stacks/account_wide/iam.tf @@ -0,0 +1,79 @@ +data "aws_iam_policy" "power_user_iam_policy" { + name = "PowerUserAccess" +} + +resource "aws_iam_role_policy_attachment" "power_user_iam_role_policy_attachment" { + role = aws_iam_role.github_runner_iam_role.name + policy_arn = data.aws_iam_policy.power_user_iam_policy.arn +} + +resource "aws_iam_policy" "read_only_user_iam_policy" { + name = "${var.repo_name}-github-runner-iam-services" + description = "Read-only policy for IAM permissions required by GitHub runner" + policy = <<-EOF + { + "Version":"2012-10-17", + "Statement": [ + { + "Action": [ + "iam:GenerateCredentialReport", + "iam:List*", + "iam:GenerateServiceLastAccessedDetails", + "iam:TagRole", + "iam:DeletePolicy", + "iam:CreateRole", + "iam:DeleteRole", + "iam:AttachRolePolicy", + "iam:TagPolicy", + "iam:CreatePolicy", + "iam:PassRole", + "iam:Get*", + "iam:DetachRolePolicy", + "iam:SimulatePrincipalPolicy", + "iam:SimulateCustomPolicy", + "iam:CreatePolicyVersion", + "iam:DeletePolicyVersion", + "iam:TagOpenIDConnectProvider", + "iam:DeleteRolePolicy", + "iam:PutRolePolicy", + "iam:UpdateOpenIDConnectProviderThumbprint", + "iam:UntagPolicy", + "iam:UntagRole" + ], + "Effect": "Allow", + "Resource": "*", + "Sid": "ReadOnlyIAM" + } + ] + } + EOF +} + +resource "aws_iam_role_policy_attachment" "read_only_user_iam_role_policy_attachment" { + role = aws_iam_role.github_runner_iam_role.name + policy_arn = aws_iam_policy.read_only_user_iam_policy.arn +} + +resource "aws_iam_role" "github_runner_iam_role" { + name = "${var.repo_name}-github-runner" + assume_role_policy = <