Proper way to create CDK script to create an App Runner service connected to a Github repo

0

I'm trying to deploy an App Runner service with AWS CDK that is connected to a Github repo, and auto deploys the code in that repo every time a change is made to the code within it. I was looking at the AWS CDK documentation, and I used the example provided here: https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apprunner.CfnService.html

In my code, I am creating an App Runner IAM role that has the permissions to query AWS secrets manager. I am then creating a wait condition to wait until the IAM role has been created, and then connect ingthe Access Role ARN of the newly created App Runner IAM role to the App Runner service that I am creating after the IAM role.

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as apprunner from 'aws-cdk-lib/aws-apprunner'
import * as iam from 'aws-cdk-lib/aws-iam';

export class CdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);


    // Create an IAM role for App runner
    const appRunnerRole = new iam.Role(this, 'AppRunnerRoleTesting', {
      assumedBy: new iam.ServicePrincipal('apprunner.amazonaws.com'),
    });


    // Attach the AWSAppRunnerServicePolicy managed policy
    appRunnerRole.attachInlinePolicy(new iam.Policy(this, 'AWSAppRunnerServicePolicy', {
      statements: [new iam.PolicyStatement({
        actions: [
          "apprunner:DescribeService",
          "secretsmanager:GetRandomPassword",
          "secretsmanager:GetResourcePolicy",
          "secretsmanager:GetSecretValue",
          "secretsmanager:DescribeSecret",
          "secretsmanager:ListSecretVersionIds",
          "secretsmanager:ListSecrets",
          "secretsmanager:BatchGetSecretValue"],
        resources: ['*'],
      })],
    }));


    // Output the IAM role ARNc
    new cdk.CfnOutput(this, 'AppRunnerRoleArn', {
      value: appRunnerRole.roleArn,
    });

    
    // Create a Wait Condition Handle to signal the completion of IAM role creation
    const waitConditionHandle = new cdk.CfnWaitConditionHandle(this, 'WaitConditionHandle');


    // Create a Wait Condition to wait for IAM role creation completion    
    const waitCondition = new cdk.CfnWaitCondition(this, 'WaitCondition', {
      count: 0,
      handle: waitConditionHandle.ref,
      timeout: '120', // Adjust as needed
    });
    

    // Signal the Wait Condition when the IAM role creation is complete
    appRunnerRole.node.addDependency(waitCondition);
    

    
    // Create the App Runner service
    const cfnService = new apprunner.CfnService(this, 'MyCfnService', {
      sourceConfiguration: {
        authenticationConfiguration: {
          accessRoleArn: appRunnerRole.roleArn,
        },
        autoDeploymentsEnabled: true,
        codeRepository: {
          repositoryUrl: 'https://github.com/mygitrepo',
          sourceCodeVersion: {
            type: 'BRANCH',
            value: 'main',
          },
    
          // the properties below are optional
          codeConfiguration: {
            configurationSource: 'REPOSITORY',
    
            // the properties below are optional
            codeConfigurationValues: {
              runtime: 'NODEJS_16',
    
              // the properties below are optional
              buildCommand: 'npm install',
              port: 'port',
              runtimeEnvironmentSecrets: [{
                name: 'name',
                value: 'value',
              }],
              runtimeEnvironmentVariables: [{
                name: 'name',
                value: 'value',
              }],
              startCommand: 'node app.js',
              
            },
          },
        },
      },
    
      // the properties below are optional
      instanceConfiguration: {
        cpu: '256',
        instanceRoleArn: appRunnerRole.roleArn,
        memory: '512',
      },
      
      networkConfiguration: {
        ingressConfiguration: {
          isPubliclyAccessible: true,
        },
        ipAddressType: 'IPV4',
      },
      
      serviceName: 'serviceName',
      tags: [{
        key: 'key',
        value: 'value',
      }],
    });
     


    cfnService.node.addDependency(appRunnerRole);

  }
}

Note that I've redacted the Github repo for the "repositoryUrl" field for the App Runner service. But when I try to run this via "cdk deploy", I keep getting this error:

Do you wish to deploy these changes (y/n)? y
CdkStack: deploying... [1/1]
CdkStack: creating CloudFormation changeset...
8:51:02 AM | CREATE_FAILED        | AWS::AppRunner::Service                  | MyCfnService
Resource handler returned message: "Error in assuming access role arn:aws:iam::<REDACTED>:role/CdkStack-AppRunnerRoleTestingEE644DF4-aM6ZIsSrivEy (Service: AppRunner, Status Code: 400, Request ID: <REDACTED>)" (RequestToken: <REDACTED>, HandlerErrorCode: InvalidRequest)

Enter image description here

Is there any workaround for this error? Or was there a better way to create an AWS App Runner service using AWS CDK?

Thanks in advance!

2 Answers
0

Hello there,

I see that you are getting “Resource handler returned message: "Error in assuming access role arn:aws:iam::<REDACTED>:role/CdkStack-AppRunnerRoleTestingEE644DF4-aM6ZIsSrivEy” when creating AppRunner service using CDK Code.

Looking at the error it seems that issue with AppRunner trust relationship policy. While taking look at your code, I see that you are using trust related policy as like this:


// Create an IAM role for App runner
const appRunnerRole = new iam.Role(this, 'AppRunnerRoleTesting', {
  assumedBy: new iam.ServicePrincipal('apprunner.amazonaws.com'),
});

However, according to the AWS AppRuner document[1], trust relationship should below look like this.


// Create an IAM role for App runner
const appRunnerRole = new iam.Role(this, 'AppRunnerRoleTesting', {
  assumedBy: new iam.ServicePrincipal('build.apprunner.amazonaws.com'),
});

Here it is how the IAM role trust relationship policy looks like in IAM console.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "build.apprunner.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Thus, I would humbly request you to please modify the code to add correct trust relationship policy and try to deploy. However, if you are still getting errors, I kindly request you to please reach out to our CDK team via AWS support case for further guidance on the same.

However, I have also found other way to create AppRunner service using CDK, mentioned in the article[2] and git hub link[3]. I kindly request you to please refer the same.

Thank you

References:

[1] https://docs.aws.amazon.com/apprunner/latest/dg/security_iam_service-with-iam.html#security_iam_service-with-iam-roles

[2] https://aws.amazon.com/getting-started/guides/deploy-webapp-apprunner/module-one/

[3] https://github.com/aws-samples/aws-apprunner-cdk

AWS
SUPPORT ENGINEER
answered 4 months ago
profile picture
EXPERT
reviewed 23 days ago
  • Hi Vaikiri,

    Thanks for reaching out.

    I made the changes to the code, but I'm still getting this error. I will go ahead and submit a support case with the CDK team.

0

Hi Vaikiri,

Thanks for reaching out.

I made the changes to the code, but I'm still getting this error. I will go ahead and submit a support case with the CDK team.

ziakq
answered 3 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions