Skip to content
Draft
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
61 changes: 61 additions & 0 deletions terraform/implementation/aca/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Data Integration Building Blocks Azure Templates

# Overview

The Data Integration Building Blocks (DIBBs) project is an effort to help state, local, territorial, and tribal public health departments better make sense of and utilize their data. You can read more about the project on the [main DIBBs repository](https://github.com/CDCgov/phdi/blob/main/README.md).

This repository is intended to provide an operational starting point for instantiating a fully-incorporated, self-sustained Azure environment that will run the DIBBs eCR Viewer pipeline. It can be deployed in full for users who wish to start an environment from scratch, or its several parts can be used to augment an existing Azure environment.

# Prerequisites

## Worker/Agent Prerequisites
The machine or deployment agent that will run this code must have the following tools installed:
* Terraform version 1.7.4 or later.
* Microsoft Azure CLI
* Docker Engine with standard Unix socket configuration (custom locations will require modification of configuration files)
* Git

## Cloud Prerequisites
The target Azure subscription must have the following:
* An existing Resource Group and Storage Account to store Terraform state files
* A Service Principal with Contributor access to the Resource Group (or an engineer with equivalent or greater access, if running from a personal machine)
* Active Azure resource providers for the services being deployed (e.g., Azure App Gateway, Azure Container Apps, etc.)

# Deployment
User-modifiable code exists in the `implementation_aca` folder. Be sure to review `_config.tf` and `main.tf` for variables and inputs that can be customized to fit your installation.

Before you deploy, ensure that you have the prerequisites installed and configured. Then, run the following commands in the `implementation_aca` folder:

```bash
terraform init
terraform plan
```
Ensure there are no configuration errors, and review the plan output to confirm that the resources to be created are as expected. If everything looks good, run:

```bash
terraform apply
```

# Deployment Sample
The `dev` folder contains a working sample of a fully-configured environment. You can use this as a reference for your own deployment.


# Notices and Disclaimers

This repository constitutes a work of the United States Government and is not
subject to domestic copyright protection under 17 USC § 105. This repository is in
the public domain within the United States, and copyright and related rights in
the work worldwide are waived through the [CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/).
All contributions to this repository will be released under the CC0 dedication. By
submitting a pull request you are agreeing to comply with this waiver of
copyright interest.

This source code in this repository is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the Apache Software License for more details.

This repository is not a source of government records, but is a copy to increase collaboration and collaborative potential. All government records will be published through the [CDC web site](http://www.cdc.gov).

Contributions to and use of this repository are governed by the [Code of Conduct](code-of-conduct.md), [License](LICENSE), and [Contributing](CONTRIBUTING.md) documents. See [DISLAIMER.md](DISLAIMER.md) for additional disclaimers and legal information.

Please refer to [CDC's Template Repository](https://github.com/CDCgov/template) for more information about [contributing to this repository](https://github.com/CDCgov/template/blob/main/CONTRIBUTING.md), [public domain notices and disclaimers](https://github.com/CDCgov/template/blob/main/DISCLAIMER.md), and [code of conduct](https://github.com/CDCgov/template/blob/main/code-of-conduct.md).
89 changes: 89 additions & 0 deletions terraform/implementation/aca/create_prereq_aca.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Azure Console Setup Instructions for Terraform Deployment

To prepare your Azure subscription for Terraform deployments, follow the steps below to create and configure the necessary resources.

---

## ✅ Prerequisites

Ensure that the following are in place:

- Access to the Azure portal: https://portal.azure.com
- Appropriate permissions to create and manage Azure resources
- Azure CLI (optional, but useful for automation): [Install Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli)

---

## 1. Create a Resource Group and Storage Account

These will be used to store Terraform state files.

### Step 1: Create a Resource Group

1. Navigate to **Resource groups**.
2. Click **+ Create**.
3. Provide:
- **Subscription**: Your target subscription
- **Resource Group Name**: e.g., `terraform-rg`
- **Region**: e.g., `East US`
4. Click **Review + Create**, then **Create**.

### Step 2: Create a Storage Account

1. Go to **Storage accounts**.
2. Click **+ Create**.
3. Provide:
- **Subscription**: Same as above
- **Resource Group**: Select the one created earlier
- **Storage account name**: e.g., `tfstate12345` (must be globally unique)
- **Region**: Same as the resource group
- **Performance**: Standard
- **Redundancy**: Locally-redundant storage (LRS)
4. Click **Review + Add Create**, then **Create**.

### Step 3: Create a Blob Container

1. Open the created storage account.
2. Navigate to **Containers** under **Data storage**.
3. Click **+ Container**.
4. Enter a name (e.g., `tfstate`) and set **Public access level** to **Private**.
5. Click **Create**.

---

## 2. Engineer Access

This allows Terraform to authenticate against Azure.

### Use an Existing Engineer Account

If running Terraform locally, ensure your Azure account has at least **Contributor** access to the target resource group.

---

## 3. Register Required Azure Resource Providers

Ensure that all necessary resource providers are registered, especially if deploying services like App Gateway or Container Apps.

### Steps:

1. Go to **Subscriptions** in the Azure portal.
2. Select your subscription.
3. Click **Resource providers** in the left menu.
4. Search for and register the following (examples):
- `Microsoft.App`
- `Microsoft.ContainerInstance`
- `Microsoft.Network`
- `Microsoft.OperationalInsights`
5. Click **Register** for each as needed.

---

## ✅ Summary

You should now have:
- A resource group and storage account for Terraform state
- An Engineer that has access with Contributor rights
- All required resource providers registered

You’re ready to deploy with Terraform!
20 changes: 20 additions & 0 deletions terraform/implementation/aca/example_deployment/_config.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
terraform {
backend "azurerm" {
resource_group_name = "<INSERT_STORAGE_RG_HERE>"
storage_account_name = "dibbsstatestorage"
container_name = "ce-tfstate"
key = "dev/terraform.tfstate"
}
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.116.0"
}
}
required_version = "~> 1.7.4"
}

provider "azurerm" {
features {}
skip_provider_registration = true
}
1 change: 1 addition & 0 deletions terraform/implementation/aca/example_deployment/_data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data "azurerm_client_config" "current" {}
62 changes: 62 additions & 0 deletions terraform/implementation/aca/example_deployment/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
locals {
team = "qc-client" //Update this to match your chosen prefix
project = "qc"
env = "dev"
location = "eastus" //Update this to match your chosen region
}

module "foundations" {
source = "../resources/foundations"
team = local.team
project = local.project
env = local.env
location = local.location
}

module "networking" {
source = "../resources/networking"
team = local.team
project = local.project
env = local.env
location = local.location
resource_group_name = module.foundations.resource_group_name

//These can be configured to match your network requirements.
//We recommend /24 at minumum for the network address space,
//and /25 for the ACA subnet. (Allows for 58 individual nodes)
network_address_space = ["10.30.0.0/24"]
aca_subnet_address_prefixes = ["10.30.0.0/25"]
app_gateway_subnet_address_prefixes = ["10.30.0.128/26"]
}

module "container_apps" {
source = "../resources/aca"
team = local.team
project = local.project
env = local.env
location = local.location
resource_group_name = module.foundations.resource_group_name

aca_subnet_id = module.networking.subnet_aca_id
appgw_subnet_id = module.networking.subnet_appgw_id
vnet_id = module.networking.network.id

acr_url = module.foundations.acr_url
acr_username = module.foundations.acr_admin_username //TODO: Change to an ACA-specific password
acr_password = module.foundations.acr_admin_password //TODO: Change to an ACA-specific password

qc_version = "0.9.1"

azure_storage_connection_string = module.foundations.azure_storage_connection_string
azure_container_name = module.foundations.azure_container_name


nextauth_url = "https://${local.team}-${local.project}-${local.env}.${local.location}.cloudapp.azure.com/ecr-viewer/api/auth"

key_vault_id = "<UPDATE_ME>" //Update this to match your target key vault. Follows the longform format: "/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/Microsoft.KeyVault/vaults/{key-vault-name}"


use_ssl = false //Set this to false if you do not want to use SSL for the ACA gateway.

pre_assigned_identity_id = "<UPDATE_ME>" //Set to the ID of a user-assigned managed identity for your gateway if you want to use one. Follows the longform format: "/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identity-name}"
}
8 changes: 8 additions & 0 deletions terraform/implementation/aca/example_deployment/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

# If you're running this code from an M-series processor or other ARM variant, you may need to specify the container platform manually.
export DOCKER_DEFAULT_PLATFORM=linux/amd64

# This section provides an example of targeted deployments, if required for your installation.
terraform apply -target=module.foundations -target=module.networking
terraform apply -target=module.container_apps
27 changes: 27 additions & 0 deletions terraform/implementation/aca/implementation_aca/_config.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* The Terraform Azure backend requires a pre-existing Azure Storage Account and a container to store the state file. If you do not already
* have a pre-configured resource for this, we recommend setting one up manually.
*
* WARNING: Make sure you don't use the same resource group for your state storage and your DIBBs resources to avoid accidental deletion.
* DIBBs resources should be deployed in their own resource group.
*/
terraform {
backend "azurerm" {
resource_group_name = "qc-aca-rg" // TODO: Change this to match the resource group that contains your storage account for Terraform state storage.
storage_account_name = "qcacastorageaccount" // TODO: Change this to match the storage account that contains/will contain your Terraform state files.
container_name = "tfstate" // We recommend leaving this alone, to keep DIBBs state files separate from the rest of your resources.
key = "dev/terraform.tfstate" // TODO: Change the prefix to match the environment you are working in.
}
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.116.0"
}
}
required_version = "~> 1.9.8"
}

provider "azurerm" {
features {}
skip_provider_registration = true
}
1 change: 1 addition & 0 deletions terraform/implementation/aca/implementation_aca/_data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data "azurerm_client_config" "current" {}
54 changes: 54 additions & 0 deletions terraform/implementation/aca/implementation_aca/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
locals {
team = "<insert>" // TODO: Change this to match your implementation team's name or internal asset code.
project = "dibbs"
env = "dev" // TODO: Change this to match your desired environment (e.g., dev, test, prod). Make sure to vary this between environments.
location = "eastus" // TODO: Change this to match your desired Azure region.
}

module "foundations" {
source = "../resources/foundations"
team = local.team
project = local.project
env = local.env
location = local.location
}

module "networking" {
source = "../resources/networking"
team = local.team
project = local.project
env = local.env
location = local.location
resource_group_name = module.foundations.resource_group_name

network_address_space = ["10.30.0.0/24"]
aca_subnet_address_prefixes = ["10.30.0.0/25"]
app_gateway_subnet_address_prefixes = ["10.30.0.128/26"]
}

module "container_apps" {
source = "../resources/aca"
team = local.team
project = local.project
env = local.env
location = local.location
resource_group_name = module.foundations.resource_group_name

aca_subnet_id = module.networking.subnet_aca_id
appgw_subnet_id = module.networking.subnet_appgw_id
vnet_id = module.networking.network.id

acr_url = module.foundations.acr_url
acr_username = module.foundations.acr_admin_username
acr_password = module.foundations.acr_admin_password

qc_version = "0.9.1"

azure_storage_connection_string = module.foundations.azure_storage_connection_string
azure_container_name = module.foundations.azure_container_name

nextauth_url = "https://${local.team}-${local.project}-${local.env}.${local.location}.cloudapp.azure.com/ecr-viewer/api/auth"

key_vault_id = "<UPDATE_ME>" //Update this to match your target key vault. Follows the longform format: "/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/Microsoft.KeyVault/vaults/{key-vault-name}"

}
51 changes: 51 additions & 0 deletions terraform/implementation/aca/resources/aca/_data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
data "azurerm_client_config" "current" {}

# data "azurerm_key_vault" "global_key_vault" {
# name = "skylightdibbsglobalkv"
# resource_group_name = "skylight-dibbs-global"
# }

data "azurerm_key_vault_secret" "query_connector_db_username" {
name = "query-connector-demo-db-user"
key_vault_id = resource.azurerm_key_vault.kv.id
}

data "azurerm_key_vault_secret" "query_connector_db_password" {
name = "query-connector-demo-db-password"
key_vault_id = resource.azurerm_key_vault.kv.id
}

# data "azurerm_key_vault" "demo_key_vault" {
# name = "skylightdibbsdemokv"
# resource_group_name = "skylight-dibbs-global"
# }

data "azurerm_key_vault_secret" "query_connector_umls_api_key" {
name = "query-connector-umls-api-key"
key_vault_id = resource.azurerm_key_vault.kv.id
}

data "azurerm_key_vault_secret" "query_connector_ersd_api_key" {
name = "query-connector-ersd-api-key"
key_vault_id = resource.azurerm_key_vault.kv.id
}

data "azurerm_key_vault_secret" "query_connector_auth_secret" {
name = "query-connector-auth-secret"
key_vault_id = resource.azurerm_key_vault.kv.id
}

data "azurerm_key_vault_secret" "query_connector_tenant" {
name = "query-connector-${local.env}-azuread-tenant-id"
key_vault_id = resource.azurerm_key_vault.kv.id
}

data "azurerm_key_vault_secret" "query_connector_auth_client_id" {
name = "query-connector-${local.env}-client-id"
key_vault_id = resource.azurerm_key_vault.kv.id
}

data "azurerm_key_vault_secret" "query_connector_auth_client_secret" {
name = "query-connector-${local.env}-client-secret"
key_vault_id = resource.azurerm_key_vault.kv.id
}
Empty file.
Loading
Loading