diff --git a/src/Aks/index.ts b/src/Aks/index.ts index 745d4327..275c585b 100644 --- a/src/Aks/index.ts +++ b/src/Aks/index.ts @@ -499,7 +499,6 @@ export default async ({ } : undefined, }, - }, { protect: lock, @@ -513,7 +512,7 @@ export default async ({ ); if (lock) { - Locker({ name: aksName, resourceId: aks.id, dependsOn: aks }); + Locker({ name: aksName, resource: aks }); } if (nodePools) { diff --git a/src/AzAd/B2C.ts b/src/AzAd/B2C.ts index 38104bf7..856a14bb 100644 --- a/src/AzAd/B2C.ts +++ b/src/AzAd/B2C.ts @@ -45,7 +45,7 @@ export default ({ name, group, location, displayName, lock }: Props) => { }); if (lock) { - Locker({ name, resourceId: b2cTenant.id, dependsOn: b2cTenant }); + Locker({ name, resource: b2cTenant }); } return b2cTenant; diff --git a/src/AzAd/ManagedIdentity.ts b/src/AzAd/ManagedIdentity.ts index 2794b99b..ab958b31 100644 --- a/src/AzAd/ManagedIdentity.ts +++ b/src/AzAd/ManagedIdentity.ts @@ -1,7 +1,7 @@ -import { BasicResourceArgs } from "../types"; -import * as azure from "@pulumi/azure-native"; -import { getManagedIdentityName } from "../Common/Naming"; -import Locker from "../Core/Locker"; +import { BasicResourceArgs } from '../types'; +import * as azure from '@pulumi/azure-native'; +import { getManagedIdentityName } from '../Common/Naming'; +import Locker from '../Core/Locker'; interface Props extends BasicResourceArgs { lock?: boolean; @@ -12,14 +12,12 @@ export default ({ name, group, lock }: Props) => { const managedIdentity = new azure.managedidentity.UserAssignedIdentity(n, { resourceName: n, ...group, - }); if (lock) { Locker({ name: n, - resourceId: managedIdentity.id, - dependsOn: managedIdentity, + resource: managedIdentity, }); } diff --git a/src/Core/Locker.ts b/src/Core/Locker.ts index c7a0448c..21549803 100644 --- a/src/Core/Locker.ts +++ b/src/Core/Locker.ts @@ -4,10 +4,9 @@ import { Input, Resource } from '@pulumi/pulumi'; interface Props { name: string; - resourceId: pulumi.Output; + resource: Input; level?: authorization.LockLevel; protect?: boolean; - dependsOn?: Input[]> | Input; } /** Lock Delete from Resource group level.*/ @@ -16,7 +15,6 @@ export default ({ resourceId, level = authorization.LockLevel.CanNotDelete, protect = true, - dependsOn, }: Props) => { const n = `${name}-${level}`; @@ -25,9 +23,9 @@ export default ({ { lockName: n, level, - scope: resourceId, + scope: resource.id, notes: `Lock ${name} from ${level}`, }, - { dependsOn, protect } + { dependsOn: resource, protect } ); }; diff --git a/src/Core/ResourceCreator.ts b/src/Core/ResourceCreator.ts index 9a81a2e1..b6c8518f 100644 --- a/src/Core/ResourceCreator.ts +++ b/src/Core/ResourceCreator.ts @@ -64,7 +64,7 @@ export default function < //Lock Azure Resource from Delete let locker: authorization.ManagementLockByScope | undefined = undefined; if (lock) { - locker = Locker({ name, resourceId: resource.id, dependsOn: resource }); + locker = Locker({ name, resource }); } //Azure DiagnosticSetting diff --git a/src/IOT/Hub/index.ts b/src/IOT/Hub/index.ts index 5d8499ea..18317aae 100644 --- a/src/IOT/Hub/index.ts +++ b/src/IOT/Hub/index.ts @@ -1,7 +1,7 @@ import { BasicResourceArgs, KeyVaultInfo } from '../../types'; import { getIotHubName } from '../../Common/Naming'; import * as devices from '@pulumi/azure-native/devices'; -import { subscriptionId } from '../../Common/AzureEnv'; +import { subscriptionId } from '../../Common/AzureEnv'; import { Input } from '@pulumi/pulumi'; import Locker from '../../Core/Locker'; import { EnvRoleNamesType } from '../../AzAd/EnvRoles'; @@ -215,7 +215,7 @@ export default async ({ ); if (lock) { - Locker({ name, resourceId: hub.id, dependsOn: hub }); + Locker({ name, resource: hub }); } //Connection Strings if (vaultInfo) { diff --git a/src/MySql/index.ts b/src/MySql/index.ts index cb097e34..146d920c 100644 --- a/src/MySql/index.ts +++ b/src/MySql/index.ts @@ -1,24 +1,25 @@ -import { BasicResourceArgs, KeyVaultInfo } from "../types"; -import { getMySqlName } from "../Common/Naming"; -import * as pulumi from "@pulumi/pulumi"; -import * as dbformysql from "@pulumi/azure-native/dbformysql"; -import { randomPassword } from "../Core/Random"; -import * as inputs from "@pulumi/azure-native/types/input"; -import { addCustomSecret } from "../KeyVault/CustomHelper"; -import { currentEnv, isPrd, tenantId } from "../Common/AzureEnv"; -import { getAdGroup } from "../AzAd/Group"; -import Role from "../AzAd/Role"; -import { EnvRoleNamesType } from "../AzAd/EnvRoles"; -import { getEncryptionKey } from "../KeyVault/Helper"; -import UserIdentity from "../AzAd/UserIdentity"; -import { grantVaultAccessToIdentity } from "../KeyVault/VaultPermissions"; -import { RandomString } from "@pulumi/random"; -import PrivateEndpoint from "../VNet/PrivateEndpoint"; +import { BasicResourceArgs, KeyVaultInfo } from '../types'; +import { getMySqlName } from '../Common/Naming'; +import * as pulumi from '@pulumi/pulumi'; +import * as dbformysql from '@pulumi/azure-native/dbformysql'; +import { randomPassword } from '../Core/Random'; +import * as inputs from '@pulumi/azure-native/types/input'; +import { addCustomSecret } from '../KeyVault/CustomHelper'; +import { currentEnv, isPrd, tenantId } from '../Common/AzureEnv'; +import { getAdGroup } from '../AzAd/Group'; +import Role from '../AzAd/Role'; +import { EnvRoleNamesType } from '../AzAd/EnvRoles'; +import { getEncryptionKey } from '../KeyVault/Helper'; +import UserIdentity from '../AzAd/UserIdentity'; +import { grantVaultAccessToIdentity } from '../KeyVault/VaultPermissions'; +import { RandomString } from '@pulumi/random'; +import PrivateEndpoint from '../VNet/PrivateEndpoint'; +import Locker from '../Core/Locker'; export interface MySqlProps extends BasicResourceArgs { enableEncryption?: boolean; vaultInfo: KeyVaultInfo; - auth: { + auth?: { enableAdAdministrator?: boolean; envRoleNames?: EnvRoleNamesType; @@ -39,6 +40,7 @@ export interface MySqlProps extends BasicResourceArgs { endIpAddress: string; }>; }; + lock?:boolean } export default ({ @@ -52,13 +54,14 @@ export default ({ [Standard_B1ms, Standard_B1s, Standard_B2ms, Standard_B2s, Standard_B4ms, Standard_B8ms, Standard_D16s_v3, Standard_D2s_v3, Standard_D32s_v3, Standard_D4s_v3, Standard_D64s_v3, Standard_D8s_v3, Standard_E16s_v3, Standard_E2s_v3, Standard_E32s_v3, Standard_E4s_v3, Standard_E64s_v3, Standard_E8s_v3, Standard_M128ms, Standard_M128s, Standard_M64ms, Standard_M64s, Standard_E48s_v3, Standard_D2ds_v4, Standard_D4ds_v4, Standard_D8ds_v4, Standard_D16ds_v4, Standard_D32ds_v4, Standard_D48ds_v4, Standard_D64ds_v4, Standard_E2ds_v4, Standard_E4ds_v4, Standard_E8ds_v4, Standard_E16ds_v4, Standard_E32ds_v4, Standard_E48ds_v4, Standard_E64ds_v4, Standard_D48s_v3, Standard_E20ds_v4, Standard_M8ms, Standard_M16ms, Standard_M32ts, Standard_M32ls, Standard_M32ms, Standard_M64ls, Standard_M64, Standard_M64m, Standard_M128, Standard_M128m, Standard_B12ms, Standard_B16ms, Standard_B20ms, Standard_D2ads_v5, Standard_D4ads_v5, Standard_D8ads_v5, Standard_D16ads_v5, Standard_D32ads_v5, Standard_D48ads_v5, Standard_D64ads_v5, Standard_D96ads_v5, Standard_E2ads_v5, Standard_E4ads_v5, Standard_E8ads_v5, Standard_E16ads_v5, Standard_E20ads_v5, Standard_E32ads_v5, Standard_E48ads_v5, Standard_E64ads_v5, Standard_E96ads_v5, Standard_D2_v5, Standard_D4_v5, Standard_D8_v5, Standard_D16_v5, Standard_D32_v5, Standard_D48_v5, Standard_D64_v5, Standard_D96_v5, Standard_D2ds_v5, Standard_D4ds_v5, Standard_D8ds_v5, Standard_D16ds_v5, Standard_D32ds_v5, Standard_D48ds_v5, Standard_D64ds_v5, Standard_D96ds_v5, Standard_E2ds_v5, Standard_E4ds_v5, Standard_E8ds_v5, Standard_E16ds_v5, Standard_E20ds_v5, Standard_E32ds_v5, Standard_E48ds_v5, Standard_E64ds_v5, Standard_E96ds_v5, Standard_E104ids_v5, Standard_E2bds_v5, Standard_E4bds_v5, Standard_E8bds_v5, Standard_E16bds_v5, Standard_E32bds_v5, Standard_E48bds_v5, Standard_E64bds_v5, Standard_E112iads_v5, Standard_M32dms_v2, Standard_M64ds_v2, Standard_M64dms_v2, Standard_M128ds_v2, Standard_M128dms_v2, Standard_M192ids_v2, Standard_M192idms_v2] */ sku = { - name: "Standard_B1ms", - tier: "Burstable", + name: 'Standard_B1ms', + tier: 'Burstable', }, network, databases, vaultInfo, dependsOn, + lock:true, }: MySqlProps) => { name = getMySqlName(name); @@ -104,8 +107,8 @@ export default ({ version, storage: { storageSizeGB, - autoGrow: isPrd ? "Enabled" : "Disabled", - autoIoScaling: isPrd ? "Enabled" : "Disabled", + autoGrow: isPrd ? 'Enabled' : 'Disabled', + autoIoScaling: isPrd ? 'Enabled' : 'Disabled', }, // identity: { @@ -132,32 +135,36 @@ export default ({ //maintenanceWindow: { dayOfWeek: 6 }, sku, backup: { - geoRedundantBackup: isPrd ? "Enabled" : "Disabled", + geoRedundantBackup: isPrd ? 'Enabled' : 'Disabled', backupRetentionDays: isPrd ? 7 : 1, }, highAvailability: { - mode: isPrd ? "ZoneRedundant" : "Disabled", - standbyAvailabilityZone: "3", + mode: isPrd ? 'ZoneRedundant' : 'Disabled', + standbyAvailabilityZone: '3', }, - availabilityZone: "1", + availabilityZone: '1', }, { dependsOn, - protect: true, - ignoreChanges: ["administratorLogin", "dataEncryption"], + protect: lock, + ignoreChanges: ['administratorLogin', 'dataEncryption'], } ); + if (lock) { + Locker({ name, resource: mySql }); + } + if (auth?.enableAdAdministrator) { const adminGroup = auth.envRoleNames ? getAdGroup(auth.envRoleNames.admin) - : Role({ env: currentEnv, roleName: "ADMIN", appName: "MYSQL" }); + : Role({ env: currentEnv, roleName: 'ADMIN', appName: 'MYSQL' }); new dbformysql.AzureADAdministrator(name, { serverName: mySql.name, ...group, login: username, - administratorType: "ActiveDirectory", + administratorType: 'ActiveDirectory', sid: adminGroup.objectId, tenantId, }); @@ -181,8 +188,8 @@ export default ({ firewallRuleName: `${name}-firewall-allowpublic`, serverName: mySql.name, ...group, - startIpAddress: "0.0.0.0", - endIpAddress: "255.255.255.255", + startIpAddress: '0.0.0.0', + endIpAddress: '255.255.255.255', }); if (network.privateLink) { @@ -190,8 +197,8 @@ export default ({ name, group, resourceId: mySql.id, - privateDnsZoneName: "mysql.database.azure.com", - linkServiceGroupIds: ["mysql"], + privateDnsZoneName: 'mysql.database.azure.com', + linkServiceGroupIds: ['mysql'], subnetId: network.privateLink.subnetId, }); } diff --git a/src/Postgresql/index.ts b/src/Postgresql/index.ts index a0152bf4..5b01567c 100644 --- a/src/Postgresql/index.ts +++ b/src/Postgresql/index.ts @@ -1,13 +1,14 @@ -import { BasicResourceArgs, KeyVaultInfo } from "../types"; -import { getPostgresqlName } from "../Common/Naming"; -import * as pulumi from "@pulumi/pulumi"; -import * as azure from "@pulumi/azure-native"; -import { isPrd, tenantId } from "../Common/AzureEnv"; -import { randomPassword } from "../Core/Random"; -import * as inputs from "@pulumi/azure-native/types/input"; -import { addCustomSecret } from "../KeyVault/CustomHelper"; -import { RandomString } from "@pulumi/random"; -import PrivateEndpoint from "../VNet/PrivateEndpoint"; +import { BasicResourceArgs, KeyVaultInfo } from '../types'; +import { getPostgresqlName } from '../Common/Naming'; +import * as pulumi from '@pulumi/pulumi'; +import * as azure from '@pulumi/azure-native'; +import { isPrd, tenantId } from '../Common/AzureEnv'; +import { randomPassword } from '../Core/Random'; +import * as inputs from '@pulumi/azure-native/types/input'; +import { addCustomSecret } from '../KeyVault/CustomHelper'; +import { RandomString } from '@pulumi/random'; +import PrivateEndpoint from '../VNet/PrivateEndpoint'; +import Locker from '../Core/Locker'; export interface PostgresProps extends BasicResourceArgs { // auth: { @@ -29,6 +30,7 @@ export interface PostgresProps extends BasicResourceArgs { endIpAddress: string; }>; }; + lock?: true; } export default ({ @@ -41,13 +43,14 @@ export default ({ [Standard_B1ms, Standard_B1s, Standard_B2ms, Standard_B2s, Standard_B4ms, Standard_B8ms, Standard_D16s_v3, Standard_D2s_v3, Standard_D32s_v3, Standard_D4s_v3, Standard_D64s_v3, Standard_D8s_v3, Standard_E16s_v3, Standard_E2s_v3, Standard_E32s_v3, Standard_E4s_v3, Standard_E64s_v3, Standard_E8s_v3, Standard_M128ms, Standard_M128s, Standard_M64ms, Standard_M64s, Standard_E48s_v3, Standard_D2ds_v4, Standard_D4ds_v4, Standard_D8ds_v4, Standard_D16ds_v4, Standard_D32ds_v4, Standard_D48ds_v4, Standard_D64ds_v4, Standard_E2ds_v4, Standard_E4ds_v4, Standard_E8ds_v4, Standard_E16ds_v4, Standard_E32ds_v4, Standard_E48ds_v4, Standard_E64ds_v4, Standard_D48s_v3, Standard_E20ds_v4, Standard_M8ms, Standard_M16ms, Standard_M32ts, Standard_M32ls, Standard_M32ms, Standard_M64ls, Standard_M64, Standard_M64m, Standard_M128, Standard_M128m, Standard_B12ms, Standard_B16ms, Standard_B20ms, Standard_D2ads_v5, Standard_D4ads_v5, Standard_D8ads_v5, Standard_D16ads_v5, Standard_D32ads_v5, Standard_D48ads_v5, Standard_D64ads_v5, Standard_D96ads_v5, Standard_E2ads_v5, Standard_E4ads_v5, Standard_E8ads_v5, Standard_E16ads_v5, Standard_E20ads_v5, Standard_E32ads_v5, Standard_E48ads_v5, Standard_E64ads_v5, Standard_E96ads_v5, Standard_D2_v5, Standard_D4_v5, Standard_D8_v5, Standard_D16_v5, Standard_D32_v5, Standard_D48_v5, Standard_D64_v5, Standard_D96_v5, Standard_D2ds_v5, Standard_D4ds_v5, Standard_D8ds_v5, Standard_D16ds_v5, Standard_D32ds_v5, Standard_D48ds_v5, Standard_D64ds_v5, Standard_D96ds_v5, Standard_E2ds_v5, Standard_E4ds_v5, Standard_E8ds_v5, Standard_E16ds_v5, Standard_E20ds_v5, Standard_E32ds_v5, Standard_E48ds_v5, Standard_E64ds_v5, Standard_E96ds_v5, Standard_E104ids_v5, Standard_E2bds_v5, Standard_E4bds_v5, Standard_E8bds_v5, Standard_E16bds_v5, Standard_E32bds_v5, Standard_E48bds_v5, Standard_E64bds_v5, Standard_E112iads_v5, Standard_M32dms_v2, Standard_M64ds_v2, Standard_M64dms_v2, Standard_M128ds_v2, Standard_M128dms_v2, Standard_M192ids_v2, Standard_M192idms_v2] */ sku = { - name: "Standard_B1ms", - tier: "Burstable", + name: 'Standard_B1ms', + tier: 'Burstable', }, network, databases, vaultInfo, dependsOn, + lock:true, }: PostgresProps) => { name = getPostgresqlName(name); @@ -72,30 +75,34 @@ export default ({ storage: { storageSizeGB }, authConfig: { - passwordAuth: "Enabled", - activeDirectoryAuth: "Enabled", + passwordAuth: 'Enabled', + activeDirectoryAuth: 'Enabled', tenantId, }, administratorLogin: username, administratorLoginPassword: password, - dataEncryption: { type: "SystemManaged" }, + dataEncryption: { type: 'SystemManaged' }, //maintenanceWindow: { dayOfWeek: 6 }, sku, //network: {}, backup: { - geoRedundantBackup: isPrd ? "Enabled" : "Disabled", + geoRedundantBackup: isPrd ? 'Enabled' : 'Disabled', backupRetentionDays: 7, }, - highAvailability: { mode: isPrd ? "ZoneRedundant" : "Disabled" }, + highAvailability: { mode: isPrd ? 'ZoneRedundant' : 'Disabled' }, //availabilityZone: isPrd ? 3 : 1, }, { dependsOn, - protect: true, - ignoreChanges: ["administratorLogin", "dataEncryption"], + protect: lock, + ignoreChanges: ['administratorLogin', 'dataEncryption'], } ); + if (lock) { + Locker({ name, resource: postgres }); + } + if (network) { if (network.firewallRules) { network.firewallRules.map( @@ -114,8 +121,8 @@ export default ({ firewallRuleName: `${name}-firewall-allowpublic`, serverName: postgres.name, ...group, - startIpAddress: "0.0.0.0", - endIpAddress: "255.255.255.255", + startIpAddress: '0.0.0.0', + endIpAddress: '255.255.255.255', }); if (network.privateLink) { @@ -123,8 +130,8 @@ export default ({ name, group, resourceId: postgres.id, - privateDnsZoneName: "postgres.database.azure.com", - linkServiceGroupIds: ["postgresql"], + privateDnsZoneName: 'postgres.database.azure.com', + linkServiceGroupIds: ['postgresql'], subnetId: network.privateLink.subnetId, }); } diff --git a/src/ServiceBus/index.ts b/src/ServiceBus/index.ts index 12936dc9..ee591226 100644 --- a/src/ServiceBus/index.ts +++ b/src/ServiceBus/index.ts @@ -19,7 +19,7 @@ import { getTopicName, getTopicOrQueueVaultName, } from './ServiceBusHelper'; -import { isPrd } from '../Common/AzureEnv'; +import { isPrd } from '../Common/AzureEnv'; import creator from '../Core/ResourceCreator'; import { getPrivateEndpointName, getServiceBusName } from '../Common/Naming'; import PrivateEndpoint from '../VNet/PrivateEndpoint'; @@ -244,7 +244,7 @@ const topicCreator = ({ ); if (lock) { - Locker({ name: topicName, resourceId: topic.id, dependsOn: topic }); + Locker({ name: topicName, resource: topic }); } let primaryConnectionKeys: @@ -352,7 +352,7 @@ const subscriptionCreator = ({ ); if (lock) { - Locker({ name, resourceId: resource.id, dependsOn: resource }); + Locker({ name, resource }); } return { @@ -417,7 +417,7 @@ const queueCreator = ({ ); if (lock) { - Locker({ name, resourceId: queue.id, dependsOn: queue }); + Locker({ name, resource: queue }); } let primaryConnectionKeys: diff --git a/src/Sql/SqlDb.ts b/src/Sql/SqlDb.ts index b99868f0..33c98a16 100644 --- a/src/Sql/SqlDb.ts +++ b/src/Sql/SqlDb.ts @@ -1,23 +1,23 @@ -import * as sql from "@pulumi/azure-native/sql"; +import * as sql from '@pulumi/azure-native/sql'; -import { BasicResourceArgs, BasicResourceResultProps } from "../types"; -import { Input, Output, Resource } from "@pulumi/pulumi"; +import { BasicResourceArgs, BasicResourceResultProps } from '../types'; +import { Input, Output, Resource } from '@pulumi/pulumi'; -import { isPrd } from "../Common/AzureEnv"; -import { getSqlDbName } from "../Common/Naming"; -import Locker from "../Core/Locker"; +import { isPrd } from '../Common/AzureEnv'; +import { getSqlDbName } from '../Common/Naming'; +import Locker from '../Core/Locker'; export type SqlDbSku = - | "Basic" - | "S0" - | "S1" - | "S2" - | "S3" - | "P1" - | "P2" - | "P4" - | "P6" - | "P11"; + | 'Basic' + | 'S0' + | 'S1' + | 'S2' + | 'S3' + | 'P1' + | 'P2' + | 'P4' + | 'P6' + | 'P11'; export interface SqlDbProps extends BasicResourceArgs { sqlServerName: Input; @@ -34,7 +34,7 @@ export default ({ name, sqlServerName, elasticPoolId, - sku = "S0", + sku = 'S0', lock, dependsOn, }: SqlDbProps): BasicResourceResultProps => { @@ -44,7 +44,7 @@ export default ({ name, { databaseName: name, - createMode: "Default", + createMode: 'Default', ...group, serverName: sqlServerName, elasticPoolId, @@ -57,13 +57,13 @@ export default ({ // capacity: 5, }, //zoneRedundant: isPrd, - requestedBackupStorageRedundancy: isPrd ? "Zone" : "Local", + requestedBackupStorageRedundancy: isPrd ? 'Zone' : 'Local', }, - { dependsOn }, + { dependsOn } ); if (lock) { - Locker({ name, resourceId: sqlDb.id, dependsOn: sqlDb }); + Locker({ name, resource: sqlDb }); } //By Default is 7 Day diff --git a/src/Sql/index.ts b/src/Sql/index.ts index 182ac131..b0445827 100644 --- a/src/Sql/index.ts +++ b/src/Sql/index.ts @@ -1,29 +1,29 @@ -import * as sql from "@pulumi/azure-native/sql"; -import { all, Input, interpolate, Output } from "@pulumi/pulumi"; -import { getEncryptionKey } from "../KeyVault/Helper"; -import { EnvRoleNamesType } from "../AzAd/EnvRoles"; -import { getAdGroup } from "../AzAd/Group"; -import { roleAssignment } from "../AzAd/RoleAssignment"; +import * as sql from '@pulumi/azure-native/sql'; +import { all, Input, interpolate, Output } from '@pulumi/pulumi'; +import { getEncryptionKey } from '../KeyVault/Helper'; +import { EnvRoleNamesType } from '../AzAd/EnvRoles'; +import { getAdGroup } from '../AzAd/Group'; +import { roleAssignment } from '../AzAd/RoleAssignment'; import { currentEnv, isPrd, subscriptionId, tenantId, -} from "../Common/AzureEnv"; -import { getElasticPoolName, getSqlServerName } from "../Common/Naming"; -import Locker from "../Core/Locker"; +} from '../Common/AzureEnv'; +import { getElasticPoolName, getSqlServerName } from '../Common/Naming'; +import Locker from '../Core/Locker'; import { BasicResourceArgs, BasicResourceResultProps, KeyVaultInfo, PrivateLinkProps, -} from "../types"; -import { convertToIpRange } from "../VNet/Helper"; -import privateEndpointCreator from "../VNet/PrivateEndpoint"; -import sqlDbCreator, { SqlDbProps } from "./SqlDb"; -import { addCustomSecret } from "../KeyVault/CustomHelper"; -import Role from "../AzAd/Role"; -import { grantVaultAccessToIdentity } from "../KeyVault/VaultPermissions"; +} from '../types'; +import { convertToIpRange } from '../VNet/Helper'; +import privateEndpointCreator from '../VNet/PrivateEndpoint'; +import sqlDbCreator, { SqlDbProps } from './SqlDb'; +import { addCustomSecret } from '../KeyVault/CustomHelper'; +import Role from '../AzAd/Role'; +import { grantVaultAccessToIdentity } from '../KeyVault/VaultPermissions'; type ElasticPoolCapacityProps = 50 | 100 | 200 | 300 | 400 | 800 | 1200; @@ -31,7 +31,7 @@ interface ElasticPoolProps extends BasicResourceArgs { sqlName: Output; /** Minimum is 50 Gd*/ maxSizeBytesGb?: number; - sku?: { name: "Standard" | "Basic"; capacity: ElasticPoolCapacityProps }; + sku?: { name: 'Standard' | 'Basic'; capacity: ElasticPoolCapacityProps }; lock?: boolean; } @@ -41,7 +41,7 @@ const createElasticPool = ({ sqlName, //Minimum is 50 GD maxSizeBytesGb = 50, - sku = { name: isPrd ? "Standard" : "Basic", capacity: 50 }, + sku = { name: isPrd ? 'Standard' : 'Basic', capacity: 50 }, lock = true, }: ElasticPoolProps): BasicResourceResultProps => { //Create Sql Elastic @@ -60,7 +60,7 @@ const createElasticPool = ({ }, perDatabaseSettings: { minCapacity: 0, - maxCapacity: sku.name === "Basic" ? 5 : sku.capacity, + maxCapacity: sku.name === 'Basic' ? 5 : sku.capacity, }, zoneRedundant: isPrd, //licenseType: sql.ElasticPoolLicenseType.BasePrice, @@ -68,7 +68,7 @@ const createElasticPool = ({ }); if (lock) { - Locker({ name, resourceId: ep.id, dependsOn: ep }); + Locker({ name, resource: ep }); } return { name: elasticName, resource: ep }; @@ -89,12 +89,12 @@ interface Props extends BasicResourceArgs { }; elasticPool?: { - name: "Standard" | "Basic"; + name: 'Standard' | 'Basic'; capacity: ElasticPoolCapacityProps; }; databases: Array< - Omit + Omit >; network?: { @@ -103,7 +103,7 @@ interface Props extends BasicResourceArgs { subnetId?: Input; ipAddresses?: Input[]; /** To enable Private Link need to ensure the subnetId is provided. */ - privateLink?: Omit; + privateLink?: Omit; }; vulnerabilityAssessment?: { @@ -145,22 +145,22 @@ export default ({ auth?.enableAdAdministrator || auth.azureAdOnlyAuthentication ? auth.envRoleNames ? getAdGroup(auth.envRoleNames.admin) - : Role({ env: currentEnv, roleName: "ADMIN", appName: "SQL" }) + : Role({ env: currentEnv, roleName: 'ADMIN', appName: 'SQL' }) : undefined; - const ignoreChanges = ["administratorLogin", "administrators"]; + const ignoreChanges = ['administratorLogin', 'administrators']; if (auth.azureAdOnlyAuthentication) - ignoreChanges.push("administratorLoginPassword"); + ignoreChanges.push('administratorLoginPassword'); const sqlServer = new sql.Server( sqlName, { serverName: sqlName, ...group, - version: "12.0", - minimalTlsVersion: "1.2", + version: '12.0', + minimalTlsVersion: '1.2', - identity: { type: "SystemAssigned" }, + identity: { type: 'SystemAssigned' }, administratorLogin: auth?.adminLogin, administratorLoginPassword: auth?.password, @@ -185,14 +185,14 @@ export default ({ { ignoreChanges, protect: lock, - }, + } ); //Allows to Read Key Vault grantVaultAccessToIdentity({ name, identity: sqlServer.identity, vaultInfo }); if (lock) { - Locker({ name: sqlName, resourceId: sqlServer.id, dependsOn: sqlServer }); + Locker({ name: sqlName, resource: sqlServer }); } const ep = elasticPool @@ -210,10 +210,10 @@ export default ({ group, name, resourceId: sqlServer.id, - privateDnsZoneName: "privatelink.database.windows.net", + privateDnsZoneName: 'privatelink.database.windows.net', ...network.privateLink, subnetId: network.subnetId, - linkServiceGroupIds: ["sqlServer"], + linkServiceGroupIds: ['sqlServer'], }); } else { //Link to Vnet @@ -230,12 +230,12 @@ export default ({ //Allow Public Ip Accessing if (network?.acceptAllInternetConnect) { - new sql.FirewallRule("accept-all-connection", { - firewallRuleName: "accept-all-connection", + new sql.FirewallRule('accept-all-connection', { + firewallRuleName: 'accept-all-connection', serverName: sqlServer.name, ...group, - startIpAddress: "0.0.0.0", - endIpAddress: "255.255.255.255", + startIpAddress: '0.0.0.0', + endIpAddress: '255.255.255.255', }); } else if (network?.ipAddresses) { all(network.ipAddresses).apply((ips) => @@ -249,7 +249,7 @@ export default ({ startIpAddress: ip.start, endIpAddress: ip.end, }); - }), + }) ); } @@ -258,9 +258,9 @@ export default ({ if (vulnerabilityAssessment.logStorageId) { roleAssignment({ name, - principalId: sqlServer.identity.apply((i) => i?.principalId || ""), - principalType: "ServicePrincipal", - roleName: "Storage Blob Data Contributor", + principalId: sqlServer.identity.apply((i) => i?.principalId || ''), + principalType: 'ServicePrincipal', + roleName: 'Storage Blob Data Contributor', scope: vulnerabilityAssessment.logStorageId, }); } @@ -268,20 +268,20 @@ export default ({ //Server Audit new sql.ExtendedServerBlobAuditingPolicy(name, { auditActionsAndGroups: [ - "SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP", - "FAILED_DATABASE_AUTHENTICATION_GROUP", - "BATCH_COMPLETED_GROUP", + 'SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP', + 'FAILED_DATABASE_AUTHENTICATION_GROUP', + 'BATCH_COMPLETED_GROUP', ], serverName: sqlServer.name, ...group, - blobAuditingPolicyName: "default", + blobAuditingPolicyName: 'default', isAzureMonitorTargetEnabled: true, isStorageSecondaryKeyInUse: false, predicateExpression: "object_name = 'SensitiveData'", queueDelayMs: 4000, retentionDays: isPrd ? 30 : 6, - state: "Enabled", + state: 'Enabled', isDevopsAuditEnabled: true, storageAccountAccessKey: vulnerabilityAssessment.storageAccessKey, @@ -301,7 +301,7 @@ export default ({ storageAccountAccessKey: vulnerabilityAssessment.storageAccessKey, storageEndpoint: vulnerabilityAssessment.storageEndpoint, - state: "Enabled", + state: 'Enabled', }); //ServerVulnerabilityAssessment @@ -324,7 +324,7 @@ export default ({ if (encryptKey) { // Enable a server key in the SQL Server with reference to the Key Vault Key const keyName = encryptKey.apply( - (c) => `${vaultInfo.name}_${c!.name}_${c!.properties.version}`, + (c) => `${vaultInfo.name}_${c!.name}_${c!.properties.version}` ); const serverKey = new sql.ServerKey( @@ -332,27 +332,29 @@ export default ({ { resourceGroupName: group.resourceGroupName, serverName: sqlName, - serverKeyType: "AzureKeyVault", + serverKeyType: 'AzureKeyVault', keyName, uri: encryptKey.apply( (c) => - `https://${vaultInfo.name}.vault.azure.net/keys/${c!.name}/${c!.properties.version}`, + `https://${vaultInfo.name}.vault.azure.net/keys/${c!.name}/${ + c!.properties.version + }` ), }, - { ignoreChanges: ["keyName", "uri"] }, + { ignoreChanges: ['keyName', 'uri'] } ); new sql.EncryptionProtector( `${sqlName}-encryptionProtector`, { - encryptionProtectorName: "current", + encryptionProtectorName: 'current', resourceGroupName: group.resourceGroupName, serverName: sqlName, - serverKeyType: "AzureKeyVault", + serverKeyType: 'AzureKeyVault', serverKeyName: keyName, autoRotationEnabled: true, }, - { dependsOn: serverKey }, + { dependsOn: serverKey } ); } diff --git a/src/Storage/index.ts b/src/Storage/index.ts index 97b0f771..2420c396 100644 --- a/src/Storage/index.ts +++ b/src/Storage/index.ts @@ -1,25 +1,25 @@ -import * as storage from "@pulumi/azure-native/storage"; +import * as storage from '@pulumi/azure-native/storage'; -import { KeyVaultInfo, BasicResourceArgs } from "../types"; -import { Input } from "@pulumi/pulumi"; -import { createThreatProtection } from "../Logs/Helpers"; -import { getSecret, getEncryptionKey } from "../KeyVault/Helper"; -import { isPrd } from "../Common/AzureEnv"; -import cdnCreator from "./CdnEndpoint"; +import { KeyVaultInfo, BasicResourceArgs } from '../types'; +import { Input } from '@pulumi/pulumi'; +import { createThreatProtection } from '../Logs/Helpers'; +import { getSecret, getEncryptionKey } from '../KeyVault/Helper'; +import { isPrd } from '../Common/AzureEnv'; +import cdnCreator from './CdnEndpoint'; import { getConnectionName, getKeyName, getStorageName, -} from "../Common/Naming"; -import { addCustomSecrets } from "../KeyVault/CustomHelper"; -import Locker from "../Core/Locker"; +} from '../Common/Naming'; +import { addCustomSecrets } from '../KeyVault/CustomHelper'; +import Locker from '../Core/Locker'; import { createManagementRules, DefaultManagementRules, ManagementRules, -} from "./ManagementRules"; -import { grantVaultAccessToIdentity } from "../KeyVault/VaultPermissions"; +} from './ManagementRules'; +import { grantVaultAccessToIdentity } from '../KeyVault/VaultPermissions'; type ContainerProps = { name: string; @@ -93,10 +93,10 @@ export default ({ }: StorageProps) => { name = getStorageName(name); - const primaryKeyName = getKeyName(name, "primary"); - const secondaryKeyName = getKeyName(name, "secondary"); - const primaryConnectionKeyName = getConnectionName(name, "primary"); - const secondConnectionKeyName = getConnectionName(name, "secondary"); + const primaryKeyName = getKeyName(name, 'primary'); + const secondaryKeyName = getKeyName(name, 'secondary'); + const primaryConnectionKeyName = getConnectionName(name, 'primary'); + const secondConnectionKeyName = getConnectionName(name, 'secondary'); const encryptionKey = featureFlags.enableKeyVaultEncryption ? getEncryptionKey(name, vaultInfo) : undefined; @@ -112,14 +112,14 @@ export default ({ ? storage.SkuName.Standard_ZRS //Zone redundant in PRD : storage.SkuName.Standard_LRS, }, - accessTier: "Hot", + accessTier: 'Hot', isHnsEnabled: true, enableHttpsTrafficOnly: true, allowBlobPublicAccess: policies?.allowBlobPublicAccess, allowSharedKeyAccess: featureFlags.allowSharedKeyAccess, - identity: { type: "SystemAssigned" }, - minimumTlsVersion: "TLS1_2", + identity: { type: 'SystemAssigned' }, + minimumTlsVersion: 'TLS1_2', //1 Year Months keyPolicy: { @@ -148,7 +148,7 @@ export default ({ sasPolicy: { expirationAction: storage.ExpirationAction.Log, - sasExpirationPeriod: "00.00:30:00", + sasExpirationPeriod: '00.00:30:00', }, customDomain: @@ -166,8 +166,8 @@ export default ({ networkRuleSet: network ? { - bypass: "Logging, Metrics", - defaultAction: "Allow", + bypass: 'Logging, Metrics', + defaultAction: 'Allow', virtualNetworkRules: network.subnetId ? [{ virtualNetworkResourceId: network.subnetId }] @@ -176,11 +176,11 @@ export default ({ ipRules: network.ipAddresses ? network.ipAddresses.map((i) => ({ iPAddressOrRange: i, - action: "Allow", + action: 'Allow', })) : undefined, } - : { defaultAction: "Allow" }, + : { defaultAction: 'Allow' }, }); //Soft Delete @@ -230,7 +230,7 @@ export default ({ } if (lock) { - Locker({ name, resourceId: stg.id, dependsOn: stg }); + Locker({ name, resource: stg }); } //Enable Static Website for SPA @@ -240,10 +240,10 @@ export default ({ { accountName: stg.name, ...group, - indexDocument: "index.html", - error404Document: "index.html", + indexDocument: 'index.html', + error404Document: 'index.html', }, - { dependsOn: stg }, + { dependsOn: stg } ); // if (appInsight && customDomain) { @@ -275,7 +275,7 @@ export default ({ ...group, accountName: stg.name, //denyEncryptionScopeOverride: true, - publicAccess: c.public ? "Blob" : "None", + publicAccess: c.public ? 'Blob' : 'None', }); if (c.managementRules) { @@ -329,7 +329,7 @@ export default ({ //Keys addCustomSecrets({ vaultInfo, - contentType: "Storage", + contentType: 'Storage', formattedName: true, items: [ { diff --git a/src/VM/index.ts b/src/VM/index.ts index 86f201f0..d3776ac9 100644 --- a/src/VM/index.ts +++ b/src/VM/index.ts @@ -1,8 +1,8 @@ -import { Input, Resource } from "@pulumi/pulumi"; -import * as native from "@pulumi/azure-native"; -import { BasicResourceArgs, KeyVaultInfo } from "../types"; -import { getNICName, getVMName } from "../Common/Naming"; -import Locker from "../Core/Locker"; +import { Input, Resource } from '@pulumi/pulumi'; +import * as native from '@pulumi/azure-native'; +import { BasicResourceArgs, KeyVaultInfo } from '../types'; +import { getNICName, getVMName } from '../Common/Naming'; +import Locker from '../Core/Locker'; interface Props extends BasicResourceArgs { subnetId: Input; @@ -12,15 +12,15 @@ interface Props extends BasicResourceArgs { login: { userName: Input; password?: Input }; windows?: { - offer: "WindowsServer"; - publisher: "MicrosoftWindowsServer"; - sku: "2019-Datacenter"; + offer: 'WindowsServer'; + publisher: 'MicrosoftWindowsServer'; + sku: '2019-Datacenter'; }; linux?: { - offer: "UbuntuServer"; - publisher: "Canonical"; - sku: "18.04-LTS"; + offer: 'UbuntuServer'; + publisher: 'Canonical'; + sku: '18.04-LTS'; }; vaultInfo?: KeyVaultInfo; @@ -42,8 +42,8 @@ export default ({ name, group, subnetId, - vmSize = "Standard_B2s", - timeZone = "Singapore Standard Time", + vmSize = 'Standard_B2s', + timeZone = 'Singapore Standard Time', //licenseType = 'None', storageAccountType = native.compute.StorageAccountTypes.Premium_LRS, osDiskSizeGB = 128, @@ -66,7 +66,7 @@ export default ({ networkInterfaceName: nicName, ...group, ipConfigurations: [ - { name: "ipconfig", subnet: { id: subnetId }, primary: true }, + { name: 'ipconfig', subnet: { id: subnetId }, primary: true }, ], nicType: native.network.NetworkInterfaceNicType.Standard, }); @@ -79,8 +79,8 @@ export default ({ ...others, hardwareProfile: { vmSize }, - identity: { type: "SystemAssigned" }, - licenseType: "None", + identity: { type: 'SystemAssigned' }, + licenseType: 'None', networkProfile: { networkInterfaces: [{ id: nic.id, primary: true }], @@ -101,7 +101,7 @@ export default ({ provisionVMAgent: true, patchSettings: { //assessmentMode: "AutomaticByPlatform", - patchMode: "AutomaticByPlatform", + patchMode: 'AutomaticByPlatform', }, } : undefined, @@ -115,7 +115,7 @@ export default ({ enableHotpatching: false, //Need to be enabled at subscription level //assessmentMode: 'AutomaticByPlatform', - patchMode: "AutomaticByPlatform", + patchMode: 'AutomaticByPlatform', }, } : undefined, @@ -124,14 +124,14 @@ export default ({ storageProfile: { imageReference: { ...(windows || linux), - version: "latest", + version: 'latest', }, osDisk: { name: `${name}osdisk`, diskSizeGB: osDiskSizeGB, - caching: "ReadWrite", - createOption: "FromImage", - osType: windows ? "Windows" : "Linux", + caching: 'ReadWrite', + createOption: 'FromImage', + osType: windows ? 'Windows' : 'Linux', managedDisk: { //Changes storage account type need to be done manually through portal. storageAccountType, @@ -161,14 +161,14 @@ export default ({ { dependsOn, ignoreChanges: [ - "storageProfile.osDisk.managedDisk.storageAccountType", - "storageProfile.osDisk.managedDisk.id", + 'storageProfile.osDisk.managedDisk.storageAccountType', + 'storageProfile.osDisk.managedDisk.id', ], } ); if (lock) { - Locker({ name: vmName, resourceId: vm.id, dependsOn: vm }); + Locker({ name: vmName, resource: vm }); } if (schedule) { @@ -179,15 +179,15 @@ export default ({ ...group, dailyRecurrence: { time: schedule.autoShutdownTime }, timeZoneId: timeZone, - status: "Enabled", + status: 'Enabled', targetResourceId: vm.id, - taskType: "ComputeVmShutdownTask", + taskType: 'ComputeVmShutdownTask', notificationSettings: { - status: "Disabled", - emailRecipient: "", - notificationLocale: "en", + status: 'Disabled', + emailRecipient: '', + notificationLocale: 'en', timeInMinutes: 30, - webhookUrl: "", + webhookUrl: '', }, }, { dependsOn: vm } diff --git a/src/VNet/IpAddress.ts b/src/VNet/IpAddress.ts index 05178369..be518d5b 100644 --- a/src/VNet/IpAddress.ts +++ b/src/VNet/IpAddress.ts @@ -62,7 +62,7 @@ export default ({ ); if (lock) { - Locker({ name, resourceId: ipAddress.id, dependsOn: ipAddress }); + Locker({ name, resource: ipAddress }); } return ipAddress; diff --git a/src/VNet/IpAddressPrefix.ts b/src/VNet/IpAddressPrefix.ts index bdd0c3b3..71235587 100644 --- a/src/VNet/IpAddressPrefix.ts +++ b/src/VNet/IpAddressPrefix.ts @@ -44,8 +44,7 @@ export default ({ if (lock) { Locker({ name, - resourceId: addressPrefix.id, - dependsOn: addressPrefix, + resource: addressPrefix, }); } diff --git a/src/Web/FuncApp.ts b/src/Web/FuncApp.ts index 6e8439bd..5074cac1 100644 --- a/src/Web/FuncApp.ts +++ b/src/Web/FuncApp.ts @@ -41,7 +41,7 @@ export default ({ ); if (lock) { - Locker({ name, resourceId: app.id, dependsOn: app }); + Locker({ name, resource: app }); } return app; }; diff --git a/src/Web/WebAppPlan.ts b/src/Web/WebAppPlan.ts index ff42285f..8cce0e86 100644 --- a/src/Web/WebAppPlan.ts +++ b/src/Web/WebAppPlan.ts @@ -29,7 +29,7 @@ export default ({ name, group, kind, lock }: Props) => { }); if (lock) { - Locker({ name, resourceId: appServicePlan.id, dependsOn: appServicePlan }); + Locker({ name, resource: appServicePlan }); } return appServicePlan; };