|
| 1 | +# Relative Paths for Bedrock Terraform Infrastructure |
| 2 | + |
| 3 | +| Revision | Date | Author | Remarks | |
| 4 | +| -------: | ------------ | -------------- | --------------------------- | |
| 5 | +| 0.1 | Mar-23, 2020 | Nathaniel Rose | Initial Draft | |
| 6 | +| 0.2 | Mar-26, 2020 | Nathaniel Rose | Changes Reflected from Team | |
| 7 | + |
| 8 | +## 1. Overview |
| 9 | + |
| 10 | +Terraform modules use a source parameter to locate the resource module target to |
| 11 | +download in order to initialize a terraform environment for deployment. A module |
| 12 | +can call other modules, which lets you include the child module's resources into |
| 13 | +the configuration in a concise way. Modules can also be called multiple times, |
| 14 | +either within the same configuration or in separate configurations, allowing |
| 15 | +resource configurations to be packaged and re-used. |
| 16 | + |
| 17 | +This document outlines multiple solution that seeks to validate alternative ways |
| 18 | +in which relative paths for child module may be supported in Bedrock |
| 19 | +implementation and the SPK cli tooling. |
| 20 | + |
| 21 | +``` |
| 22 | +module "servers" { |
| 23 | + source = "./app-cluster" |
| 24 | +
|
| 25 | + servers = 5 |
| 26 | +} |
| 27 | +``` |
| 28 | + |
| 29 | +This design shall only target supporting relative paths in spk scaffolding and |
| 30 | +generation. |
| 31 | + |
| 32 | +### Issues Addressed: |
| 33 | + |
| 34 | +1. As an SRE, I want to use module sources that are versioned and localalized to |
| 35 | + the terraform templates repo. |
| 36 | +2. As an Operator, I want automated CI pipelines that can handle internal |
| 37 | + references for incoming PR that modify my custom Bedrock modules. |
| 38 | + |
| 39 | +## 2. Solution |
| 40 | + |
| 41 | +In the current implementation on SPK infra practices, the tool is embedded into |
| 42 | +a generation pipeline that provisions terraform files respective to the modified |
| 43 | +infra HLD. `spk infra generate` provisions a terraform deployment template files |
| 44 | +based on the key values provided in the target directory's `definition.yaml`. If |
| 45 | +the `source` template in the `definition.yaml` uses relative paths in respects |
| 46 | +to the source, `infra generate` command will produce a terraform file with the |
| 47 | +module source out of scope from the provisioned terraform files. |
| 48 | + |
| 49 | +When executing a `terraform init` on the generated deployment files it produces |
| 50 | +an error similar to the following: |
| 51 | + |
| 52 | +``` |
| 53 | +Initializing modules... |
| 54 | +- aks-gitops in |
| 55 | +- provider in |
| 56 | +- vnet in |
| 57 | +
|
| 58 | +Error: Unreadable module directory |
| 59 | +
|
| 60 | +Unable to evaluate directory symlink: lstat ../../azure: no such file or |
| 61 | +directory |
| 62 | +``` |
| 63 | + |
| 64 | +### 2.1 Munge together URL with relative Path in SPK Generate - **ACCEPTED DESIGN** |
| 65 | + |
| 66 | +One option to address this issue is to directly modify the generated `.tf` files |
| 67 | +to reflect the respective module source. Inside the `infra generate` command we |
| 68 | +can use the `source`, `version`, and `template` values to modify the terraform |
| 69 | +child module source to a remote module source for terraform to download upon |
| 70 | +initialization. |
| 71 | + |
| 72 | +Example: |
| 73 | + |
| 74 | +**`Definition.yaml`** |
| 75 | + |
| 76 | +``` |
| 77 | +name: fabrikam |
| 78 | +source: "https://github.com/Microsoft/bedrock.git" |
| 79 | +template: cluster/environments/azure-single-keyvault |
| 80 | +version: nate.infra.relative.paths |
| 81 | +. |
| 82 | +. |
| 83 | +. |
| 84 | +``` |
| 85 | + |
| 86 | +Use a function to get the module path from root of remote repo in cached |
| 87 | +directory. (`pathFunction`) |
| 88 | + |
| 89 | +> source= ~~https://~~`source`?ref=`version`//`pathFunction()`" |
| 90 | +
|
| 91 | +**Output `Main.tf`** |
| 92 | + |
| 93 | +``` |
| 94 | +terraform { |
| 95 | + backend "azurerm" {} |
| 96 | +} |
| 97 | +
|
| 98 | +data "azurerm_client_config" "current" {} |
| 99 | +
|
| 100 | +data "azurerm_resource_group" "cluster_rg" { |
| 101 | + name = var.resource_group_name |
| 102 | +} |
| 103 | +
|
| 104 | +data "azurerm_resource_group" "keyvault" { |
| 105 | + name = var.keyvault_resource_group |
| 106 | +} |
| 107 | +
|
| 108 | +data "azurerm_subnet" "vnet" { |
| 109 | + name = var.subnet_name |
| 110 | + virtual_network_name = var.vnet_name |
| 111 | + resource_group_name = data.azurerm_resource_group.keyvault.name |
| 112 | +} |
| 113 | +
|
| 114 | +module "aks-gitops" { |
| 115 | + source = "github.com/microsoft/bedrock?ref=master//cluster/azure/aks-gitops" |
| 116 | +} |
| 117 | +
|
| 118 | +# Create Azure Key Vault role for SP |
| 119 | +module "keyvault_flexvolume_role" { |
| 120 | + source = "github.com/microsoft/bedrock?ref=master//cluster/azure/keyvault_flexvol_role" |
| 121 | +} |
| 122 | +
|
| 123 | +# Deploy central keyvault flexvolume |
| 124 | +module "flex_volume" { |
| 125 | + source = "github.com/microsoft/bedrock?ref=master//cluster/azure/keyvault_flexvol" |
| 126 | +} |
| 127 | +``` |
| 128 | + |
| 129 | +## 3. Dependencies |
| 130 | + |
| 131 | +An existing pull request for Bedrock currently exists that verifies relative |
| 132 | +path implementation with the use of Bedrock Provided Templates in |
| 133 | +[#1189](https://github.com/microsoft/bedrock/pull/1189). This design document |
| 134 | +seeks to propose interoperability of the relative paths with SPK tooling and |
| 135 | +adjustment of infrastructure pipeline. |
| 136 | + |
| 137 | +## 4. Risks & Mitigations |
| 138 | + |
| 139 | +Limitations to the solution include: |
| 140 | + |
| 141 | +- Manipulating user input data and output terraform files |
| 142 | +- Potential Regex parsing for URL validation to detect relative paths |
| 143 | + |
| 144 | +## 5. Documentation |
| 145 | + |
| 146 | +Yes. A brief update to the |
| 147 | +[`spk-infra-generation-pipeline.md`](/guides/infra/spk-infra-generation-pipeline.md) |
| 148 | +detailing relative path support for module sources. |
| 149 | + |
| 150 | +## 6. Alternatives |
| 151 | + |
| 152 | +### 6.1 Copy Modules to Alternative Configured Generated Directory |
| 153 | + |
| 154 | +Another option is to copy modules from cached remote directory to the generated |
| 155 | +folder. This allows SPK to directly reference the parent module source with the |
| 156 | +generated terraform templates. In addition, this would also require the |
| 157 | +templates to be placed accordingly in respects to relative paths to parent |
| 158 | +modules. In Bedrock, the template folders are 3 levels down |
| 159 | +(../../../cluster/azure/keyvault_flex_vol") |
| 160 | + |
| 161 | +``` |
| 162 | +fabrikam/ |
| 163 | + definition.yaml |
| 164 | + fabrikam-central/ |
| 165 | + definition.yaml |
| 166 | + fabrikam-east/ |
| 167 | + definition.yaml |
| 168 | + fabrikam-west/ |
| 169 | + definition.yaml |
| 170 | +fabrikam-generated/ |
| 171 | + cluster |
| 172 | + azure |
| 173 | + common |
| 174 | + minikube |
| 175 | + environments |
| 176 | + deployments |
| 177 | + fabrikam-central/ |
| 178 | + main.tf |
| 179 | + variables.tf |
| 180 | + keyvault.tf |
| 181 | + terraform.tfvars |
| 182 | + backend.tfvars |
| 183 | + fabrikam-east/ |
| 184 | + main.tf |
| 185 | + variables.tf |
| 186 | + keyvault.tf |
| 187 | + terraform.tfvars |
| 188 | + backend.tfvars |
| 189 | + fabrikam-west/ |
| 190 | + main.tf |
| 191 | + variables.tf |
| 192 | + keyvault.tf |
| 193 | + terraform.tfvars |
| 194 | + backend.tfvars |
| 195 | +``` |
| 196 | + |
| 197 | +Limitations: |
| 198 | + |
| 199 | +- Very coupled to current organization of Bedrock and will have breaking changes |
| 200 | + when introducing new folders at template /module levels |
| 201 | +- Copying modules twice local to agent, once for cache and again during generate |
| 202 | + |
| 203 | +### 6.2 Use a symlink to reference the modules |
| 204 | + |
| 205 | +A symbolic link, also termed a soft link, is a special kind of file that points |
| 206 | +to another file, much like a shortcut in Windows or a Macintosh alias. This will |
| 207 | +allow generate the alias the cached repo for all `spk infra generate` commands. |
| 208 | + |
| 209 | +`ln -s modules /path/to/modules` |
| 210 | + |
| 211 | +Inside of spk, the terraform files will now reference the symlink which is |
| 212 | +cached. |
| 213 | + |
| 214 | +**Output `Main.tf`** |
| 215 | + |
| 216 | +``` |
| 217 | +terraform { |
| 218 | + backend "azurerm" {} |
| 219 | +} |
| 220 | +
|
| 221 | +data "azurerm_client_config" "current" {} |
| 222 | +
|
| 223 | +data "azurerm_resource_group" "cluster_rg" { |
| 224 | + name = var.resource_group_name |
| 225 | +} |
| 226 | +
|
| 227 | +data "azurerm_resource_group" "keyvault" { |
| 228 | + name = var.keyvault_resource_group |
| 229 | +} |
| 230 | +
|
| 231 | +data "azurerm_subnet" "vnet" { |
| 232 | + name = var.subnet_name |
| 233 | + virtual_network_name = var.vnet_name |
| 234 | + resource_group_name = data.azurerm_resource_group.keyvault.name |
| 235 | +} |
| 236 | +
|
| 237 | +module "aks-gitops" { |
| 238 | + source = "modules/azure/aks-gitops" |
| 239 | +} |
| 240 | +
|
| 241 | +# Create Azure Key Vault role for SP |
| 242 | +module "keyvault_flexvolume_role" { |
| 243 | + source = "modules/azure/keyvault_flexvol_role" |
| 244 | +} |
| 245 | +
|
| 246 | +# Deploy central keyvault flexvolume |
| 247 | +module "flex_volume" { |
| 248 | + source = "modules/azure/keyvault_flexvol" |
| 249 | +} |
| 250 | +``` |
| 251 | + |
| 252 | +Limitations: |
| 253 | + |
| 254 | +- Modifying the terraform output files. |
| 255 | +- Added complexity with symlink alias which prevents ease of simply running |
| 256 | + terraform commands on native machine |
0 commit comments