Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AIVA2/CCM-5680 setup terraform components #4

Merged
merged 7 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

terraform 1.7.0
pre-commit 3.6.0

tfsec 1.28.6
# ==============================================================================
# The section below is reserved for Docker image versions.

Expand Down
Empty file removed infrastructure/images/.gitkeep
Empty file.
Empty file removed infrastructure/modules/.gitkeep
Empty file.
60 changes: 60 additions & 0 deletions infrastructure/terraform/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
### Terraform ###

# Transient backends
components/**/backend_tfscaffold.tf

# Compiled files
**/*.tfstate
**/*.tfplan
**/*.tfstate.backup
**/.terraform
**/.terraform.lock.hcl
**/.terraform/*
**/build/*
**/work/*
**/*tfstate.lock.info

# Scaffold Plugin Cache
plugin-cache/*

# PyCache
**/__pycache__

### OSX ###
**/.DS_Store
**/.AppleDouble
**/.LSOverride

# Icon must end with two \r
Icon

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

*.swp
.nyc_output

# VS Code
.vscode

# IntelliJ Idea
.idea
**/*.iml

# js
node_modules
1 change: 1 addition & 0 deletions infrastructure/terraform/components/acct/.tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform 1.9.2
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
resource "aws_cloudwatch_log_group" "aws_route53_query_log" {
provider = aws.us-east-1 # Route53 query logging must be in us-east-1 https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_query_log

name = "/aws/route53/${local.csi}"
retention_in_days = var.log_retention_in_days
}

resource "aws_cloudwatch_log_resource_policy" "route53_query_logging_policy" {
provider = aws.us-east-1 # Route53 query logging must be in us-east-1 https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_query_log

policy_document = data.aws_iam_policy_document.route53_logs.json
policy_name = "${local.csi}-route53-query-logging-policy"
}

data "aws_iam_policy_document" "route53_logs" {
statement {
effect = "Allow"

principals {
type = "Service"

identifiers = [
"route53.amazonaws.com"
]
}

actions = [
"logs:CreateLogStream",
"logs:PutLogEvents",
]

resources = [
aws_cloudwatch_log_group.aws_route53_query_log.arn,
"${aws_cloudwatch_log_group.aws_route53_query_log.arn}:*"
]
}
}
44 changes: 44 additions & 0 deletions infrastructure/terraform/components/acct/locals_tfscaffold.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
locals {
terraform_state_bucket = format(
"%s-tfscaffold-%s-%s",
var.project,
var.aws_account_id,
var.region,
)

csi = replace(
format(
"%s-%s-%s",
var.project,
var.environment,
var.component,
),
"_",
"",
)

# CSI for use in resources with a global namespace, i.e. S3 Buckets
csi_global = replace(
format(
"%s-%s-%s-%s-%s",
var.project,
var.aws_account_id,
var.region,
var.environment,
var.component,
),
"_",
"",
)

default_tags = merge(
var.default_tags,
{
Project = var.project
Environment = var.environment
Component = var.component
Group = var.group
Name = local.csi
},
)
}
11 changes: 11 additions & 0 deletions infrastructure/terraform/components/acct/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
output "dns_zone" {
value = {
id = aws_route53_zone.main.id
name = aws_route53_zone.main.name
nameservers = aws_route53_zone.main.name_servers
}
}

output "github_pat_ssm_param_name" {
value = aws_ssm_parameter.github_pat.name
}
24 changes: 24 additions & 0 deletions infrastructure/terraform/components/acct/provider_aws.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
provider "aws" {
region = var.region

allowed_account_ids = [
var.aws_account_id,
]

default_tags {
tags = local.default_tags
}
}

provider "aws" {
alias = "us-east-1"
region = "us-east-1"

default_tags {
tags = local.default_tags
}

allowed_account_ids = [
var.aws_account_id,
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "aws_route53_delegation_set" "main" {
reference_name = "iam.${var.root_domain_name}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
resource "aws_route53_query_log" "main" {
zone_id = aws_route53_zone.main.zone_id

cloudwatch_log_group_arn = aws_cloudwatch_log_group.aws_route53_query_log.arn

depends_on = [
aws_cloudwatch_log_resource_policy.route53_query_logging_policy
]
}
5 changes: 5 additions & 0 deletions infrastructure/terraform/components/acct/route53_zone.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "aws_route53_zone" "main" {
name = "iam.${var.root_domain_name}"

delegation_set_id = aws_route53_delegation_set.main.id
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
resource "aws_ssm_parameter" "github_pat" {
name = "/${local.csi}/github_pat"
description = "A GitHub PAT token for settings up AWS Amplify. This is only used at initial setup of the service"
type = "SecureString"
value = try(var.initial_cli_secrets_provision_override.github_pat, "UNSET")

lifecycle {
ignore_changes = [value]
}
}

# This can be set at provision time like:
# PARAM_OBJECT=$(jq -n \
# --arg github_pat "github_pat_123abc" \
# '{github_pat:$github_pat}' | jq -R)
# .bin/terraform <args> .. -a apply -- -var="initial_cli_secrets_provision_override=${PARAM_OBJECT}"
72 changes: 72 additions & 0 deletions infrastructure/terraform/components/acct/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
##
# Basic Required Variables for tfscaffold Components
##

variable "project" {
type = string
description = "The name of the tfscaffold project"
}

variable "environment" {
type = string
description = "The name of the tfscaffold environment"
}

variable "aws_account_id" {
type = string
description = "The AWS Account ID (numeric)"
}

variable "region" {
type = string
description = "The AWS Region"
}

variable "group" {
type = string
description = "The group variables are being inherited from (often synonmous with account short-name)"
}

##
# tfscaffold variables specific to this component
##

# This is the only primary variable to have its value defined as
# a default within its declaration in this file, because the variables
# purpose is as an identifier unique to this component, rather
# then to the environment from where all other variables come.
variable "component" {
type = string
description = "The variable encapsulating the name of this component"
default = "acct"
}

variable "default_tags" {
type = map(string)
description = "A map of default tags to apply to all taggable resources within the component"
default = {}
}

##
# Variables specific to the "dnsroot"component
##

variable "log_retention_in_days" {
type = number
description = "The retention period in days for the Cloudwatch Logs events to be retained, default of 0 is indefinite"
default = 0
}

variable "root_domain_name" {
type = string
description = "The service's root DNS root nameespace, like nonprod.nhsnotify.national.nhs.uk"
default = "nonprod.nhsnotify.national.nhs.uk"
}

variable "initial_cli_secrets_provision_override" {
type = map(string)
description = "A map of default value to intialise SSM secret values with. Only useful for initial setup of the account due to lifecycle rules."
default = {}
# Usage like:
# ... -a apply -- -var initial_cli_secrets_provision_override={\"github_pat\":\"l0ngstr1ng"}
}
10 changes: 10 additions & 0 deletions infrastructure/terraform/components/acct/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.50"
}
}

required_version = ">= 1.9.0"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform 1.9.2
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
locals {
bootstrap = data.terraform_remote_state.bootstrap.outputs
acct = data.terraform_remote_state.acct.outputs
iam = data.terraform_remote_state.iam.outputs
}

data "terraform_remote_state" "bootstrap" {
backend = "s3"

config = {
bucket = local.terraform_state_bucket

key = format(
"%s/%s/%s/%s/bootstrap.tfstate",
var.project,
var.aws_account_id,
"eu-west-2",
"bootstrap"
)

region = "eu-west-2"
}
}

data "terraform_remote_state" "acct" {
backend = "s3"

config = {
bucket = local.terraform_state_bucket

key = format(
"%s/%s/%s/%s/acct.tfstate",
var.project,
var.aws_account_id,
"eu-west-2",
"main"
)

region = "eu-west-2"
}
}

data "terraform_remote_state" "iam" {
backend = "s3"

config = {
bucket = local.terraform_state_bucket

key = format(
"%s/%s/%s/%s/iam.tfstate",
var.project,
var.aws_account_id,
"eu-west-2",
var.parent_amplify_environment,
)

region = "eu-west-2"
}
}


Loading
Loading