-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from fluxcd/azure-gh-actions
Add azure github actions tf module
- Loading branch information
Showing
4 changed files
with
290 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,97 @@ | ||
# Azure GitHub Actions Secrets and Variables | ||
|
||
Configuration in this directory registers an Azure app to be used in CI, | ||
generates a client secret for the app, creates a custom role with the requested | ||
permissions and assigns the role to the Azure app service account. The app | ||
client details are then written to GitHub actions secrets and variables of a | ||
given repository. | ||
|
||
By default, the following GitHub actions secrets are created: | ||
- `ARM_CLIENT_ID` | ||
- `ARM_CLIENT_SECRET` | ||
- `ARM_SUBSCRIPTION_ID` | ||
- `ARM_TENANT_ID` | ||
|
||
and `TF_VAR_azure_location` actions variable is created. All of these names | ||
are overridable, see `variables.tf`. | ||
|
||
It also supports adding custom secrets and variables in addition to the above. | ||
|
||
**NOTE:** Overwriting existing GitHub secrets and variables are not supported. | ||
|
||
## Usage | ||
|
||
```hcl | ||
module "azure_gh_actions" { | ||
source = "git::https://github.com/fluxcd/test-infra.git//tf-modules/azure/github-actions" | ||
azure_owners = ["owner-id-1", "owner-id-2"] | ||
azure_app_name = "test-app-1" | ||
azure_app_description = "A test app." | ||
azure_permissions = [ | ||
"Microsoft.Kubernetes/*", | ||
"Microsoft.ContainerRegistry/*" | ||
] | ||
azure_location = "eastus" | ||
github_project = "repo-name" | ||
github_variable_custom = { | ||
"SOME_VAR1" = "some-val1", | ||
"SOME_var2" = "some-val2" | ||
} | ||
github_secret_custom = { | ||
"SECRET1" = "some-secret1", | ||
"SECRET2" = "some-secret2" | ||
} | ||
} | ||
``` | ||
|
||
## Azure Requirements | ||
|
||
AzureAD permissions: | ||
- To use a Service Account, grant the following Microsoft Graph API permissions: | ||
- `Application.ReadWrite.OwnedBy` | ||
- `Directory.Read.All` | ||
- To use a User account, ensure that the user has one of the following | ||
directory roles: | ||
- `Application Administrator` | ||
- `Global Administrator` | ||
|
||
Refer [azuread_application docs](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application) | ||
and [azuread_service_principal docs](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/service_principal) | ||
for more details. | ||
|
||
AzureRM permissions: | ||
- The following IAM permissions are required when using a Service Account: | ||
- `Microsoft.Resources/subscriptions/read` | ||
- `Microsoft.Authorization/roleDefinitions/write` | ||
- `Microsoft.Authorization/roleDefinitions/delete` | ||
- `Microsoft.Authorization/roleAssignments/read` | ||
- `Microsoft.Authorization/roleAssignments/write` | ||
- `Microsoft.Authorization/roleAssignments/delete` | ||
|
||
## GitHub Requirements | ||
|
||
Create a GitHub fine-grained token for the target repository with the following | ||
repository permissions: | ||
- `Read access to metadata` | ||
- `Read and Write access to actions variables and secrets` | ||
|
||
## Provider Configuration | ||
|
||
Configure the AzureRM, AzureAD and Github providers with the following | ||
environment variables: | ||
```sh | ||
export ARM_CLIENT_ID="" | ||
export ARM_CLIENT_SECRET="" | ||
export ARM_SUBSCRIPTION_ID="" | ||
export ARM_TENANT_ID="" | ||
|
||
export GITHUB_TOKEN="" | ||
``` | ||
|
||
**NOTE:** When using Azure user account, logging in using the Azure CLI should | ||
be enough to configure the Azure providers. | ||
|
||
Check the respective provider docs for more details. |
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,94 @@ | ||
provider "azurerm" { | ||
skip_provider_registration = true | ||
features {} | ||
} | ||
|
||
data "azurerm_subscription" "primary" {} | ||
data "azuread_client_config" "current" {} | ||
|
||
# Register application, create service principal for it and generate client | ||
# secret. | ||
resource "azuread_application" "app" { | ||
display_name = var.azure_app_name | ||
owners = concat(var.azure_owners, [data.azuread_client_config.current.object_id]) | ||
} | ||
|
||
resource "azuread_service_principal" "app_sp" { | ||
application_id = azuread_application.app.application_id | ||
use_existing = true | ||
} | ||
|
||
resource "azuread_application_password" "app_secret" { | ||
application_object_id = resource.azuread_application.app.id | ||
display_name = var.azure_app_secret_name | ||
} | ||
|
||
# Define custom role. | ||
resource "azurerm_role_definition" "role" { | ||
name = var.azure_app_name | ||
scope = data.azurerm_subscription.primary.id | ||
description = var.azure_app_description | ||
|
||
permissions { | ||
actions = var.azure_permissions | ||
} | ||
|
||
assignable_scopes = [ | ||
data.azurerm_subscription.primary.id, | ||
] | ||
} | ||
|
||
# Assign role to the registered app's service principal. | ||
resource "azurerm_role_assignment" "assignment" { | ||
scope = data.azurerm_subscription.primary.id | ||
role_definition_id = azurerm_role_definition.role.role_definition_resource_id | ||
principal_id = azuread_service_principal.app_sp.object_id | ||
} | ||
|
||
# Add client details in github repo. | ||
resource "github_actions_secret" "client_id" { | ||
repository = var.github_project | ||
secret_name = var.github_secret_client_id_name | ||
plaintext_value = azuread_application.app.application_id | ||
} | ||
|
||
resource "github_actions_secret" "client_secret" { | ||
repository = var.github_project | ||
secret_name = var.github_secret_client_secret_name | ||
plaintext_value = azuread_application_password.app_secret.value | ||
} | ||
|
||
resource "github_actions_secret" "subscription_id" { | ||
repository = var.github_project | ||
secret_name = var.github_secret_subscription_id_name | ||
plaintext_value = data.azurerm_subscription.primary.subscription_id | ||
} | ||
|
||
resource "github_actions_secret" "tenant_id" { | ||
repository = var.github_project | ||
secret_name = var.github_secret_tenant_id_name | ||
plaintext_value = azuread_service_principal.app_sp.application_tenant_id | ||
} | ||
|
||
resource "github_actions_variable" "location" { | ||
repository = var.github_project | ||
variable_name = var.github_variable_location_name | ||
value = var.azure_location | ||
} | ||
|
||
resource "github_actions_variable" "custom" { | ||
for_each = var.github_variable_custom | ||
|
||
repository = var.github_project | ||
variable_name = each.key | ||
value = each.value | ||
} | ||
|
||
resource "github_actions_secret" "custom" { | ||
# Mark only the key as nonsensitive. | ||
for_each = nonsensitive(toset(keys(var.github_secret_custom))) | ||
|
||
repository = var.github_project | ||
secret_name = each.key | ||
plaintext_value = var.github_secret_custom[each.key] | ||
} |
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,81 @@ | ||
variable "azure_owners" { | ||
description = "Object IDs of the Azure resource owners" | ||
type = list(string) | ||
default = [] | ||
} | ||
|
||
variable "github_project" { | ||
description = "Name of the GitHub project to add secrets to" | ||
type = string | ||
} | ||
|
||
variable "azure_app_name" { | ||
description = "Name of the Azure app to register" | ||
type = string | ||
} | ||
|
||
variable "azure_app_description" { | ||
description = "Description of the Azure app, will be used to provide context to the role assigned to the app" | ||
type = string | ||
} | ||
|
||
variable "azure_app_secret_name" { | ||
description = "Name of the Azure app secret" | ||
type = string | ||
default = "tf-generated-secret" | ||
} | ||
|
||
variable "azure_permissions" { | ||
description = "List of permissions to grant to the created app" | ||
type = list(string) | ||
default = [] | ||
} | ||
|
||
variable "github_secret_client_id_name" { | ||
description = "GitHub secret name for Azure app client ID" | ||
type = string | ||
default = "ARM_CLIENT_ID" | ||
} | ||
|
||
variable "github_secret_client_secret_name" { | ||
description = "GitHub secret name for Azure app client secret" | ||
type = string | ||
default = "ARM_CLIENT_SECRET" | ||
} | ||
|
||
variable "github_secret_subscription_id_name" { | ||
description = "GitHub secret name for Azure subscription ID" | ||
type = string | ||
default = "ARM_SUBSCRIPTION_ID" | ||
} | ||
|
||
variable "github_secret_tenant_id_name" { | ||
description = "GitHub secret name for Azure tenant ID" | ||
type = string | ||
default = "ARM_TENANT_ID" | ||
} | ||
|
||
variable "github_variable_location_name" { | ||
description = "GitHub variable name for Azure location" | ||
type = string | ||
default = "TF_VAR_azure_location" | ||
} | ||
|
||
variable "azure_location" { | ||
description = "Azure location used by the tests" | ||
type = string | ||
default = "eastus" | ||
} | ||
|
||
variable "github_variable_custom" { | ||
description = "A map of custom GitHub variables to be created" | ||
type = map(string) | ||
default = {} | ||
} | ||
|
||
variable "github_secret_custom" { | ||
description = "A map of custom GitHub secrets to be created" | ||
type = map(string) | ||
default = {} | ||
sensitive = true | ||
} |
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,18 @@ | ||
terraform { | ||
required_providers { | ||
azurerm = { | ||
source = "hashicorp/azurerm" | ||
version = ">= 3.62.1" | ||
} | ||
|
||
azuread = { | ||
source = "hashicorp/azuread" | ||
version = ">= 2.39.0" | ||
} | ||
|
||
github = { | ||
source = "integrations/github" | ||
version = ">= 5.28.1" | ||
} | ||
} | ||
} |