majuna/app/terraform/static/aws.py

151 lines
5.5 KiB
Python
Raw Permalink Normal View History

import logging
import os
from datetime import datetime, timezone
from typing import Any, List
from flask import current_app
from app.extensions import db
from app.models.base import Group
from app.models.cloud import CloudAccount, CloudProvider
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.")
2024-12-06 18:15:47 +00:00
if "values" not in state or "child_modules" not in state["values"]["root_module"]:
# There are no CloudFront origins deployed to import state for
return
# CloudFront distributions (origins)
2024-12-06 18:15:47 +00:00
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)
2024-12-06 18:15:47 +00:00
for res in mod["resources"]:
if res["address"].endswith("aws_cloudfront_distribution.this"):
logging.debug("and found related cloudfront distribution")
2024-12-06 18:15:47 +00:00
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.now(tz=timezone.utc)
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,
2024-12-06 18:15:47 +00:00
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}"
}}""",
2024-12-06 18:15:47 +00:00
**{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())