Skip to content

Commit

Permalink
feature: Latest changes from likvid-cloudfoundation prod branch
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] committed Jun 19, 2024
1 parent 271e627 commit e552f45
Show file tree
Hide file tree
Showing 27 changed files with 596 additions and 31 deletions.
64 changes: 64 additions & 0 deletions kit/azure/aviatrix/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
name: Azure Aviatrix
summary: |
Set
compliance:
- control: cfmm/cost-management/monthly-cloud-tenant-billing-report
statement: |
Enables
- control: cfmm/cost-management/billing-alerts
statement: |
Sets
---

# Azure Aviatrix

Aviatrix

<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
| <a name="requirement_azuread"></a> [azuread](#requirement\_azuread) | ~> 2.46.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | ~> 3.81.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azuread_app_role_assignment.aviatrix_deploy-approle](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/app_role_assignment) | resource |
| [azuread_app_role_assignment.aviatrix_deploy-directory](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/app_role_assignment) | resource |
| [azuread_application.aviatrix_deploy](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application) | resource |
| [azuread_application_password.aviatrix_deploy](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application_password) | resource |
| [azuread_service_principal.aviatrix_deploy](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/service_principal) | resource |
| [azurerm_role_assignment.aviatrix_deploy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_definition.aviatrix_deploy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_definition) | resource |
| [time_rotating.key_rotation](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/rotating) | resource |
| [azuread_application_published_app_ids.well_known](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/application_published_app_ids) | data source |
| [azuread_service_principal.msgraph](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/service_principal) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_allowed_user_group_id"></a> [allowed\_user\_group\_id](#input\_allowed\_user\_group\_id) | id of the authorized id which can do changes | `list(string)` | n/a | yes |
| <a name="input_location"></a> [location](#input\_location) | The Azure location used for creating policy assignments establishing this landing zone's guardrails. | `string` | n/a | yes |
| <a name="input_parent_management_group"></a> [parent\_management\_group](#input\_parent\_management\_group) | id of the tenant management group | `string` | n/a | yes |
| <a name="input_service_principal_name"></a> [service\_principal\_name](#input\_service\_principal\_name) | id of the tenant management group | `string` | `"avaitrix_deploy_spn"` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_aviatrix_service_principal"></a> [aviatrix\_service\_principal](#output\_aviatrix\_service\_principal) | n/a |
| <a name="output_client_id"></a> [client\_id](#output\_client\_id) | n/a |
| <a name="output_client_principal_id"></a> [client\_principal\_id](#output\_client\_principal\_id) | n/a |
| <a name="output_client_secret"></a> [client\_secret](#output\_client\_secret) | n/a |
| <a name="output_documentation_md"></a> [documentation\_md](#output\_documentation\_md) | n/a |
<!-- END_TF_DOCS -->
127 changes: 127 additions & 0 deletions kit/azure/aviatrix/aviatrix.spn.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
resource "azurerm_role_definition" "aviatrix_deploy" {
name = var.service_principal_name
scope = var.parent_management_group
description = "Permissions required to deploy the avaitrix"

permissions {
actions = [
#https://docs.aviatrix.com/documentation/latest/accounts-and-users/custom-role-azure.html?expand=true
"Microsoft.MarketplaceOrdering/offerTypes/publishers/offers/plans/agreements/*",
"Microsoft.Compute/*/read",
"Microsoft.Compute/availabilitySets/*",
"Microsoft.Compute/virtualMachines/*",
"Microsoft.Network/*/read",
"Microsoft.Network/publicIPAddresses/*",
"Microsoft.Network/networkInterfaces/*",
"Microsoft.Network/networkSecurityGroups/*",
"Microsoft.Network/loadBalancers/*",
"Microsoft.Network/routeTables/*",
"Microsoft.Network/virtualNetworks/*",
"Microsoft.Storage/storageAccounts/*",
"Microsoft.Resources/*/read",
"Microsoft.Resourcehealth/healthevent/*",
"Microsoft.Resources/deployments/*",
"Microsoft.Resources/tags/*",
"Microsoft.Resources/marketplace/purchase/action",
"Microsoft.Resources/subscriptions/resourceGroups/*"
]
}

assignable_scopes = [
var.parent_management_group
]
}

data "azuread_application_published_app_ids" "well_known" {}

data "azuread_service_principal" "msgraph" {
client_id = data.azuread_application_published_app_ids.well_known.result.MicrosoftGraph
}

resource "azuread_application" "aviatrix_deploy" {
display_name = var.service_principal_name

web {
implicit_grant {
access_token_issuance_enabled = false
}
}
required_resource_access {
resource_app_id = data.azuread_application_published_app_ids.well_known.result.MicrosoftGraph

resource_access {
id = data.azuread_service_principal.msgraph.app_role_ids["Directory.Read.All"]
type = "Role"
}
resource_access {
id = data.azuread_service_principal.msgraph.app_role_ids["Group.ReadWrite.All"]
type = "Role"
}
resource_access {
id = data.azuread_service_principal.msgraph.app_role_ids["AppRoleAssignment.ReadWrite.All"]
type = "Role"
}

resource_access {
id = data.azuread_service_principal.msgraph.app_role_ids["Application.ReadWrite.All"]
type = "Role"
}
}

# NOTE: currently it is not possible to automate the "Grant admin consent button"
# https://github.com/terraform-providers/terraform-provider-azuread/issues/33
# As a result we have to ignore this value in terraform for now
# In addition please keep in mind you have to grant admin consent manually
lifecycle {
ignore_changes = [
app_role
]
}
}

resource "azuread_service_principal" "aviatrix_deploy" {
client_id = azuread_application.aviatrix_deploy.client_id
# The following tags are needed to create an Enterprise Application
# See https://github.com/hashicorp/terraform-provider-azuread/issues/7#issuecomment-529597534
tags = [
"WindowsAzureActiveDirectoryIntegratedApp",
]
}

resource "azurerm_role_assignment" "aviatrix_deploy" {
scope = var.parent_management_group
role_definition_id = azurerm_role_definition.aviatrix_deploy.role_definition_resource_id
principal_id = azuread_service_principal.aviatrix_deploy.id
}

resource "azuread_app_role_assignment" "aviatrix_deploy-directory" {
app_role_id = data.azuread_service_principal.msgraph.app_role_ids["Directory.Read.All"]
principal_object_id = azuread_service_principal.aviatrix_deploy.object_id
resource_object_id = data.azuread_service_principal.msgraph.object_id
}
# This azuread_app_role_assignment is necessary if you want to manage groups through Terraform.
# Productive use in a cloud foundation should probably manage groups not via Terraform but
# via existing IAM processes, but this is a good lean start.
# resource "azuread_app_role_assignment" "aviatrix_deploy-group" {
# app_role_id = data.azuread_service_principal.msgraph.app_role_ids["Group.ReadWrite.All"]
# principal_object_id = azuread_service_principal.aviatrix_deploy.object_id
# resource_object_id = data.azuread_service_principal.msgraph.object_id
# }

resource "azuread_app_role_assignment" "aviatrix_deploy-approle" {
app_role_id = data.azuread_service_principal.msgraph.app_role_ids["AppRoleAssignment.ReadWrite.All"]
principal_object_id = azuread_service_principal.aviatrix_deploy.object_id
resource_object_id = data.azuread_service_principal.msgraph.object_id
}

# note this requires the terraform to be run regularly
resource "time_rotating" "key_rotation" {
rotation_days = 365
}

resource "azuread_application_password" "aviatrix_deploy" {
application_id = azuread_application.aviatrix_deploy.id
rotate_when_changed = {
rotation = time_rotating.key_rotation.id
}
}
6 changes: 6 additions & 0 deletions kit/azure/aviatrix/documentation.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
output "documentation_md" {
value = <<EOF
# Aviatrix
EOF
}
16 changes: 16 additions & 0 deletions kit/azure/aviatrix/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
output "client_id" {
value = azuread_service_principal.aviatrix_deploy.client_id
}

output "client_secret" {
value = azuread_application_password.aviatrix_deploy.value
sensitive = true
}

output "client_principal_id" {
value = azuread_service_principal.aviatrix_deploy.id
}

output "aviatrix_service_principal" {
value = azuread_application.aviatrix_deploy.display_name
}
40 changes: 40 additions & 0 deletions kit/azure/aviatrix/template/platform-module/terragrunt.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
include "platform" {
path = find_in_parent_folders("platform.hcl")
expose = true
}

terraform {
source = "${get_repo_root()}//kit/azure/aviatrix"
}

dependency "bootstrap" {
config_path = "../bootstrap"
}

dependency "organization-hierarchy" {
config_path = "../organization-hierarchy"
}

generate "provider" {
path = "provider.tf"
if_exists = "overwrite"
contents = <<EOF
provider "azurerm" {
features {}
skip_provider_registration = true
tenant_id = "${include.platform.locals.platform.azure.aadTenantId}"
subscription_id = "${include.platform.locals.platform.azure.subscriptionId}"
}
provider "azuread" {
tenant_id = "${include.platform.locals.platform.azure.aadTenantId}"
}
EOF
}

inputs = {
# todo: set input variables
parent_management_group = "${dependency.organization-hierarchy.outputs.landingzones_id}"
allowed_user_group_id = ["${dependency.bootstrap.outputs.platform_engineers_azuread_group_id}"]
location = "${try(include.platform.locals.tfstateconfig.location, "could not read location from stateconfig. configure it explicitly")}"
}
23 changes: 23 additions & 0 deletions kit/azure/aviatrix/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
variable "parent_management_group" {
type = string
nullable = false
description = "id of the tenant management group"
}

variable "service_principal_name" {
type = string
nullable = false
default = "avaitrix_deploy_spn"
description = "id of the tenant management group"
}

variable "allowed_user_group_id" {
type = list(string)
nullable = false
description = "id of the authorized id which can do changes"
}

variable "location" {
type = string
description = "The Azure location used for creating policy assignments establishing this landing zone's guardrails."
}
15 changes: 15 additions & 0 deletions kit/azure/aviatrix/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
terraform {
required_version = ">= 1.0"

required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.81.0"
}

azuread = {
source = "hashicorp/azuread"
version = "~> 2.46.0"
}
}
}
2 changes: 1 addition & 1 deletion kit/azure/bootstrap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ collie foundation deploy --bootstrap -- destroy
|------|-------------|------|---------|:--------:|
| <a name="input_aad_tenant_id"></a> [aad\_tenant\_id](#input\_aad\_tenant\_id) | Id of the AAD Tenant. This is also the simultaneously the id of the root management group. | `string` | n/a | yes |
| <a name="input_documentation_uami"></a> [documentation\_uami](#input\_documentation\_uami) | read-only UAMI with access to terraform states to generate documentation in CI pipelines | <pre>object({<br> name = string<br> # note: it seems wildcards are not supported yet, see https://github.com/Azure/azure-workload-identity/issues/373<br> oidc_subject = string<br> })</pre> | `null` | no |
| <a name="input_key_vault"></a> [key\_vault](#input\_key\_vault) | This object contains configuration details for setting up a key vault. | <pre>object({<br> name = string,<br> resource_group_name = string<br> })</pre> | <pre>{<br> "name": "cloudfoundation-kv",<br> "resource_group_name": "cloudfoundation-keyvault"<br>}</pre> | no |
| <a name="input_key_vault"></a> [key\_vault](#input\_key\_vault) | This object contains configuration details for setting up a key vault. | <pre>object({<br> name = string,<br> resource_group_name = string<br> })</pre> | <pre>{<br> "name": "cloudfoundation-kv",<br> "resource_group_name": "cloudfoundation-rg"<br>}</pre> | no |
| <a name="input_parent_management_group_name"></a> [parent\_management\_group\_name](#input\_parent\_management\_group\_name) | Name of the management group you want to use as parent for your foundation. | `string` | n/a | yes |
| <a name="input_platform_engineers_group"></a> [platform\_engineers\_group](#input\_platform\_engineers\_group) | the name of the cloud foundation platform engineers group | `string` | `"cloudfoundation-platform-engineers"` | no |
| <a name="input_platform_engineers_members"></a> [platform\_engineers\_members](#input\_platform\_engineers\_members) | Set up a group of platform engineers. If enabled, this group will receive access to terraform\_state\_storage | <pre>list(object({<br> email = string,<br> upn = string,<br> }))</pre> | n/a | yes |
Expand Down
7 changes: 3 additions & 4 deletions kit/azure/bootstrap/template/platform-module/terragrunt.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ EOF
}

inputs = {
aad_tenant_id = include.platform.locals.platform.azure.aadTenantId
parent_management_group_name = "cloudfoundation-management-group" #TODO the cloudfoundation is created in a separate management group so as not to jeopardize the existing infrastructure
aad_tenant_id = include.platform.locals.platform.azure.aadTenantId

terraform_state_storage = {
name = "${include.platform.locals.cloudfoundation.name}"
Expand All @@ -53,8 +52,8 @@ inputs = {
}
]
key_vault = {
name = "cloudfoundation-kv"
resource_group_name = "cloudfoundation-keyvault"
name = "likvid-cloudfoundation-kv"
resource_group_name = "likvid-cloudfoundation-keyvault"
}


Expand Down
2 changes: 1 addition & 1 deletion kit/azure/bootstrap/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ variable "key_vault" {
description = "This object contains configuration details for setting up a key vault."
default = {
name = "cloudfoundation-kv"
resource_group_name = "cloudfoundation-keyvault"
resource_group_name = "cloudfoundation-rg"
}
}

Expand Down
2 changes: 1 addition & 1 deletion kit/azure/buildingblocks/automation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,4 @@ No modules.
| <a name="output_storage_account_name"></a> [storage\_account\_name](#output\_storage\_account\_name) | n/a |
| <a name="output_subscription_id"></a> [subscription\_id](#output\_subscription\_id) | n/a |
| <a name="output_tenant_id"></a> [tenant\_id](#output\_tenant\_id) | n/a |
<!-- END_TF_DOCS -->
<!-- END_TF_DOCS -->
1 change: 1 addition & 0 deletions kit/azure/buildingblocks/automation/documentation.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ This module automates the deployment of building blocks within Azure. It utilize
EOF
}

Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ dependency "organization-hierarchy" {
config_path = "../../organization-hierarchy"
}

dependency "bootstrap" {
config_path = "../../bootstrap"
}

generate "provider" {
path = "provider.tf"
if_exists = "overwrite"
Expand All @@ -33,9 +29,5 @@ terraform {
inputs = {
location = "germanywestcentral"
service_principal_name = "cloud_foundation_tf_buildingblock_user"
key_vault = {
name = dependency.bootstrap.outputs.azurerm_key_vault.name
resource_group_name = dependency.bootstrap.outputs.azurerm_key_vault_rg_name
}
scope = dependency.organization-hierarchy.outputs.landingzones_id
scope = dependency.organization-hierarchy.outputs.landingzones_id
}
Loading

0 comments on commit e552f45

Please sign in to comment.