This repository has been archived by the owner on Apr 13, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for relative paths Design Doc in SPK (#459)
* rebasing off master * updated docs format - standardized Co-authored-by: Dennis Seah <dennis.seah@gmail.com>
- Loading branch information
1 parent
bcdc1d3
commit af9ea2d
Showing
1 changed file
with
256 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,256 @@ | ||
# Relative Paths for Bedrock Terraform Infrastructure | ||
|
||
| Revision | Date | Author | Remarks | | ||
| -------: | ------------ | -------------- | --------------------------- | | ||
| 0.1 | Mar-23, 2020 | Nathaniel Rose | Initial Draft | | ||
| 0.2 | Mar-26, 2020 | Nathaniel Rose | Changes Reflected from Team | | ||
|
||
## 1. Overview | ||
|
||
Terraform modules use a source parameter to locate the resource module target to | ||
download in order to initialize a terraform environment for deployment. A module | ||
can call other modules, which lets you include the child module's resources into | ||
the configuration in a concise way. Modules can also be called multiple times, | ||
either within the same configuration or in separate configurations, allowing | ||
resource configurations to be packaged and re-used. | ||
|
||
This document outlines multiple solution that seeks to validate alternative ways | ||
in which relative paths for child module may be supported in Bedrock | ||
implementation and the SPK cli tooling. | ||
|
||
``` | ||
module "servers" { | ||
source = "./app-cluster" | ||
servers = 5 | ||
} | ||
``` | ||
|
||
This design shall only target supporting relative paths in spk scaffolding and | ||
generation. | ||
|
||
### Issues Addressed: | ||
|
||
1. As an SRE, I want to use module sources that are versioned and localalized to | ||
the terraform templates repo. | ||
2. As an Operator, I want automated CI pipelines that can handle internal | ||
references for incoming PR that modify my custom Bedrock modules. | ||
|
||
## 2. Solution | ||
|
||
In the current implementation on SPK infra practices, the tool is embedded into | ||
a generation pipeline that provisions terraform files respective to the modified | ||
infra HLD. `spk infra generate` provisions a terraform deployment template files | ||
based on the key values provided in the target directory's `definition.yaml`. If | ||
the `source` template in the `definition.yaml` uses relative paths in respects | ||
to the source, `infra generate` command will produce a terraform file with the | ||
module source out of scope from the provisioned terraform files. | ||
|
||
When executing a `terraform init` on the generated deployment files it produces | ||
an error similar to the following: | ||
|
||
``` | ||
Initializing modules... | ||
- aks-gitops in | ||
- provider in | ||
- vnet in | ||
Error: Unreadable module directory | ||
Unable to evaluate directory symlink: lstat ../../azure: no such file or | ||
directory | ||
``` | ||
|
||
### 2.1 Munge together URL with relative Path in SPK Generate - **ACCEPTED DESIGN** | ||
|
||
One option to address this issue is to directly modify the generated `.tf` files | ||
to reflect the respective module source. Inside the `infra generate` command we | ||
can use the `source`, `version`, and `template` values to modify the terraform | ||
child module source to a remote module source for terraform to download upon | ||
initialization. | ||
|
||
Example: | ||
|
||
**`Definition.yaml`** | ||
|
||
``` | ||
name: fabrikam | ||
source: "https://github.com/Microsoft/bedrock.git" | ||
template: cluster/environments/azure-single-keyvault | ||
version: nate.infra.relative.paths | ||
. | ||
. | ||
. | ||
``` | ||
|
||
Use a function to get the module path from root of remote repo in cached | ||
directory. (`pathFunction`) | ||
|
||
> source= ~~https://~~`source`?ref=`version`//`pathFunction()`" | ||
**Output `Main.tf`** | ||
|
||
``` | ||
terraform { | ||
backend "azurerm" {} | ||
} | ||
data "azurerm_client_config" "current" {} | ||
data "azurerm_resource_group" "cluster_rg" { | ||
name = var.resource_group_name | ||
} | ||
data "azurerm_resource_group" "keyvault" { | ||
name = var.keyvault_resource_group | ||
} | ||
data "azurerm_subnet" "vnet" { | ||
name = var.subnet_name | ||
virtual_network_name = var.vnet_name | ||
resource_group_name = data.azurerm_resource_group.keyvault.name | ||
} | ||
module "aks-gitops" { | ||
source = "github.com/microsoft/bedrock?ref=master//cluster/azure/aks-gitops" | ||
} | ||
# Create Azure Key Vault role for SP | ||
module "keyvault_flexvolume_role" { | ||
source = "github.com/microsoft/bedrock?ref=master//cluster/azure/keyvault_flexvol_role" | ||
} | ||
# Deploy central keyvault flexvolume | ||
module "flex_volume" { | ||
source = "github.com/microsoft/bedrock?ref=master//cluster/azure/keyvault_flexvol" | ||
} | ||
``` | ||
|
||
## 3. Dependencies | ||
|
||
An existing pull request for Bedrock currently exists that verifies relative | ||
path implementation with the use of Bedrock Provided Templates in | ||
[#1189](https://github.com/microsoft/bedrock/pull/1189). This design document | ||
seeks to propose interoperability of the relative paths with SPK tooling and | ||
adjustment of infrastructure pipeline. | ||
|
||
## 4. Risks & Mitigations | ||
|
||
Limitations to the solution include: | ||
|
||
- Manipulating user input data and output terraform files | ||
- Potential Regex parsing for URL validation to detect relative paths | ||
|
||
## 5. Documentation | ||
|
||
Yes. A brief update to the | ||
[`spk-infra-generation-pipeline.md`](/guides/infra/spk-infra-generation-pipeline.md) | ||
detailing relative path support for module sources. | ||
|
||
## 6. Alternatives | ||
|
||
### 6.1 Copy Modules to Alternative Configured Generated Directory | ||
|
||
Another option is to copy modules from cached remote directory to the generated | ||
folder. This allows SPK to directly reference the parent module source with the | ||
generated terraform templates. In addition, this would also require the | ||
templates to be placed accordingly in respects to relative paths to parent | ||
modules. In Bedrock, the template folders are 3 levels down | ||
(../../../cluster/azure/keyvault_flex_vol") | ||
|
||
``` | ||
fabrikam/ | ||
definition.yaml | ||
fabrikam-central/ | ||
definition.yaml | ||
fabrikam-east/ | ||
definition.yaml | ||
fabrikam-west/ | ||
definition.yaml | ||
fabrikam-generated/ | ||
cluster | ||
azure | ||
common | ||
minikube | ||
environments | ||
deployments | ||
fabrikam-central/ | ||
main.tf | ||
variables.tf | ||
keyvault.tf | ||
terraform.tfvars | ||
backend.tfvars | ||
fabrikam-east/ | ||
main.tf | ||
variables.tf | ||
keyvault.tf | ||
terraform.tfvars | ||
backend.tfvars | ||
fabrikam-west/ | ||
main.tf | ||
variables.tf | ||
keyvault.tf | ||
terraform.tfvars | ||
backend.tfvars | ||
``` | ||
|
||
Limitations: | ||
|
||
- Very coupled to current organization of Bedrock and will have breaking changes | ||
when introducing new folders at template /module levels | ||
- Copying modules twice local to agent, once for cache and again during generate | ||
|
||
### 6.2 Use a symlink to reference the modules | ||
|
||
A symbolic link, also termed a soft link, is a special kind of file that points | ||
to another file, much like a shortcut in Windows or a Macintosh alias. This will | ||
allow generate the alias the cached repo for all `spk infra generate` commands. | ||
|
||
`ln -s modules /path/to/modules` | ||
|
||
Inside of spk, the terraform files will now reference the symlink which is | ||
cached. | ||
|
||
**Output `Main.tf`** | ||
|
||
``` | ||
terraform { | ||
backend "azurerm" {} | ||
} | ||
data "azurerm_client_config" "current" {} | ||
data "azurerm_resource_group" "cluster_rg" { | ||
name = var.resource_group_name | ||
} | ||
data "azurerm_resource_group" "keyvault" { | ||
name = var.keyvault_resource_group | ||
} | ||
data "azurerm_subnet" "vnet" { | ||
name = var.subnet_name | ||
virtual_network_name = var.vnet_name | ||
resource_group_name = data.azurerm_resource_group.keyvault.name | ||
} | ||
module "aks-gitops" { | ||
source = "modules/azure/aks-gitops" | ||
} | ||
# Create Azure Key Vault role for SP | ||
module "keyvault_flexvolume_role" { | ||
source = "modules/azure/keyvault_flexvol_role" | ||
} | ||
# Deploy central keyvault flexvolume | ||
module "flex_volume" { | ||
source = "modules/azure/keyvault_flexvol" | ||
} | ||
``` | ||
|
||
Limitations: | ||
|
||
- Modifying the terraform output files. | ||
- Added complexity with symlink alias which prevents ease of simply running | ||
terraform commands on native machine |