-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[BOOST-652] Implement skeleton for azure-infrastructure (#197)
* [BOOST-652] - Implement skeleton for azure-infrastructure
- Loading branch information
Showing
19 changed files
with
713 additions
and
10 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
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
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
3 changes: 3 additions & 0 deletions
3
packages/framework-provider-azure-infrastructure/.eslintignore
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,3 @@ | ||
dist | ||
lib | ||
node_modules |
10 changes: 10 additions & 0 deletions
10
packages/framework-provider-azure-infrastructure/.mocharc.yml
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,10 @@ | ||
diff: true | ||
require: 'ts-node/register' | ||
extension: | ||
- ts | ||
package: './package.json' | ||
recursive: true | ||
reporter: 'spec' | ||
timeout: 5000 | ||
full-trace: true | ||
bail: true |
44 changes: 44 additions & 0 deletions
44
packages/framework-provider-azure-infrastructure/package.json
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,44 @@ | ||
{ | ||
"name": "@boostercloud/framework-provider-azure-infrastructure", | ||
"version": "0.4.1", | ||
"description": "Handle the Booster deployment process to Azure", | ||
"keywords": [ | ||
"framework-provider-azure-infrastructure" | ||
], | ||
"author": "Booster Cloud", | ||
"homepage": "https://booster.cloud", | ||
"license": "Apache-2.0", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"main": "dist/index.js", | ||
"files": [ | ||
"dist" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/boostercloud/booster.git" | ||
}, | ||
"dependencies": { | ||
"@boostercloud/framework-types": "^0.4.1", | ||
"@boostercloud/framework-provider-azure": "^0.4.0", | ||
"ms-rest-azure": "^3.0.0", | ||
"azure-arm-resource": "^7.3.0", | ||
"copyfiles": "^2.3.0" | ||
}, | ||
"scripts": { | ||
"lint": "eslint --ext '.js,.ts' **/*.ts", | ||
"fix-lint": "eslint --quiet --fix --ext '.js,.ts' **/*.ts", | ||
"compile": "tsc -b tsconfig.json && copyfiles -f src/infrastructure/templates/*.json dist/infrastructure/templates", | ||
"clean": "rimraf ./dist tsconfig.tsbuildinfo", | ||
"prepack": "tsc -b tsconfig.json", | ||
"test": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/boostercloud/booster/issues" | ||
}, | ||
"devDependencies": { | ||
"@types/faker": "^4.1.11", | ||
"faker": "^4.1.0" | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
packages/framework-provider-azure-infrastructure/src/index.ts
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,6 @@ | ||
import { deploy, nuke } from './infrastructure' | ||
|
||
export const Infrastructure = { | ||
deploy, | ||
nuke, | ||
} |
43 changes: 43 additions & 0 deletions
43
packages/framework-provider-azure-infrastructure/src/infrastructure/index.ts
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,43 @@ | ||
import { Observable, Subscriber } from 'rxjs' | ||
import { BoosterConfig } from '@boostercloud/framework-types' | ||
import { ApplicationStackBuilder } from './stacks/application-stack' | ||
import { createResourceGroup, createResourceGroupName, createResourceManagementClient } from './setup' | ||
|
||
export function deploy(configuration: BoosterConfig): Observable<string> { | ||
return new Observable((observer): void => { | ||
// eslint-disable-next-line @typescript-eslint/no-floating-promises | ||
deployApp(observer, configuration) | ||
.catch((error): void => observer.error(error)) | ||
.then((): void => observer.complete()) | ||
}) | ||
} | ||
|
||
export function nuke(configuration: BoosterConfig): Observable<string> { | ||
return new Observable((observer): void => { | ||
// eslint-disable-next-line @typescript-eslint/no-floating-promises | ||
nukeApp(observer, configuration) | ||
.catch((error): void => observer.error(error)) | ||
.then((): void => observer.complete()) | ||
}) | ||
} | ||
|
||
/** | ||
* Deploys the application in Azure | ||
*/ | ||
async function deployApp(observer: Subscriber<string>, config: BoosterConfig): Promise<void> { | ||
const resourceManagementClient = await createResourceManagementClient() | ||
const resourceGroupName = createResourceGroupName(config) | ||
await createResourceGroup(resourceGroupName, resourceManagementClient) | ||
const applicationBuilder = new ApplicationStackBuilder(config) | ||
await applicationBuilder.buildOn(resourceManagementClient, resourceGroupName) | ||
} | ||
|
||
/** | ||
* Nuke all the resources used in the Resource Group | ||
*/ | ||
async function nukeApp(observer: Subscriber<string>, config: BoosterConfig): Promise<void> { | ||
const resourceManagementClient = await createResourceManagementClient() | ||
|
||
// By deleting the resource group we are deleting all the resources within it. | ||
await resourceManagementClient.resourceGroups.deleteMethod(createResourceGroupName(config)) | ||
} |
7 changes: 7 additions & 0 deletions
7
packages/framework-provider-azure-infrastructure/src/infrastructure/params.ts
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,7 @@ | ||
export const configuration = { | ||
appId: process.env['AZURE_APP_ID'] ?? '', | ||
secret: process.env['AZURE_SECRET'] ?? '', | ||
tenantId: process.env['AZURE_TENANT_ID'] ?? '', | ||
subscriptionId: process.env['AZURE_SUBSCRIPTION_ID'] ?? '', | ||
region: process.env['REGION'] ?? '', | ||
} |
41 changes: 41 additions & 0 deletions
41
packages/framework-provider-azure-infrastructure/src/infrastructure/setup.ts
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,41 @@ | ||
import ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient' | ||
import { configuration } from './params' | ||
import { ApplicationTokenCredentials, loginWithServicePrincipalSecret } from 'ms-rest-azure' | ||
import { ResourceGroup } from 'azure-arm-resource/lib/resource/models' | ||
import { BoosterConfig } from '@boostercloud/framework-types/dist' | ||
|
||
export async function createResourceManagementClient(): Promise<ResourceManagementClient> { | ||
const credentials = await azureCredentials() | ||
return new ResourceManagementClient(credentials, configuration.subscriptionId) | ||
} | ||
|
||
export async function azureCredentials(): Promise<ApplicationTokenCredentials> { | ||
const applicationTokenCredentials = await loginWithServicePrincipalSecret( | ||
configuration.appId, | ||
configuration.secret, | ||
configuration.tenantId); | ||
|
||
if (!applicationTokenCredentials) { | ||
throw new Error( | ||
'Unable to login with Service Principal. Please verified provided appId, secret and subscription ID in .env file are correct.' | ||
) | ||
} | ||
|
||
return applicationTokenCredentials | ||
} | ||
|
||
export async function createResourceGroup( | ||
resourceGroupName: string, | ||
resourceManagementClient: ResourceManagementClient | ||
) { | ||
const existed = await resourceManagementClient.resourceGroups.checkExistence(resourceGroupName) | ||
|
||
if(!existed) { | ||
const groupParameters: ResourceGroup = { location: configuration.region } | ||
await resourceManagementClient.resourceGroups.createOrUpdate(resourceGroupName, groupParameters) | ||
} | ||
} | ||
|
||
export function createResourceGroupName(config: BoosterConfig): string { | ||
return 'resource-group-' + config.appName + '-' + config.environmentName | ||
} |
74 changes: 74 additions & 0 deletions
74
...es/framework-provider-azure-infrastructure/src/infrastructure/stacks/application-stack.ts
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,74 @@ | ||
import { BoosterConfig } from '@boostercloud/framework-types' | ||
import ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient' | ||
import { DeploymentExtended } from 'azure-arm-resource/lib/resource/models' | ||
|
||
export class ApplicationStackBuilder { | ||
public constructor(readonly config: BoosterConfig) {} | ||
|
||
public async buildOn(resourceManagementClient: ResourceManagementClient, resourceGroupName: string): Promise<void> { | ||
const storageAccountDeployment = await this.buildResource( | ||
resourceManagementClient, | ||
resourceGroupName, | ||
{}, | ||
'../templates/storage-account.json' | ||
) | ||
// @ts-ignore | ||
const functionAppDeployment = await this.buildResource( | ||
resourceManagementClient, | ||
resourceGroupName, | ||
{ | ||
storageAccountName: { | ||
// @ts-ignore | ||
value: storageAccountDeployment.properties.outputs.storageAccountName.value, | ||
}, | ||
}, | ||
'../templates/function-app.json' | ||
) | ||
// @ts-ignore | ||
const apiManagementServiceDeployment = await this.buildResource( | ||
resourceManagementClient, | ||
resourceGroupName, | ||
{ | ||
publisherEmail: { value: 'mario@theagilemonkeys.com' }, | ||
publisherName: { value: 'The Agile Monkeys' }, | ||
apiName: { value: this.config.appName + '-rest-api' }, | ||
apiDisplayName: { value: this.config.appName + '-rest-api' }, | ||
apiPath: { value: '/' + this.config.environmentName }, | ||
}, | ||
'../templates/api-management.json' | ||
) | ||
} | ||
|
||
/** | ||
* Deploys an Azure resource to a resource group. | ||
* | ||
* @param {ResourceManagementClient} resourceManagementClient A ResourceManagementClient instance | ||
* @param {string} resourceGroupName The resource group where the resource will be deployed to | ||
* @param {object} parameters A JSON object with parameters for the ARM template | ||
* @param {string} templatePath The path of the ARM template JSON file | ||
* | ||
* @returns {Promise<DeploymentExtended>} | ||
*/ | ||
private async buildResource( | ||
resourceManagementClient: ResourceManagementClient, | ||
resourceGroupName: string, | ||
parameters: object, | ||
templatePath: string | ||
): Promise<DeploymentExtended> { | ||
const template = require(templatePath) | ||
|
||
const deploymentParameters = { | ||
properties: { | ||
parameters: parameters, | ||
template: template, | ||
mode: 'Incremental', | ||
}, | ||
} | ||
|
||
return resourceManagementClient.deployments.createOrUpdate( | ||
resourceGroupName, | ||
'testdeploymentbooster', | ||
deploymentParameters | ||
) | ||
} | ||
} |
99 changes: 99 additions & 0 deletions
99
.../framework-provider-azure-infrastructure/src/infrastructure/templates/api-management.json
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,99 @@ | ||
{ | ||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", | ||
"contentVersion": "1.0.0.0", | ||
"parameters": { | ||
"publisherEmail": { | ||
"type": "string", | ||
"minLength": 1, | ||
"metadata": { | ||
"description": "The email address of the owner of the service" | ||
} | ||
}, | ||
"publisherName": { | ||
"type": "string", | ||
"minLength": 1, | ||
"metadata": { | ||
"description": "The name of the owner of the service" | ||
} | ||
}, | ||
"sku": { | ||
"type": "string", | ||
"allowedValues": [ | ||
"Consumption", | ||
"Developer", | ||
"Standard", | ||
"Premium" | ||
], | ||
"defaultValue": "Consumption", | ||
"metadata": { | ||
"description": "The pricing tier of this API Management service" | ||
} | ||
}, | ||
"skuCount": { | ||
"type": "int", | ||
"allowedValues": [ | ||
0, | ||
1, | ||
2 | ||
], | ||
"defaultValue": 0, | ||
"metadata": { | ||
"description": "The instance size of this API Management service." | ||
} | ||
}, | ||
"location": { | ||
"type": "string", | ||
"defaultValue": "[resourceGroup().location]", | ||
"metadata": { | ||
"description": "Location for all resources." | ||
} | ||
}, | ||
"apiName": { | ||
"type": "string" | ||
}, | ||
"apiDisplayName": { | ||
"type": "string" | ||
}, | ||
"apiPath": { | ||
"type": "string" | ||
} | ||
}, | ||
"variables": { | ||
"apiManagementServiceName": "[concat('apiservice', uniqueString(resourceGroup().id))]" | ||
}, | ||
"resources": [ | ||
{ | ||
"apiVersion": "2019-12-01", | ||
"name": "[variables('apiManagementServiceName')]", | ||
"type": "Microsoft.ApiManagement/service", | ||
"location": "[parameters('location')]", | ||
"tags": {}, | ||
"sku": { | ||
"name": "[parameters('sku')]", | ||
"capacity": "[parameters('skuCount')]" | ||
}, | ||
"properties": { | ||
"publisherEmail": "[parameters('publisherEmail')]", | ||
"publisherName": "[parameters('publisherName')]" | ||
}, | ||
"resources": [ | ||
{ | ||
"name": "[parameters('apiName')]", | ||
"type": "apis", | ||
"dependsOn": [ | ||
"[concat('Microsoft.ApiManagement/service/', variables('apiManagementServiceName'))]" | ||
], | ||
"apiVersion": "2019-12-01", | ||
"properties": { | ||
"path": "[parameters('apiPath')]", | ||
"displayName": "[parameters('apiDisplayName')]", | ||
"protocols": [ | ||
"http", | ||
"https" | ||
] | ||
} | ||
} | ||
] | ||
} | ||
] | ||
} |
Oops, something went wrong.