Skip to content

Commit

Permalink
Update examples and add tests for multiple identities (#2)
Browse files Browse the repository at this point in the history
* added new example `multiple-identities`

* adjust example as per test case

* addtest test for multiple identities

* chore: cosmetics on simple example

* not sure what's wrong

* added tf config in test dir

* added test tfvar as exclusion gitignore
  • Loading branch information
ishuar authored Dec 22, 2023
1 parent b007730 commit 49a5adf
Show file tree
Hide file tree
Showing 22 changed files with 462 additions and 11 deletions.
2 changes: 1 addition & 1 deletion release-version.yaml → .github/release-version.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Update this file for a new release version.

module_version: "0.1.0"
module_version: "0.2.0"

## Example for manual release notes.
# release_notes: |
Expand Down
107 changes: 107 additions & 0 deletions .github/workflows/module-testing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
name: Module Testing

on:
workflow_dispatch:
pull_request:
paths:
- './*.tf' ## trigger if any terraform file has ben modified in repo root.
- 'scripts/*.sh' ## trigger if any involved script has been modified.
- 'tests/*.tftest.hcl' ## trigger if any test has been modified.
- 'examples/complete/*.tf' ## trigger if complete example has been modified.
- '.github/workflows/module-testing.yaml' ## trigger if this workflow has been modified.

permissions:
pull-requests: write

concurrency:
group: testing

jobs:
moduleTesting:
runs-on: ubuntu-latest
env:
ARM_SUBSCRIPTION_ID: "${{ secrets.ARM_SUBSCRIPTION_ID }}"
ARM_CLIENT_ID: "${{ secrets.AZURE_CLIENT_ID }}"
ARM_CLIENT_SECRET: "${{ secrets.AZURE_CLIENT_SECRET }}"
ARM_TENANT_ID: "${{ secrets.AZURE_TENANT_ID}}"

steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.6
terraform_wrapper: true

## Static Analysis and Linting Test (Unit Testing)
- name: Terraform validate on all examples
run: |
CURRENT_DIR="$(pwd)"
for dir in ./examples/*; do
if [[ -d "$dir" ]]; then
echo "$dir"
cd "$dir" || exit
terraform init
terraform validate
cd "${CURRENT_DIR}" || exit
fi
done
## Integrating testing using terraform native testing
- name: Testing example
working-directory: "${{ github.workspace }}/tests"
id: testing
run: |
pwd
terraform init
terraform test -no-color -var-file=multiple-identities.auto.tfvars
- uses: actions/github-script@v7
if: github.event_name == 'pull_request' && always() && !cancelled()
env:
TEST_OUTPUT: "${{ steps.testing.outputs.stdout }}"
TEST_ERROR: "${{ steps.testing.outputs.stderr }}"
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
// 1. Retrieve existing bot comments for the PR
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
})
const botComment = comments.find(comment => {
return comment.user.type === 'Bot' && comment.body.includes('Test Results')
})
// 2. Set output data
const output = `### Test Results :gear: Status: \`${{ steps.testing.outcome }}\`
- \`Test Output:\`
\`\`\`bash\n
${process.env.TEST_OUTPUT}
\`\`\`
- \`Test Error Message:\`
\`\`\`bash\n
${process.env.TEST_ERROR}
\`\`\`
*Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`, Workflow: \`${{ github.workflow }}\`*`;
// 3. If we have a comment, update it, otherwise create a new one
if (botComment) {
github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: output
})
} else {
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output
})
}
1 change: 1 addition & 0 deletions .github/workflows/publish-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
fetch-depth: 0 ## to get all tags

- name: Create GitHub release
working-directory: ./.github
run: |
release_tag="v$(yq '.module_version' "./release-version.yaml")"
release_notes="$(yq '.release_notes' "./release-version.yaml")"
Expand Down
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ crash.log
crash.*.log

# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json
Expand All @@ -32,3 +32,5 @@ override.tf.json
# Ignore CLI configuration files
.terraformrc
terraform.rc

!multiple-identities.auto.tfvars
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
-->

## v0.2.0

### Added
- Added example for creating multiple identities using individual combination of azure built-in and custom roles.

### Others
- Added automated tests for the example `multiple-identities`.
- To verify the core functionality of the module , create identities, assign multiple role and generate federated credentials.

## v0.1.0

### Added
Expand Down
2 changes: 1 addition & 1 deletion examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ clean-all: clean

.Phony: docs
docs:
terraform-docs --header-from local.tf markdown --sort-by required . > README.md
terraform-docs --header-from versions.tf markdown --sort-by required . > README.md
48 changes: 48 additions & 0 deletions examples/multiple-identities/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/multiple-identities/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../Makefile
40 changes: 40 additions & 0 deletions examples/multiple-identities/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Introduction

This example show the example of using the module to create a multiple user-managed identities and assign a combination of azure built-in and newly created custom role definitions via module.

## Requirements

No requirements.

## Providers

| Name | Version |
|------|---------|
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.85.0 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_multiple_identities"></a> [multiple\_identities](#module\_multiple\_identities) | ../../ | n/a |

## Resources

| Name | Type |
|------|------|
| [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_identities"></a> [identities](#input\_identities) | (optional) Identities to create. See README for more information.It includes all the inputs from the role\_assignments block in the module. | <pre>set(object({<br> service_account_name = string<br> namespace = string<br> role_assignments = set(object({<br> role_definition_name = optional(string)<br> name = optional(string, null)<br> create_custom_role = optional(bool, false)<br> condition = optional(string, null)<br> condition_version = optional(string, null)<br> scope = optional(string)<br> custom_role_description = optional(string)<br> custom_role_definition_id = optional(string, null)<br> custom_role_actions = optional(set(string), [])<br> custom_role_data_actions = optional(set(string), [])<br> custom_role_not_actions = optional(set(string), [])<br> custom_role_not_data_actions = optional(set(string), [])<br> custom_role_assignable_scopes = optional(set(string), null)<br> }))<br> }))</pre> | `[]` | no |
| <a name="input_namespace"></a> [namespace](#input\_namespace) | (optional) namesapce for example-service-account-02, need variable to over-ride in tests. | `string` | `"default"` | no |
| <a name="input_service_account_name"></a> [service\_account\_name](#input\_service\_account\_name) | (optional) Service Account name for second example, need variable to over-ride in tests. | `string` | `"example-service-account-02"` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_client_ids"></a> [client\_ids](#output\_client\_ids) | The IDs of the apps associated with the Identities |
| <a name="output_subjects"></a> [subjects](#output\_subjects) | The subjects for the Federated Identity Credential associated with the Identities |
48 changes: 48 additions & 0 deletions examples/multiple-identities/local.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
locals {
prefix = "wi-multi-module"

tags = {
github_repo = "ishuar/terraform-azure-workload-identity"
managed_by = "terraform"
used_case = "tf-az-wi-module-dev"
}

example-service-account-01 = [
########### Identity with Azure built-in role ###########
{
service_account_name = "example-service-account-01"
namespace = "example-01"
role_assignments = [
{
role_definition_name = "Reader"
scope = azurerm_resource_group.this.id
},
]
},
]
example-service-account-02 = [
########### Identity with Azure built-in and custom role ###########
{
service_account_name = var.service_account_name # for testing purposes
namespace = var.namespace # for testing purposes
role_assignments = [
{
role_definition_name = "Reader"
scope = azurerm_resource_group.this.id
},
{
role_definition_name = "blob-reader"
scope = azurerm_resource_group.this.id
create_custom_role = true
custom_role_data_actions = [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read",
]
}
]
}
]
identities = concat(
local.example-service-account-01,
local.example-service-account-02
)
}
19 changes: 19 additions & 0 deletions examples/multiple-identities/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
resource "azurerm_resource_group" "this" {
location = "North Europe"
name = "${local.prefix}-resources"
}

### Multiple Identities using for_each on the module level ###

module "multiple_identities" {
## check variables.tf for variable definition
for_each = { for identity in local.identities : identity.service_account_name => identity }

source = "../../"
resource_group_name = azurerm_resource_group.this.name
location = azurerm_resource_group.this.location
oidc_issuer_url = "https://token.actions.githubusercontent.com"
service_account_name = each.value.service_account_name
namespace = each.value.namespace
role_assignments = each.value.role_assignments
}
9 changes: 9 additions & 0 deletions examples/multiple-identities/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
output "client_ids" {
value = { for k, v in module.multiple_identities : k => v.client_id }
description = "The IDs of the apps associated with the Identities"
}

output "subjects" {
value = { for k, v in module.multiple_identities : k => v.subject }
description = "The subjects for the Federated Identity Credential associated with the Identities"
}
Loading

0 comments on commit 49a5adf

Please sign in to comment.