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 6, 2024
1 parent 7c356a7 commit 18cae54
Show file tree
Hide file tree
Showing 76 changed files with 1,809 additions and 29 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"
}
}
}
9 changes: 9 additions & 0 deletions kit/azure/bootstrap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,24 @@ collie foundation deploy --bootstrap -- destroy
| [azuread_group.platform_engineers](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/group) | resource |
| [azurerm_federated_identity_credential.docs](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/federated_identity_credential) | resource |
| [azurerm_federated_identity_credential.validation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/federated_identity_credential) | resource |
| [azurerm_key_vault.key_vault](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault) | resource |
| [azurerm_resource_group.key_vault](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_role_assignment.cloudfoundation_deploy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.cloudfoundation_tfdeploy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.docs_tfstate](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.tfstates_engineers](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.validation_reader](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.validation_reader_keyvault](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.validation_tfstate](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_definition.cloudfoundation_deploy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_definition) | resource |
| [azurerm_role_definition.validation_reader](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_definition) | resource |
| [azurerm_user_assigned_identity.docs](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
| [azurerm_user_assigned_identity.validation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
| [azuread_client_config.current](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/client_config) | data source |
| [azuread_users.platform_engineers_members](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/users) | data source |
| [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) | data source |
| [azurerm_management_group.parent](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/management_group) | data source |
| [azurerm_role_definition.keyvault](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/role_definition) | data source |
| [azurerm_subscription.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source |

## Inputs
Expand All @@ -115,6 +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-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 All @@ -125,6 +132,8 @@ collie foundation deploy --bootstrap -- destroy

| Name | Description |
|------|-------------|
| <a name="output_azurerm_key_vault"></a> [azurerm\_key\_vault](#output\_azurerm\_key\_vault) | n/a |
| <a name="output_azurerm_key_vault_rg_name"></a> [azurerm\_key\_vault\_rg\_name](#output\_azurerm\_key\_vault\_rg\_name) | n/a |
| <a name="output_documentation_md"></a> [documentation\_md](#output\_documentation\_md) | n/a |
| <a name="output_documentation_uami_client_id"></a> [documentation\_uami\_client\_id](#output\_documentation\_uami\_client\_id) | n/a |
| <a name="output_module_storage_account_resource_id"></a> [module\_storage\_account\_resource\_id](#output\_module\_storage\_account\_resource\_id) | n/a |
Expand Down
8 changes: 8 additions & 0 deletions kit/azure/bootstrap/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,11 @@ output "documentation_uami_client_id" {
output "validation_uami_client_id" {
value = length(azurerm_user_assigned_identity.validation) > 0 ? azurerm_user_assigned_identity.validation[0].client_id : null
}

output "azurerm_key_vault" {
value = azurerm_key_vault.key_vault
}

output "azurerm_key_vault_rg_name" {
value = azurerm_resource_group.key_vault.name
}
27 changes: 27 additions & 0 deletions kit/azure/bootstrap/resources.key-vault.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
data "azurerm_client_config" "current" {}

resource "azurerm_resource_group" "key_vault" {
name = var.key_vault.resource_group_name
location = var.terraform_state_storage.location
}

resource "azurerm_key_vault" "key_vault" {
name = var.key_vault.name
location = var.terraform_state_storage.location
resource_group_name = azurerm_resource_group.key_vault.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
soft_delete_retention_days = 7
purge_protection_enabled = true
enable_rbac_authorization = true
}

data "azurerm_role_definition" "keyvault" {
name = "Key Vault Administrator"
}

resource "azurerm_role_assignment" "cloudfoundation_tfdeploy" {
principal_id = azuread_group.platform_engineers.id
scope = azurerm_key_vault.key_vault.id
role_definition_name = data.azurerm_role_definition.keyvault.name
}
Loading

0 comments on commit 18cae54

Please sign in to comment.