Skip to content

Commit

Permalink
HTTPS certificates
Browse files Browse the repository at this point in the history
  • Loading branch information
tiagojsag committed Feb 25, 2022
1 parent 56f61d4 commit 5b5b95a
Show file tree
Hide file tree
Showing 29 changed files with 508 additions and 21 deletions.
7 changes: 7 additions & 0 deletions infrastructure/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,19 @@ module "network" {
project_name = var.project_name
}

module "dns" {
source = "./modules/dns"
resource_group = data.azurerm_resource_group.resource_group
domain = var.domain
}

module "bastion" {
source = "./modules/bastion"
resource_group = data.azurerm_resource_group.resource_group
project_name = var.project_name
bastion_ssh_public_keys = var.bastion_ssh_public_keys
bastion_subnet_id = module.network.bastion_subnet_id
dns_zone = module.dns.dns_zone
}

module "container_registry" {
Expand Down
8 changes: 8 additions & 0 deletions infrastructure/modules/bastion/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,11 @@ resource "azurerm_linux_virtual_machine" "bastion" {
version = "latest"
}
}

resource "azurerm_dns_a_record" "bastion_dns_record" {
name = "bastion"
zone_name = var.dns_zone.name
resource_group_name = var.resource_group.name
ttl = 300
records = [azurerm_linux_virtual_machine.bastion.public_ip_address]
}
4 changes: 4 additions & 0 deletions infrastructure/modules/bastion/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
output "bastion_public_ip" {
value = azurerm_linux_virtual_machine.bastion.public_ip_address
}

output "bastion_hostname" {
value = azurerm_dns_a_record.bastion_dns_record.fqdn
}
4 changes: 4 additions & 0 deletions infrastructure/modules/bastion/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ variable "bastion_host_size" {
variable "bastion_subnet_id" {
description = "The id of the subnet where the bastion host will be placed"
}

variable "dns_zone" {
description = "The Azure DNS zone where the bastion A record will be added"
}
4 changes: 4 additions & 0 deletions infrastructure/modules/dns/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
resource "azurerm_dns_zone" "marxan" {
name = var.domain
resource_group_name = var.resource_group.name
}
3 changes: 3 additions & 0 deletions infrastructure/modules/dns/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "dns_zone" {
value = azurerm_dns_zone.marxan
}
7 changes: 7 additions & 0 deletions infrastructure/modules/dns/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
variable "resource_group" {
description = "The Azure resource group where the module will create its resources"
}

variable "domain" {
description = "The domain name"
}
2 changes: 1 addition & 1 deletion infrastructure/modules/node_pool/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ variable "min_node_count" {

variable "max_node_count" {
type = number
default = 2
default = 4
description = "The maximum number of machines in this pool"
}

Expand Down
25 changes: 17 additions & 8 deletions infrastructure/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
output "client_certificate" {
value = module.kubernetes.client_certificate
sensitive = true
}

output "aks_cluster_name" {
output "k8s_cluster_name" {
value = module.kubernetes.cluster_name
description = "AKS cluster name"
}

output "kube_config" {
value = module.kubernetes.kube_config

sensitive = true
}

output "azurerm_container_registry_login_server" {
output "container_registry_hostname" {
value = module.container_registry.azurerm_container_registry_login_server
}

output "azuread_application_password" {
output "container_registry_password" {
value = module.container_registry.azuread_application_password
sensitive = true
}

output "azure_client_id" {
output "container_registry_client_id" {
value = module.container_registry.azure_client_id
}

Expand All @@ -37,15 +38,23 @@ output "bastion_public_ip" {
value = module.bastion.bastion_public_ip
}

output "redis_url" {
output "bastion_hostname" {
value = module.bastion.bastion_hostname
}

output "redis_hostname" {
value = module.redis.redis_url
}

output "redis_port" {
value = module.redis.redis_port
}

output "redis_password" {
value = module.redis.redis_password
sensitive = true
}

output "redis_port" {
value = module.redis.redis_port
output "dns_zone_name" {
value = module.dns.dns_zone.name
}
5 changes: 5 additions & 0 deletions infrastructure/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,8 @@ variable "solution_plan_map" {
}
type = map(any)
}

variable "domain" {
type = string
description = "The domain name"
}
1 change: 1 addition & 0 deletions infrastructure/vars/terraform.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ bastion_ssh_public_keys = [{
user = "ubuntu"
key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsQgoIZQAVAMFnESCsYotosbp3N2n8onp8Xmn0DZJmCnBzkfvn2SJdTQRKcyzjcHBqrseq+8Id0JYdb1aJJT2497b7NVOWvVLgqD5pYoxwLO4m3VjppUjpOfgGk3aBpzQTGwPHMqk4X4yvHNAuQcCTxo6gNIsyJZFxdzdc2P+oDLdTwekzsQvsPscFDXDYvtLTkCnSfeZAKsbb45XiAsH0HRnwzJYPvPr69V6c1R3igc2aDZ+eI2sZPvsCXWnvJYfL0QLJp+NwqJuRzHygcxsByg9p/wTPko2vEQLGvefBqjMFHbDYRyVh1omfwt3w/l5R6Abb1Mc2sNDqhBKFEe7/"
}]
domain = "marxan.vizzuality.com"
17 changes: 17 additions & 0 deletions kubernetes/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 57 additions & 3 deletions kubernetes/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ data "terraform_remote_state" "core" {
}

data "azurerm_kubernetes_cluster" "k8s_cluster" {
name = data.terraform_remote_state.core.outputs.aks_cluster_name
name = data.terraform_remote_state.core.outputs.k8s_cluster_name
resource_group_name = data.azurerm_resource_group.resource_group.name
}

data "azurerm_dns_zone" "dns_zone" {
name = data.terraform_remote_state.core.outputs.dns_zone_name
resource_group_name = data.azurerm_resource_group.resource_group.name
}

Expand All @@ -45,6 +50,15 @@ module "k8s_namespaces" {
k8s_cluster_ca_certificate = local.k8s_cluster_ca_certificate
}

module "cert_manager" {
source = "./modules/cert_manager"
k8s_host = local.k8s_host
k8s_client_certificate = local.k8s_client_certificate
k8s_client_key = local.k8s_client_key
k8s_cluster_ca_certificate = local.k8s_cluster_ca_certificate
email = var.cert_email
}

####
# Production
####
Expand Down Expand Up @@ -103,6 +117,18 @@ module "geoprocessing_production" {
deployment_name = "geoprocessing"
}

module "client_production" {
source = "./modules/client"
k8s_host = local.k8s_host
k8s_client_certificate = local.k8s_client_certificate
k8s_client_key = local.k8s_client_key
k8s_cluster_ca_certificate = local.k8s_cluster_ca_certificate
namespace = "production"
image = "marxan.azurecr.io/marxan-client:production"
deployment_name = "client"
site_url = "http://${module.ingress_production.client_ip}"
}

module "production_secrets" {
source = "./modules/secrets"
k8s_host = local.k8s_host
Expand All @@ -113,7 +139,7 @@ module "production_secrets" {
namespace = "production"
name = "api"
key_vault_id = module.key_vault_production.key_vault_id
redis_host = data.terraform_remote_state.core.outputs.redis_url
redis_host = data.terraform_remote_state.core.outputs.redis_hostname
redis_password = data.terraform_remote_state.core.outputs.redis_password
redis_port = data.terraform_remote_state.core.outputs.redis_port
}
Expand All @@ -127,6 +153,8 @@ module "ingress_production" {
k8s_cluster_ca_certificate = local.k8s_cluster_ca_certificate
resource_group = data.azurerm_resource_group.resource_group
project_name = var.project_name
dns_zone = data.azurerm_dns_zone.dns_zone
domain = var.domain
}


Expand Down Expand Up @@ -188,6 +216,18 @@ module "geoprocessing_staging" {
deployment_name = "geoprocessing"
}

module "client_staging" {
source = "./modules/client"
k8s_host = local.k8s_host
k8s_client_certificate = local.k8s_client_certificate
k8s_client_key = local.k8s_client_key
k8s_cluster_ca_certificate = local.k8s_cluster_ca_certificate
namespace = "staging"
image = "marxan.azurecr.io/marxan-client:staging"
deployment_name = "client"
site_url = "http://${module.ingress_production.client_ip}"
}

module "staging_secrets" {
source = "./modules/secrets"
k8s_host = local.k8s_host
Expand All @@ -198,7 +238,21 @@ module "staging_secrets" {
namespace = "staging"
name = "api"
key_vault_id = module.key_vault_staging.key_vault_id
redis_host = data.terraform_remote_state.core.outputs.redis_url
redis_host = data.terraform_remote_state.core.outputs.redis_hostname
redis_password = data.terraform_remote_state.core.outputs.redis_password
redis_port = data.terraform_remote_state.core.outputs.redis_port
}

module "ingress_staging" {
source = "./modules/ingress"
namespace = "staging"
k8s_host = local.k8s_host
k8s_client_certificate = local.k8s_client_certificate
k8s_client_key = local.k8s_client_key
k8s_cluster_ca_certificate = local.k8s_cluster_ca_certificate
resource_group = data.azurerm_resource_group.resource_group
project_name = var.project_name
dns_zone = data.azurerm_dns_zone.dns_zone
domain = var.domain
domain_prefix = "staging"
}
2 changes: 1 addition & 1 deletion kubernetes/modules/api/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ resource "kubernetes_deployment" "api_deployment" {
}

env {
name = "REDIS_USE_TLS"
name = "REDIS_USE_TLS"
value = "true"
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: ${email}
# ACME server URL for Let’s Encrypt’s staging environment.
# The staging environment will not issue trusted certificates but is
# used to ensure that the verification process is working properly
# before moving to production
server: ${cert_server}
privateKeySecretRef:
# Secret resource used to store the account's private key.
name: cluster-cert-issuer-account-key
# Enable the HTTP-01 challenge provider
# you prove ownership of a domain by ensuring that a particular
# file is present at the domain
solvers:
- http01:
ingress:
class: azure/application-gateway
29 changes: 29 additions & 0 deletions kubernetes/modules/cert_manager/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
resource "helm_release" "cert-manager" {
name = "cert-manager"
repository = "https://charts.jetstack.io"
chart = "cert-manager"
version = "1.7.1"

namespace = "cert-manager"

wait = false
create_namespace = true

set {
name = "installCRDs"
value = "true"
}

set {
name = "startupapicheck.timeout"
value = "5m"
}
}


resource "kubectl_manifest" "alb_ingress_controller_main" {
yaml_body = templatefile("${path.module}/k8s_files/01_cluster-issuer.yaml.tmpl", {
email : var.email,
cert_server : var.cert_server,
})
}
30 changes: 30 additions & 0 deletions kubernetes/modules/cert_manager/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
variable "k8s_host" {
description = "Hostname of the k8s cluster"
type = string
}

variable "k8s_client_certificate" {
description = "Client certificate for the k8s cluster"
type = string
}

variable "k8s_client_key" {
description = "Client key for the k8s cluster"
type = string
}

variable "k8s_cluster_ca_certificate" {
description = "Cluster CA certificate for the k8s cluster"
type = string
}

variable "email" {
description = "Email address to use for cert renovation warnings"
type = string
}

variable "cert_server" {
description = "Lets encrypt server URL"
type = string
default = "https://acme-v02.api.letsencrypt.org/directory"
}
Loading

0 comments on commit 5b5b95a

Please sign in to comment.