How does one add a Role to a function when using `...
# help
d
How does one add a Role to a function when using
Api
? I see the permissions but I can’t seem to figure out how that can translate to something like this…
Need Trust Policy too
assumedBy
A PolicyStatement used in an identity-based policy cannot specify any IAM principals.
is what SST is giving me now with…
Copy code
const api = new sst.Api(this, 'Api', {
      defaultFunctionProps: {
        timeout: 20,
      },
      routes: {
        'GET /callback': 'src/lambda.callback',
        'GET /install': 'src/lambda.install',
        'GET /webhook': {
          function: {
            handler: 'src/lambda.install',
            permissions: [
              new iam.PolicyStatement({
                actions: ['events:PutEvents'],
                effect: iam.Effect.ALLOW,
                principals: [new iam.ServicePrincipal('<http://apigateway.amazonaws.com|apigateway.amazonaws.com>')],
                resources: [`arn:aws:events:${region}:${account}:event-bus/default`],
              }),
            ],
          },
        },
      },
    })
t
I believe there's a function.role field
that you can pass an
iam.Role
to
d
If I do that, I assume it till overrite SST’s default role which will remove the Log policy?
t
I believe we always add the log policy directly
d
oh ya? so it would be redundant for me to add to role?
t
Wait sorry which Log policy are you referring to?
I can't find the code right now but I vaguely remember us adding log permissions directly to the lambda
d
Copy code
const webhookRole = new iam.Role(this, 'request-lambda-role', {
      assumedBy: new iam.ServicePrincipal('<http://apigateway.amazonaws.com|apigateway.amazonaws.com>'),
      inlinePolicies: {
        AllowLambdaServiceToAssumeRole: new iam.PolicyDocument({
          statements: [
            new iam.PolicyStatement({
              effect: iam.Effect.ALLOW,
              actions: [
                'logs:CreateLogGroup',
                'logs:CreateLogStream',
                'logs:PutLogEvents',
                'logs:DescribeLogStreams',
              ],
              resources: ['arn:aws:logs:*:*:*'],
            }),
            new iam.PolicyStatement({
              actions: ['events:PutEvents'],
              effect: iam.Effect.ALLOW,
              resources: [`arn:aws:events:${region}:${account}:event-bus/default`],
            }),
          ],
        }),
      },
    })
or is this fine…
Copy code
const webhookRole = new iam.Role(this, 'request-lambda-role', {
      assumedBy: new iam.ServicePrincipal('<http://apigateway.amazonaws.com|apigateway.amazonaws.com>'),
      inlinePolicies: {
        AllowLambdaServiceToAssumeRole: new iam.PolicyDocument({
          statements: [
            new iam.PolicyStatement({
              actions: ['events:PutEvents'],
              effect: iam.Effect.ALLOW,
              resources: [`arn:aws:events:${region}:${account}:event-bus/default`],
            }),
          ],
        }),
      },
    })
t
I think the latter should be fine but you should give it a try and see
d
kk…. seems odd that SST would extend an explicit role.
t
There's ways to add policies to the function directly and not through the role
But I need to verify what I'm saying
d
nw…. ya very interested. I’m hazy on what is possible there
t
The reason I think this should work is I was overriding a role myself and didn't see any issues with logs
d
i’ll report back
t
I'm realizing the reason I don't see this functionality in the sst codebase is because it happens in the cdk codebase
d
oh.. even better.
t
Oh wait
Copy code
this.role.addManagedPolicy(
      iam.ManagedPolicy.fromAwsManagedPolicyName(
        "service-role/AWSLambdaBasicExecutionRole"
      )
    )
I added this to my role
Which has the logs permissions
d
ah
t
Also instead of creating a new role you can also add policies to the autocreated role
Copy code
function: {
  permissions: [  new iam.PolicyStatement({...}) ]
}
d
how do you add “assumeby” though
Trust Policy
I need both…
Copy code
assumedBy: new iam.CompositePrincipal(
        new iam.ServicePrincipal('<http://lambda.amazonaws.com|lambda.amazonaws.com>'),
        new iam.ServicePrincipal('<http://apigateway.amazonaws.com|apigateway.amazonaws.com>'),
      ),
      inlinePolicies: {
        AllowLambdaServiceToAssumeRole: new iam.PolicyDocument({
          statements: [
            new iam.PolicyStatement({
              actions: ['events:PutEvents'],
              effect: iam.Effect.ALLOW,
              resources: [`arn:aws:events:${region}:${account}:event-bus/default`],
            }),
          ],
        }),
      },
t
ah ok I think then you do need a role
d
hmmm…. actually… I think I’m dense…. that assumeBy was old from when I was using service integration
t
Although in this case for the function you wouldn't need the assumedBy -> lambda right
d
doh
sorry… I just wasted about 1hr on that
🤦‍♂️