|  | 
|  | 1 | +import * as cdk from 'aws-cdk-lib'; | 
|  | 2 | +import * as appconfig from 'aws-cdk-lib/aws-appconfig'; | 
|  | 3 | +import * as lambda from 'aws-cdk-lib/aws-lambda'; | 
|  | 4 | +import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch'; | 
|  | 5 | +import { Construct } from 'constructs'; | 
|  | 6 | +import { RustFunction } from 'cargo-lambda-cdk'; | 
|  | 7 | + | 
|  | 8 | +export class CdkStack extends cdk.Stack { | 
|  | 9 | +  constructor(scope: Construct, id: string, props?: cdk.StackProps) { | 
|  | 10 | +    super(scope, id, props); | 
|  | 11 | + | 
|  | 12 | +    // Create AppConfig Application | 
|  | 13 | +    const application = new appconfig.CfnApplication(this, 'MyApplication', { | 
|  | 14 | +      name: 'MyRustLambdaApp', | 
|  | 15 | +    }); | 
|  | 16 | + | 
|  | 17 | +    // Create AppConfig Environment | 
|  | 18 | +    const environment = new appconfig.CfnEnvironment(this, 'MyEnvironment', { | 
|  | 19 | +      applicationId: application.ref, | 
|  | 20 | +      name: 'Production', | 
|  | 21 | +    }); | 
|  | 22 | + | 
|  | 23 | +    // Create AppConfig Configuration Profile | 
|  | 24 | +    const configProfile = new appconfig.CfnConfigurationProfile(this, 'MyConfigProfile', { | 
|  | 25 | +      applicationId: application.ref, | 
|  | 26 | +      name: 'MyConfigProfile', | 
|  | 27 | +      locationUri: 'hosted', | 
|  | 28 | +    }); | 
|  | 29 | + | 
|  | 30 | +    // Create AppConfig Hosted Configuration Version | 
|  | 31 | +    const hostedConfig = new appconfig.CfnHostedConfigurationVersion(this, 'MyHostedConfig', { | 
|  | 32 | +      applicationId: application.ref, | 
|  | 33 | +      configurationProfileId: configProfile.ref, | 
|  | 34 | +      content: JSON.stringify({ | 
|  | 35 | +        'spanish-response': false | 
|  | 36 | +      }), | 
|  | 37 | +      contentType: 'application/json', | 
|  | 38 | +    }); | 
|  | 39 | + | 
|  | 40 | +    // Create AppConfig Deployment Strategy | 
|  | 41 | +    const deploymentStrategy = new appconfig.CfnDeploymentStrategy(this, 'MyDeploymentStrategy', { | 
|  | 42 | +      name: 'MyDeploymentStrategy', | 
|  | 43 | +      deploymentDurationInMinutes: 0, | 
|  | 44 | +      growthFactor: 100, | 
|  | 45 | +      replicateTo: 'NONE', | 
|  | 46 | +    }); | 
|  | 47 | + | 
|  | 48 | +    const architecture = lambda.Architecture.ARM_64; | 
|  | 49 | +    const layerVersion = architecture === lambda.Architecture.ARM_64 ? '68' : '60'; | 
|  | 50 | + | 
|  | 51 | +    // Create Lambda function using cargo-lambda-cdk | 
|  | 52 | +    const myFunction = new RustFunction(this, 'MyRustFunction', { | 
|  | 53 | +      functionName: 'my-rust-lambda', | 
|  | 54 | +      manifestPath: '..', // Points to the parent directory where Cargo.toml is located | 
|  | 55 | +      architecture, | 
|  | 56 | +      memorySize: 128, | 
|  | 57 | +      timeout: cdk.Duration.seconds(30), | 
|  | 58 | +      environment: { | 
|  | 59 | +        APPLICATION_ID: application.ref, | 
|  | 60 | +        ENVIRONMENT_ID: environment.ref, | 
|  | 61 | +        CONFIGURATION_PROFILE_ID: configProfile.ref, | 
|  | 62 | +        AWS_APPCONFIG_EXTENSION_PREFETCH_LIST: `/applications/${application.ref}/environments/${environment.ref}/configurations/${configProfile.ref}`, | 
|  | 63 | +      }, | 
|  | 64 | +      layers: [ | 
|  | 65 | +        lambda.LayerVersion.fromLayerVersionArn( | 
|  | 66 | +          this, | 
|  | 67 | +          'AppConfigExtensionLayer', | 
|  | 68 | +          `arn:aws:lambda:${this.region}:027255383542:layer:AWS-AppConfig-Extension:${layerVersion}` | 
|  | 69 | +        ), | 
|  | 70 | +      ], | 
|  | 71 | +    }); | 
|  | 72 | + | 
|  | 73 | +    // Create CloudWatch Alarm for rollback | 
|  | 74 | +    const errorRateAlarm = new cloudwatch.Alarm(this, 'ErrorRateAlarm', { | 
|  | 75 | +      metric: myFunction.metricErrors({ | 
|  | 76 | +        period: cdk.Duration.minutes(1), | 
|  | 77 | +        statistic: 'sum', | 
|  | 78 | +      }), | 
|  | 79 | +      threshold: 5, | 
|  | 80 | +      evaluationPeriods: 1, | 
|  | 81 | +      comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD, | 
|  | 82 | +      alarmDescription: 'Alarm if the error rate is greater than 5 errors per minute', | 
|  | 83 | +    }); | 
|  | 84 | + | 
|  | 85 | +    // Create AppConfig Deployment with rollback configuration | 
|  | 86 | +    new appconfig.CfnDeployment(this, 'MyDeployment', { | 
|  | 87 | +      applicationId: application.ref, | 
|  | 88 | +      environmentId: environment.ref, | 
|  | 89 | +      deploymentStrategyId: deploymentStrategy.ref, | 
|  | 90 | +      configurationProfileId: configProfile.ref, | 
|  | 91 | +      configurationVersion: hostedConfig.ref, | 
|  | 92 | +      tags: [ | 
|  | 93 | +        { | 
|  | 94 | +          key: 'RollbackTrigger', | 
|  | 95 | +          value: errorRateAlarm.alarmArn, | 
|  | 96 | +        }, | 
|  | 97 | +      ], | 
|  | 98 | +    }); | 
|  | 99 | + | 
|  | 100 | +    // Grant AppConfig permissions to the Lambda function | 
|  | 101 | +    myFunction.addToRolePolicy(new cdk.aws_iam.PolicyStatement({ | 
|  | 102 | +      actions: [ | 
|  | 103 | +        'appconfig:GetConfiguration', | 
|  | 104 | +        'appconfig:StartConfigurationSession', | 
|  | 105 | +        'cloudwatch:PutMetricData', | 
|  | 106 | +      ], | 
|  | 107 | +      resources: ['*'], | 
|  | 108 | +    })); | 
|  | 109 | +  } | 
|  | 110 | +} | 
0 commit comments