Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/lib/azure/common/construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
AzureDnsManager,
AzureLogAnalyticsWorkspaceManager,
AzureMonitorManager,
AzureRedisManager,
} from '../services'
import { CommonAzureStackProps } from './types'
import { AzureRemoteBackend } from './constants'
Expand All @@ -40,6 +41,7 @@ export class CommonAzureConstruct extends TerraformStack {
keyVaultManager: AzureKeyVaultManager
logAnalyticsWorkspaceManager: AzureLogAnalyticsWorkspaceManager
monitorManager: AzureMonitorManager
redisManager: AzureRedisManager
resourceGroupManager: AzureResourceGroupManager
resourceNameFormatter: AzureResourceNameFormatter
servicebusManager: AzureServicebusManager
Expand All @@ -62,6 +64,7 @@ export class CommonAzureConstruct extends TerraformStack {
this.keyVaultManager = new AzureKeyVaultManager()
this.logAnalyticsWorkspaceManager = new AzureLogAnalyticsWorkspaceManager()
this.monitorManager = new AzureMonitorManager()
this.redisManager = new AzureRedisManager()
this.resourceGroupManager = new AzureResourceGroupManager()
this.resourceNameFormatter = new AzureResourceNameFormatter(this, `${id}-rnf`, props)
this.servicebusManager = new AzureServicebusManager()
Expand Down
16 changes: 15 additions & 1 deletion src/lib/azure/services/api-management/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
ApiManagementLogger,
ApiManagementLoggerApplicationInsights,
} from '@cdktf/provider-azurerm/lib/api-management-logger'
import { ApiManagementRedisCache } from '@cdktf/provider-azurerm/lib/api-management-redis-cache'
import { RedisCache } from '@cdktf/provider-azurerm/lib/redis-cache'
import { Resource } from '../../.gen/providers/azapi/resource'
import { CommonAzureConstruct } from '../../common'
import { createAzureTfOutput } from '../../utils'
Expand All @@ -20,6 +22,7 @@ import {
ApiManagementBackendProps,
ApiManagementApiProps,
ApiManagementCustomDomainProps,
ApiManagementRedisCacheProps,
} from './types'
import _ from 'lodash'

Expand Down Expand Up @@ -52,7 +55,8 @@ export class AzureApiManagementManager {
id: string,
scope: CommonAzureConstruct,
props: ApiManagementProps,
applicationInsightsKey?: ApiManagementLoggerApplicationInsights['instrumentationKey']
applicationInsightsKey?: ApiManagementLoggerApplicationInsights['instrumentationKey'],
externalRedisCache?: RedisCache
) {
if (!props) throw `Props undefined for ${id}`

Expand Down Expand Up @@ -84,6 +88,16 @@ export class AzureApiManagementManager {
})
}

if (externalRedisCache) {
new ApiManagementRedisCache(scope, `${id}-am-redis-cache`, {
name: scope.resourceNameFormatter.format(props.name, scope.props.resourceNameOptions?.apiManagementRedisCache),
apiManagementId: apiManagement.id,
connectionString: externalRedisCache.primaryConnectionString,
cacheLocation: externalRedisCache.location,
redisCacheId: externalRedisCache.id,
})
}

createAzureTfOutput(`${id}-apiManagementName`, scope, apiManagement.name)
createAzureTfOutput(`${id}-apiManagementFriendlyUniqueId`, scope, apiManagement.friendlyUniqueId)
createAzureTfOutput(`${id}-apiManagementId`, scope, apiManagement.id)
Expand Down
3 changes: 3 additions & 0 deletions src/lib/azure/services/api-management/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ApiManagementBackendConfig } from '@cdktf/provider-azurerm/lib/api-mana
import { ApiManagementCustomDomainConfig } from '@cdktf/provider-azurerm/lib/api-management-custom-domain'
import { ApiManagementApiConfig } from '@cdktf/provider-azurerm/lib/api-management-api'
import { ApiManagementApiOperationConfig } from '@cdktf/provider-azurerm/lib/api-management-api-operation'
import { ApiManagementRedisCacheConfig } from '@cdktf/provider-azurerm/lib/api-management-redis-cache'

export interface ApiManagementProps extends ApiManagementConfig {}

Expand Down Expand Up @@ -35,3 +36,5 @@ export interface ApiManagementApiRateLimit {
calls: number
renewalPeriodInSecs: number
}

export interface ApiManagementRedisCacheProps extends ApiManagementRedisCacheConfig {}
1 change: 1 addition & 0 deletions src/lib/azure/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export * from './function'
export * from './key-vault'
export * from './log-analytics-workspace'
export * from './monitor'
export * from './redis'
export * from './resource-group'
export * from './servicebus'
export * from './storage'
2 changes: 2 additions & 0 deletions src/lib/azure/services/redis/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './main'
export * from './types'
59 changes: 59 additions & 0 deletions src/lib/azure/services/redis/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { DataAzurermResourceGroup } from '@cdktf/provider-azurerm/lib/data-azurerm-resource-group'
import { RedisCache } from '@cdktf/provider-azurerm/lib/redis-cache'
import { CommonAzureConstruct } from '../../common'
import { createAzureTfOutput } from '../../utils'
import { RedisCacheProps } from './types'

/**
* @classdesc Provides operations on Azure Redis
* - A new instance of this class is injected into {@link CommonAzureConstruct} constructor.
* - If a custom construct extends {@link CommonAzureConstruct}, an instance is available within the context.
* @example
* ```
* import { CommonAzureConstruct, CommonAzureStackProps } from '@gradientedge/cdk-utils'
*
* class CustomConstruct extends CommonAzureConstruct {
* constructor(parent: Construct, id: string, props: CommonAzureStackProps) {
* super(parent, id, props)
* this.props = props
* this.redisManager.createRedis('MyRedisCache', this, props)
* }
* }
* ```
*/
export class AzureRedisManager {
/**
* @summary Method to create a new redis cache
* @param id scoped id of the resource
* @param scope scope in which this resource is defined
* @param props redis cache properties
* @see [CDKTF Redis Cache Module]{@link https://github.com/cdktf/cdktf-provider-azurerm/blob/main/docs/redisCache.typescript.md}
*/
public createRedisCache(id: string, scope: CommonAzureConstruct, props: RedisCacheProps) {
if (!props) throw `Props undefined for ${id}`

const resourceGroup = new DataAzurermResourceGroup(scope, `${id}-rc-rg`, {
name: scope.props.resourceGroupName
? scope.resourceNameFormatter.format(scope.props.resourceGroupName)
: `${props.resourceGroupName}`,
})

if (!resourceGroup) throw `Resource group undefined for ${id}`

const redisCache = new RedisCache(scope, `${id}-rc`, {
...props,
name: scope.resourceNameFormatter.format(props.name, scope.props.resourceNameOptions?.redisCache),
location: resourceGroup.location,
resourceGroupName: resourceGroup.name,
tags: props.tags ?? {
environment: scope.props.stage,
},
})

createAzureTfOutput(`${id}-redisCacheName`, scope, redisCache.name)
createAzureTfOutput(`${id}-redisCacheFriendlyUniqueId`, scope, redisCache.friendlyUniqueId)
createAzureTfOutput(`${id}-redisCacheId`, scope, redisCache.id)

return redisCache
}
}
3 changes: 3 additions & 0 deletions src/lib/azure/services/redis/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { RedisCacheConfig } from '@cdktf/provider-azurerm/lib/redis-cache'

export interface RedisCacheProps extends RedisCacheConfig {}
10 changes: 10 additions & 0 deletions src/test/azure/common/cdkConfig/redis.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"testRedisCache": {
"name": "test-redis-cache",
"capacity": 2,
"family": "C",
"skuName": "Basic",
"nonSslPortEnabled": false,
"minimumTlsVersion": "1.2"
}
}
121 changes: 121 additions & 0 deletions src/test/azure/services/redis-manager.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { RedisCache } from '@cdktf/provider-azurerm/lib/redis-cache'
import { App, Testing } from 'cdktf'
import 'cdktf/lib/testing/adapters/jest'
import { Construct } from 'constructs'
import { CommonAzureConstruct, CommonAzureStack, CommonAzureStackProps, RedisCacheProps } from '../../../lib'

interface TestAzureStackProps extends CommonAzureStackProps {
testRedisCache: RedisCacheProps
testAttribute?: string
}

const testStackProps: any = {
domainName: 'gradientedge.io',
extraContexts: ['src/test/azure/common/cdkConfig/dummy.json', 'src/test/azure/common/cdkConfig/redis.json'],
features: {},
name: 'test-common-stack',
resourceGroupName: 'test-rg',
skipStageForARecords: false,
stage: 'dev',
stageContextPath: 'src/test/aws/common/cdkEnv',
}

class TestCommonStack extends CommonAzureStack {
declare props: TestAzureStackProps

constructor(parent: Construct, name: string, props: TestAzureStackProps) {
super(parent, name, testStackProps)
this.construct = new TestCommonConstruct(this, props.name, this.props)
}

protected determineConstructProps(props: CommonAzureStackProps) {
return {
...super.determineConstructProps(props),
testAttribute: this.node.tryGetContext('testAttribute'),
testRedisCache: this.node.tryGetContext('testRedisCache'),
}
}
}

class TestInvalidCommonStack extends CommonAzureStack {
declare props: TestAzureStackProps

constructor(parent: Construct, name: string, props: TestAzureStackProps) {
super(parent, name, props)

this.construct = new TestCommonConstruct(this, testStackProps.name, this.props)
}
}

class TestCommonConstruct extends CommonAzureConstruct {
declare props: TestAzureStackProps

constructor(parent: Construct, name: string, props: TestAzureStackProps) {
super(parent, name, props)
this.redisManager.createRedisCache(`test-redis-cache-${this.props.stage}`, this, this.props.testRedisCache)
}
}

const app = new App({ context: testStackProps })
const testingApp = Testing.fakeCdktfJsonPath(app)
const commonStack = new TestCommonStack(testingApp, 'test-common-stack', testStackProps)
const stack = Testing.fullSynth(commonStack)
const construct = Testing.synth(commonStack.construct)

describe('TestAzureRedisConstruct', () => {
test('handles mis-configurations as expected', () => {
const error = () => new TestInvalidCommonStack(app, 'test-invalid-stack', testStackProps)
expect(error).toThrow('Props undefined for test-redis-cache-dev')
})
})

describe('TestAzureRedisConstruct', () => {
test('is initialised as expected', () => {
/* test if the created stack have the right properties injected */
expect(commonStack.props).toHaveProperty('testAttribute')
expect(commonStack.props.testAttribute).toEqual('success')
})
})

describe('TestAzureRedisConstruct', () => {
test('synthesises as expected', () => {
expect(stack).toBeDefined()
expect(construct).toBeDefined()
expect(stack).toBeValidTerraform()
expect(stack).toPlanSuccessfully()
})
})

describe('TestAzureRedisConstruct', () => {
test('provisions outputs as expected', () => {
expect(JSON.parse(construct).output).toMatchObject({
testRedisCacheDevRedisCacheFriendlyUniqueId: {
value: 'test-redis-cache-dev-rc',
},
testRedisCacheDevRedisCacheId: {
value: '${azurerm_redis_cache.test-redis-cache-dev-rc.id}',
},
testRedisCacheDevRedisCacheName: {
value: '${azurerm_redis_cache.test-redis-cache-dev-rc.name}',
},
})
})
})

describe('TestAzureRedisConstruct', () => {
test('provisions redis cache as expected', () => {
expect(construct).toHaveResourceWithProperties(RedisCache, {
capacity: 2,
family: 'C',
location: '${data.azurerm_resource_group.test-redis-cache-dev-rc-rg.location}',
minimum_tls_version: '1.2',
name: 'test-redis-cache-dev',
non_ssl_port_enabled: false,
resource_group_name: '${data.azurerm_resource_group.test-redis-cache-dev-rc-rg.name}',
sku_name: 'Basic',
tags: {
environment: 'dev',
},
})
})
})
Loading