The short answer is you are going to have to use a Lambda to use HTTP requests against your cluster do to this after the cluster has been created.
The long answer is you can use can use a CDK Custom Resource as part of your CDK implementation. A Custom Resource needs a Provider to execute. In this case our Provider will be the Lambda I mentioned before.
From this Lambda we can do anything we want in an async manner including do any HTTP requests.
All of this is tied to your CDK deployment by the Custom Resource & Provider. This means that if you HTTP request fails (or whatever you choose to do) You can signal that CDK should rollback all of your changes.
Basically it's a nice way to tie distributed transactions into your stack creation.
What I use this for is to run any number of configurations against the cluster just after it is created. If any of them fail the whole thing rolls back.
I have a terribly named construct to orchestrate the requests:
(take special note of requests: props.requests
)
export class Configurator extends Construct {
constructor(scope: Construct, id: string, props: ConfiguratorProps) {
super(scope, id);
const configuratorLambda = new NodejsFunction(this, 'ConfiguratorLambda', {
securityGroups: [props.securityGroup],
vpc: props.vpc,
runtime: Runtime.NODEJS_18_X,
handler: 'handler',
role: props.role,
entry: path.join(__dirname, '../../src/configurator-lambda.ts'),
timeout: Duration.seconds(30),
environment: {
DOMAIN: props.domain.domainEndpoint,
},
});
const configuratorProvider = new Provider(this, 'ConfiguratorProvider', {
onEventHandler: configuratorLambda,
});
const customResource = new CustomResource(
this,
'ConfiguratorCustomResource',
{
serviceToken: configuratorProvider.serviceToken,
properties: {
requests: props.requests,
},
},
);
}
}
Then from my stack I use it like this - as you noted previously the requests are passed on to the Lambda as an argument in the Configurator code.
new Configurator(this, 'Configurator', {
stage,
vpc,
securityGroup: inboundSecurityGroup,
role: adminFnRole,
domain,
requests: [
{
method: 'PUT',
path: '/sample-index1',
body: {
},
},
{
method: 'PUT',
path: '/_plugins/_security/api/rolesmapping/all_access',
body: {
users: [
'username',
'other-username'
].filter(Boolean),
},
},
],
});
I won't put the lambda code in for brevity but you just use fetch
or something to execute the request against the cluster. Make sure you handle errors and deal with appropriately.
From the Lambda you also need to explicitly respond correctly so that CDK can correctly interpret success or failure.
Here is a good example of the Lambda implementation which you can modify.