While playing around with RestateCloudEnvironment, a lambda function, and ServiceDeployer, I had issues with IAM's eventual consistency. The lambda:InvokeFunction permission sometimes takes a while to propagate. Therefore I switched to attribute-based access control (ABAC) and that worked without issues.
While you might not want to add direct support for ABAC to this repo, maybe you want to mention it somewhere in your documentation.
Code
Note that AWS' documentation tags both the principal and the resource. To keep it a bit simpler (and because it's an inline policy) I opted to only tag the lambda function(s).
```ts
const environment = new RestateCloudEnvironment(…);
environment.invokerRole.attachInlinePolicy(new iam.Policy(this, "RestateInvokerPolicy", {
statements: [
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ["lambda:InvokeFunction"],
resources: [this.formatArn({
partition: cdk.Aws.PARTITION,
account: cdk.Aws.ACCOUNT_ID,
region: cdk.Aws.REGION,
service: 'lambda',
resource: 'function:*'
})],
conditions: {
'StringEquals': {
'aws:ResourceTag/RestateInvokeable': ['true'],
},
},
})
]
}));
const dummy = new NodejsFunction(this, 'DummyService', { … });
cdk.Tags.of(greeter).add('RestateInvokeable', 'true', {
includeResourceTypes: ['AWS::Lambda::Function'],
});
deployer.deployService("Dummy", dummycurrentVersion, environment, {
skipInvokeFunctionGrant: true
});
```
(In our case the `RestateCloudEnvironment` lives in its own stack and is shared. Therefore the `invokerRole` is deployed long before the first call to `deployer.deployService()`. The code snippet doesn't show that.)
While playing around with
RestateCloudEnvironment
, a lambda function, andServiceDeployer
, I had issues with IAM's eventual consistency. Thelambda:InvokeFunction
permission sometimes takes a while to propagate. Therefore I switched to attribute-based access control (ABAC) and that worked without issues.While you might not want to add direct support for ABAC to this repo, maybe you want to mention it somewhere in your documentation.
Code
Note that AWS' documentation tags both the principal and the resource. To keep it a bit simpler (and because it's an inline policy) I opted to only tag the lambda function(s). ```ts const environment = new RestateCloudEnvironment(…); environment.invokerRole.attachInlinePolicy(new iam.Policy(this, "RestateInvokerPolicy", { statements: [ new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ["lambda:InvokeFunction"], resources: [this.formatArn({ partition: cdk.Aws.PARTITION, account: cdk.Aws.ACCOUNT_ID, region: cdk.Aws.REGION, service: 'lambda', resource: 'function:*' })], conditions: { 'StringEquals': { 'aws:ResourceTag/RestateInvokeable': ['true'], }, }, }) ] })); const dummy = new NodejsFunction(this, 'DummyService', { … }); cdk.Tags.of(greeter).add('RestateInvokeable', 'true', { includeResourceTypes: ['AWS::Lambda::Function'], }); deployer.deployService("Dummy", dummycurrentVersion, environment, { skipInvokeFunctionGrant: true }); ``` (In our case the `RestateCloudEnvironment` lives in its own stack and is shared. Therefore the `invokerRole` is deployed long before the first call to `deployer.deployService()`. The code snippet doesn't show that.)Here are some links: