feat(static): adds new static origins feature

This commit is contained in:
Iain Learmonth 2023-05-25 15:32:31 +01:00
parent 6a29d68985
commit 15a85b1efe
20 changed files with 843 additions and 7 deletions

141
app/terraform/static/aws.py Normal file
View file

@ -0,0 +1,141 @@
import logging
import os
from datetime import datetime
from typing import List, Any
from flask import current_app
from app.extensions import db
from app.models.base import Group
from app.models.cloud import CloudProvider, CloudAccount
from app.models.mirrors import StaticOrigin
from app.terraform.terraform import TerraformAutomation
def import_state(state: Any) -> None:
if not isinstance(state, dict):
raise RuntimeError("The Terraform state object returned was not a dict.")
if "child_modules" not in state['values']['root_module']:
# There are no CloudFront origins deployed to import state for
return
# CloudFront distributions (origins)
for mod in state['values']['root_module']['child_modules']:
if mod['address'].startswith('module.static_'):
static_id = mod['address'][len('module.static_'):]
logging.debug("Found static module in state: %s", static_id)
for res in mod['resources']:
if res['address'].endswith('aws_cloudfront_distribution.this'):
logging.debug("and found related cloudfront distribution")
static = StaticOrigin.query.filter(StaticOrigin.id == static_id).first()
static.origin_domain_name = res['values']['domain_name']
logging.debug("and found static origin: %s to update with domain name: %s", static.id,
static.origin_domain_name)
static.terraform_updated = datetime.utcnow()
break
db.session.commit()
class StaticAWSAutomation(TerraformAutomation):
short_name = "static_aws"
description = "Deploy static origins to AWS"
provider = CloudProvider.AWS
cloud_name = "aws"
template_parameters: List[str] = []
template = """
terraform {
{{ backend_config }}
required_providers {
aws = {
version = "~> 4.67.0"
}
gitlab = {
source = "gitlabhq/gitlab"
version = "~> 15.11.0"
}
}
}
{% for group in groups %}
module "label_{{ group.id }}" {
source = "cloudposse/label/null"
version = "0.25.0"
namespace = "{{ global_namespace }}"
tenant = "{{ group.group_name }}"
label_order = ["namespace", "tenant", "name", "attributes"]
}
{% endfor %}
{% for account in source_cloud_accounts -%}
provider "gitlab" {
token = "{{ account.credentials['gitlab_token'] }}"
alias = "account_{{ account.id }}"
}
{% endfor -%}
{% for account in storage_cloud_accounts -%}
provider "aws" {
access_key = "{{ account.credentials['aws_access_key'] }}"
secret_key = "{{ account.credentials['aws_secret_key'] }}"
region = "{{ account.credentials['aws_region'] }}"
alias = "account_{{ account.id }}"
}
provider "aws" {
access_key = "{{ account.credentials['aws_access_key'] }}"
secret_key = "{{ account.credentials['aws_secret_key'] }}"
region = "us-east-1"
alias = "account_{{ account.id }}_us_east_1"
}
{% for static in account.statics | selectattr("destroyed", "none") %}
module "static_{{ static.id }}" {
providers = {
aws = aws.account_{{ account.id }}
aws.us_east_1 = aws.account_{{ account.id }}_us_east_1
gitlab = gitlab.account_{{ static.source_cloud_account_id }}
}
source = "{{ terraform_modules_path }}/terraform-aws-bc-static-origin"
name = "static"
context = module.label_{{ static.group.id }}.context
{% if static.keanu_convene_path -%}
keanu_convene_path = "{{ static.keanu_convene_path }}"
{%- endif %}
{% if static.keanu_convene_config -%}
keanu_convene_config = "{{ static.keanu_convene_config | replace('"', '\\\\"') }}"
{%- endif %}
{% if static.matrix_homeserver -%}
matrix_homeserver = "{{ static.matrix_homeserver }}"
{%- endif %}
gitlab_project = "{{ static.source_project }}"
attributes = ["{{ static.id }}"]
}
{% endfor -%}
{%- endfor %}
"""
def tf_generate(self) -> None:
groups = Group.query.all()
storage_cloud_accounts = CloudAccount.query.filter(
CloudAccount.provider == CloudProvider.AWS
).all()
source_cloud_accounts = CloudAccount.query.filter(
CloudAccount.provider == CloudProvider.GITLAB
).all()
self.tf_write(
self.template,
groups=groups,
storage_cloud_accounts=storage_cloud_accounts,
source_cloud_accounts=source_cloud_accounts,
global_namespace=current_app.config['GLOBAL_NAMESPACE'], bypass_token=current_app.config['BYPASS_TOKEN'],
terraform_modules_path=os.path.join(*list(os.path.split(current_app.root_path))[:-1], 'terraform-modules'),
backend_config=f"""backend "http" {{
lock_address = "{current_app.config['TFSTATE_BACKEND']}/{self.short_name}"
unlock_address = "{current_app.config['TFSTATE_BACKEND']}/{self.short_name}"
address = "{current_app.config['TFSTATE_BACKEND']}/{self.short_name}"
}}""",
**{k: current_app.config[k.upper()] for k in self.template_parameters})
def tf_posthook(self, *, prehook_result: Any = None) -> None:
import_state(self.tf_show())