Skip to content
This repository has been archived by the owner on Dec 13, 2022. It is now read-only.

Commit

Permalink
Merge pull request #90 from arkahna/feature/refine-github-permissions
Browse files Browse the repository at this point in the history
Work on improving the create service principal generator
  • Loading branch information
JakeGinnivan authored Dec 6, 2022
2 parents 73a65d6 + aa5f406 commit b12f010
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/brave-olives-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@arkahna/nx-terraform': minor
---

Improvements to service principal creation
16 changes: 15 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,19 @@
],
"[terraform]": {
"editor.defaultFormatter": "hashicorp.terraform"
}
},
"hediet.vscode-drawio.theme": "Kennedy",
"hediet.vscode-drawio.customFonts": [
"Calibri"
],
"hediet.vscode-drawio.defaultVertexStyle": {
"fontFamily": "Calibri",
"fillColor": "#dae8fc",
"strokeColor": "#6c8ebf",
"strokeWidth": "1",
"labelBackgroundColor": "none"
},
"hediet.vscode-drawio.defaultEdgeStyle": {
"edgeStyle": "orthogonalEdgeStyle;"
},
}
26 changes: 26 additions & 0 deletions libs/nx-terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,30 @@ pnpm nx g \
@arkahna/nx-terraform:add-project-environment \
<projectname> \
--environment <environmentname>
```

### create-environment-sp

Creates a service principal for GitHub actions to use.

Need to be logged in as an application administrator role.

This generator will do the following:

- Create a service principal
- Grant the service principal the desired role on the environment resource group
- Grant the service principal permissions to write to the terraform state store (if using Azure storage for state)
- Grant the service principal permissions to read/write secrets in the environment KeyVault
- Add the Application.ReadWrite.Owner permission to the service principal
- Print the links and command line args to grant admin consent to the service principal (enabling Service Principal to Create and Maintain App Registrations)

#### Usage

```
pnpm nx g \
@arkahna/nx-terraform:create-environment-sp \
--environment <environmentname>
```

## Executors

Expand All @@ -115,3 +137,7 @@ If you are running apply multiple times locally, run with `--leaveFirewallExcept
### Lint

Needs tfsec installed, or set tfsec command to false. See https://github.com/aquasecurity/tfsec#installation

## Concepts

![Concepts](./docs/concepts.drawio.png)
Binary file added libs/nx-terraform/docs/concepts.drawio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion libs/nx-terraform/src/common/getEnvTfVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function getTfEnvVars(projectName: string, envConfig: EnvConfig, repoConf
`project_name_tag=${projectName || ''}`,
`cost_centre_tag=${repoConfig.azureCostCentre || ''}`,
`resource_prefix=${repoConfig.azureResourcePrefix || ''}`,
`github_service_principal=${envConfig.github_service_principal || ''}`,
`github_service_principal=${envConfig.github_service_principal_name || ''}`,
`github_service_principal_id=${envConfig.github_service_principal_id || ''}`,
]
}
Expand Down
4 changes: 3 additions & 1 deletion libs/nx-terraform/src/common/readConfigFromEnvFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ export async function readConfigFromEnvFile(
environmentFile,
attributes,
environmentFileBody: body,
github_service_principal: attributes.github_service_principal,
github_service_principal_name: attributes.github_service_principal_name,
github_service_principal_id: attributes.github_service_principal_id,
github_service_principal_app_object_id: attributes.github_service_principal_app_object_id,
github_service_principal_app_client_id: attributes.github_service_principal_app_client_id,
}
}
3 changes: 3 additions & 0 deletions libs/nx-terraform/src/executors/apply/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ export default async function runExecutor(options: ApplyExecutorSchema, context:
await execa('terragrunt', terragruntArguments, {
stdio: 'inherit',
cwd: projectRoot,
env: {
...process.env,
},
})
} finally {
if (options.leaveFirewallExceptions !== true) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default async function (
]

const idPlaceholder = 'ID_ONCE_CREATED'
const appIdPlaceholder = 'APP_ID_ONCE_CREATED'
const storageContributorRoleAssignmentArgs = [
'role',
'assignment',
Expand All @@ -64,6 +65,21 @@ export default async function (
kvScope,
]

const assignApplicationWritePermissions = [
'ad',
'app',
'permission',
'add',
'--id',
appIdPlaceholder,
'--api',
// Graph
'00000003-0000-0000-c000-000000000000',
'--api-permissions',
// Application.ReadWrite.OwnedBy
'18a4783c-866b-4cc7-a460-3d5e5662c884=Role',
]

if (isDryRun()) {
console.log('Will run:')

Expand All @@ -74,6 +90,8 @@ export default async function (
}

console.log(`> ${getEscapedCommand(`az`, keyvaultRoleAssignmentArgs)}`)

console.log(`> ${getEscapedCommand(`az`, assignApplicationWritePermissions)}`)
}

return async () => {
Expand All @@ -83,20 +101,34 @@ export default async function (
stdio: 'inherit',
})

const { stdout } = await execa(`az`, [
const { stdout: stdoutAdList } = await execa(`az`, [
'ad',
'sp',
'list',
'--display-name',
servicePrincipalName,
])
const servicePrincipalObjectId: string = JSON.parse(stdout)[0].id
const servicePrincipalObjectId: string = JSON.parse(stdoutAdList)[0].id
console.log(`Service principal id: ${servicePrincipalObjectId}`)

const { stdout: stdoutAppList } = await execa(`az`, [
'ad',
'app',
'list',
'--display-name',
servicePrincipalName,
])
const appObjectId: string = JSON.parse(stdoutAppList)[0].id
const appClientId: string = JSON.parse(stdoutAppList)[0].appId
console.log(`Service principal app object id: ${appObjectId}`)
console.log(`Service principal app client id: ${appClientId}`)

const newAttributes: Record<string, string | undefined> = {
...environmentConfig.attributes,
github_service_principal: servicePrincipalName,
github_service_principal_name: servicePrincipalName,
github_service_principal_id: servicePrincipalObjectId,
github_service_principal_app_object_id: appObjectId,
github_service_principal_app_client_id: appClientId,
}

fs.writeFileSync(
Expand Down Expand Up @@ -124,6 +156,7 @@ ${environmentConfig.environmentFileBody}
)
}

console.log()
console.log(`> ${getEscapedCommand(`az`, keyvaultRoleAssignmentArgs)}`)
await execa(
'az',
Expand All @@ -135,6 +168,24 @@ ${environmentConfig.environmentFileBody}
},
)

console.log(`> ${getEscapedCommand(`az`, assignApplicationWritePermissions)}`)
await execa(
'az',
assignApplicationWritePermissions.map((arg) =>
arg === appIdPlaceholder ? appObjectId : arg,
),
{
stdio: 'inherit',
},
)

console.log(
`Application link: https://portal.azure.com/?feature.msaljs=false#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/${appClientId}/isMSAApp~/false`,
)
console.log(
`Consent link: https://login.microsoftonline.com/${environmentConfig.tenantId}/adminconsent?client_id=${appClientId}`,
)

console.log(`πŸŽ‰ Success πŸŽ‰`)
console.log(
`πŸŽ‰ Ensure you copy the credentials, the secret will not be stored in ${environmentConfig.environmentFile} πŸŽ‰`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ variable "cost_centre_tag" {
}

variable "github_service_principal" {
description = "The name of the github service principal which deploys this environment (if configured through NX)."
description = "The id of the github service principal which deploys this environment (if configured through NX)."
type = string
nullable = true
}
Expand Down

0 comments on commit b12f010

Please sign in to comment.