diff --git a/apprunner-cdk-dotnet/.gitignore b/apprunner-cdk-dotnet/.gitignore new file mode 100644 index 000000000..a4609e758 --- /dev/null +++ b/apprunner-cdk-dotnet/.gitignore @@ -0,0 +1,342 @@ +# CDK asset staging directory +.cdk.staging +cdk.out + +# Created by https://www.gitignore.io/api/csharp + +### Csharp ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + + +# End of https://www.gitignore.io/api/csharp \ No newline at end of file diff --git a/apprunner-cdk-dotnet/README.md b/apprunner-cdk-dotnet/README.md new file mode 100644 index 000000000..deb6a417d --- /dev/null +++ b/apprunner-cdk-dotnet/README.md @@ -0,0 +1,60 @@ +# AWS AppRunner: Deploying Web APIs with CDK + +The CDK stack that creates an AWS App Runner service to deploy a .NET web API application. + +Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/apprunner-cdk-dotnet + +Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. + +## Requirements + +* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. +* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured +* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +* [.NET 6](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) installed +* [AWS Cloud Development Kit](https://docs.aws.amazon.com/cdk/latest/guide/cli.html) (AWS CDK) installed +* [Docker](https://docs.docker.com/engine/install/) installed + +## Deployment Instructions for Windows + +1. Clone the project to your local working directory + ``` + git clone https://github.com/aws-samples/serverless-patterns + ``` +2. Change the working directory to this pattern's directory + ``` + cd apprunner-cdk-dotnet\src\DemoApplication.API + ``` +3. Build the application + ``` + dotnet build + ``` +4. Return to root level folder back to the path `apprunner-cdk-dotnet` + ``` + cd ..\.. + ``` +5. Deploy the stack to your default AWS account and region. + ``` + cdk deploy + ``` + +## Testing + +1. After deployment, the output shows the App Runner Service URL, for example: `ApprunnerCdkDotnetStack.AppRunnerServiceURL = https://..awsapprunner.com` +2. Copy this URL and append `WeatherForecast`, the URL will look like this: `https://..awsapprunner.com/weatherforecast` +3. Enter this URL into your browser, you should receive a JSON response with weather information. + +``` +[{"date":"2024-01-09T10:21:16.4618292+00:00","temperatureC":30,"temperatureF":85,"summary":"Chilly"},{"date":"2024-01-10T10:21:16.4618407+00:00","temperatureC":13,"temperatureF":55,"summary":"Mild"}] +``` + +## Cleanup +Run the given command to delete the resources that were created. It might take some time for the CloudFormation stack to get deleted. +``` +cdk destroy +``` + +---- +Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +SPDX-License-Identifier: MIT-0 \ No newline at end of file diff --git a/apprunner-cdk-dotnet/apprunner-cdk-dotnet.json b/apprunner-cdk-dotnet/apprunner-cdk-dotnet.json new file mode 100644 index 000000000..76c19f758 --- /dev/null +++ b/apprunner-cdk-dotnet/apprunner-cdk-dotnet.json @@ -0,0 +1,66 @@ +{ + "title": "AWS AppRunner API Deployment", + "description": "The CDK stack that creates an AWS App Runner service to deploy a .NET Web API application.", + "language": ".NET", + "level": "200", + "framework": "CDK", + "introBox": { + "headline": "How it works", + "text": [ + "The pattern shows how to use an AWS App Runner service to deploy a .NET Web API application. App Runner eliminates the need to manage servers, containers, or clusters. Simply provide your code or container image, and App Runner handles the rest, making it ideal for developers who want to focus on their application logic." + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/apprunner-cdk-dotnet", + "projectFolder": "apprunner-cdk-dotnet", + "readmeURL": "https://github.com/aws-samples/serverless-patterns/tree/main/apprunner-cdk-dotnet/README.md", + "templateURL": "serverless-patterns/apprunner-cdk-dotnet", + "templateFile": "src/ApprunnerCdkDotnet/ApprunnerCdkDotnetStack.cs" + } + }, + "resources": { + "bullets": [ + { + "text": "AWS App Runner", + "link": "https://docs.aws.amazon.com/apprunner/latest/dg/what-is-apprunner.html" + }, + { + "text": "AppRunner Construct Library", + "link": "https://docs.aws.amazon.com/cdk/api/v2/dotnet/api/Amazon.CDK.AWS.AppRunner.Alpha.html" + } + ] + }, + "deploy": { + "text": [ + "cdk deploy" + ] + }, + "testing": { + "text": [ + "See the Github repo for detailed testing instructions." + ] + }, + "cleanup": { + "text": [ + "Delete the stack: cdk destroy." + ] + }, + "authors": [ + { + "name": "Sanjay Chaudhari", + "image": "https://avatars.githubusercontent.com/u/9101436?v=4", + "bio": "Application Development Consultant at AWS Professional Services.", + "linkedin": "sanjay-chaudhari-it", + "twitter": "sanjaypc" + } + ], + "patternArch": { + "icon1": { + "x": 50, + "y": 50, + "service": "apprunner", + "label": "AWS App Runner" + } + } +} diff --git a/apprunner-cdk-dotnet/cdk.json b/apprunner-cdk-dotnet/cdk.json new file mode 100644 index 000000000..6148fc444 --- /dev/null +++ b/apprunner-cdk-dotnet/cdk.json @@ -0,0 +1,62 @@ +{ + "app": "dotnet run --project src/ApprunnerCdkDotnet/ApprunnerCdkDotnet.csproj", + "watch": { + "include": [ + "**" + ], + "exclude": [ + "README.md", + "cdk*.json", + "src/*/obj", + "src/*/bin", + "src/*.sln", + "src/*/GlobalSuppressions.cs", + "src/*/*.csproj" + ] + }, + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": [ + "aws", + "aws-cn" + ], + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, + "@aws-cdk/aws-iam:minimizePolicies": true, + "@aws-cdk/core:validateSnapshotRemovalPolicy": true, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, + "@aws-cdk/core:enablePartitionLiterals": true, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, + "@aws-cdk/aws-iam:standardizedServicePrincipals": true, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, + "@aws-cdk/aws-route53-patters:useCertificate": true, + "@aws-cdk/customresources:installLatestAwsSdkDefault": false, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, + "@aws-cdk/aws-efs:denyAnonymousAccess": true, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true + } +} diff --git a/apprunner-cdk-dotnet/example-pattern.json b/apprunner-cdk-dotnet/example-pattern.json new file mode 100644 index 000000000..661542d45 --- /dev/null +++ b/apprunner-cdk-dotnet/example-pattern.json @@ -0,0 +1,58 @@ +{ + "title": "AWS AppRunner API Deployment", + "description": "The CDK stack that creates an AWS App Runner service to deploy a .NET Web API application.", + "language": ".NET", + "level": "200", + "framework": "CDK", + "introBox": { + "headline": "How it works", + "text": [ + "The pattern shows how to use an AWS App Runner service to deploy a .NET Web API application. App Runner eliminates the need to manage servers, containers, or clusters. Simply provide your code or container image, and App Runner handles the rest, making it ideal for developers who want to focus on their application logic." + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/apprunner-cdk-dotnet", + "projectFolder": "apprunner-cdk-dotnet", + "readmeURL": "https://github.com/aws-samples/serverless-patterns/tree/main/apprunner-cdk-dotnet/README.md", + "templateURL": "serverless-patterns/apprunner-cdk-dotnet", + "templateFile": "src/ApprunnerCdkDotnet/ApprunnerCdkDotnetStack.cs" + } + }, + "resources": { + "bullets": [ + { + "text": "AWS App Runner", + "link": "https://docs.aws.amazon.com/apprunner/latest/dg/what-is-apprunner.html" + }, + { + "text": "AppRunner Construct Library", + "link": "https://docs.aws.amazon.com/cdk/api/v2/dotnet/api/Amazon.CDK.AWS.AppRunner.Alpha.html" + } + ] + }, + "deploy": { + "text": [ + "cdk deploy" + ] + }, + "testing": { + "text": [ + "See the Github repo for detailed testing instructions." + ] + }, + "cleanup": { + "text": [ + "Delete the stack: cdk destroy." + ] + }, + "authors": [ + { + "name": "Sanjay Chaudhari", + "image": "https://avatars.githubusercontent.com/u/9101436?v=4", + "bio": "Application Development Consultant at AWS Professional Services.", + "linkedin": "sanjay-chaudhari-it", + "twitter": "sanjaypc" + } + ] +} \ No newline at end of file diff --git a/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet.sln b/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet.sln new file mode 100644 index 000000000..af518790f --- /dev/null +++ b/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApprunnerCdkDotnet", "ApprunnerCdkDotnet\ApprunnerCdkDotnet.csproj", "{6E15BAAB-8188-4D13-9B96-4F2AA40D17DE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6E15BAAB-8188-4D13-9B96-4F2AA40D17DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E15BAAB-8188-4D13-9B96-4F2AA40D17DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E15BAAB-8188-4D13-9B96-4F2AA40D17DE}.Debug|x64.ActiveCfg = Debug|Any CPU + {6E15BAAB-8188-4D13-9B96-4F2AA40D17DE}.Debug|x64.Build.0 = Debug|Any CPU + {6E15BAAB-8188-4D13-9B96-4F2AA40D17DE}.Debug|x86.ActiveCfg = Debug|Any CPU + {6E15BAAB-8188-4D13-9B96-4F2AA40D17DE}.Debug|x86.Build.0 = Debug|Any CPU + {6E15BAAB-8188-4D13-9B96-4F2AA40D17DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E15BAAB-8188-4D13-9B96-4F2AA40D17DE}.Release|Any CPU.Build.0 = Release|Any CPU + {6E15BAAB-8188-4D13-9B96-4F2AA40D17DE}.Release|x64.ActiveCfg = Release|Any CPU + {6E15BAAB-8188-4D13-9B96-4F2AA40D17DE}.Release|x64.Build.0 = Release|Any CPU + {6E15BAAB-8188-4D13-9B96-4F2AA40D17DE}.Release|x86.ActiveCfg = Release|Any CPU + {6E15BAAB-8188-4D13-9B96-4F2AA40D17DE}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet/ApprunnerCdkDotnet.csproj b/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet/ApprunnerCdkDotnet.csproj new file mode 100644 index 000000000..6d5709b72 --- /dev/null +++ b/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet/ApprunnerCdkDotnet.csproj @@ -0,0 +1,21 @@ + + + + Exe + net6.0 + + Major + + + + + + + + + + + + diff --git a/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet/ApprunnerCdkDotnetStack.cs b/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet/ApprunnerCdkDotnetStack.cs new file mode 100644 index 000000000..3962a712f --- /dev/null +++ b/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet/ApprunnerCdkDotnetStack.cs @@ -0,0 +1,55 @@ +using Amazon.CDK; +using Amazon.CDK.AWS.AppRunner.Alpha; +using Amazon.CDK.AWS.Ecr.Assets; +using Amazon.CDK.AWS.IAM; +using Constructs; + +namespace ApprunnerCdkDotnet +{ + public class ApprunnerCdkDotnetStack : Stack + { + public ApprunnerCdkDotnetStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) + { + // Define Docker image asset for the AppRunner service + var appRunnerContainerImage = new DockerImageAsset(this, "ApplicationImageAsset", new DockerImageAssetProps + { + Directory = "./src/DemoApplication.API" + }); + + // Create a role for the AppRunner service + var appRunnerServiceRole = new Role(this, "AppRunnerServiceRole", new RoleProps() + { + AssumedBy = new ServicePrincipal("build.apprunner.amazonaws.com") + }); + + // Create a role for AppRunner instances + var appRunnerInstanceRole = new Role(this, "AppRunnerInstanceRole", new RoleProps() + { + AssumedBy = new ServicePrincipal("tasks.apprunner.amazonaws.com") + }); + + // Define the AppRunner service + var appRunnerService = new Service(this, "AppRunnerService", new ServiceProps + { + ServiceName = "dotnet-webapi-apprunner-service", + Source = Source.FromAsset(new AssetProps + { + ImageConfiguration = new ImageConfiguration { Port = 80 }, + Asset = appRunnerContainerImage + }), + + Cpu = Cpu.ONE_VCPU, + Memory = Memory.TWO_GB, + AccessRole = appRunnerServiceRole, + InstanceRole = appRunnerInstanceRole, + AutoDeploymentsEnabled = true + }); + + // Output the AppRunner service URL + new CfnOutput(this, "AppRunnerServiceURL", new CfnOutputProps + { + Value = $"https://{appRunnerService.ServiceUrl}" + }); + } + } +} \ No newline at end of file diff --git a/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet/GlobalSuppressions.cs b/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet/GlobalSuppressions.cs new file mode 100644 index 000000000..26233fcb5 --- /dev/null +++ b/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet/GlobalSuppressions.cs @@ -0,0 +1 @@ +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Potential Code Quality Issues", "RECS0026:Possible unassigned object created by 'new'", Justification = "Constructs add themselves to the scope in which they are created")] diff --git a/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet/Program.cs b/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet/Program.cs new file mode 100644 index 000000000..ffb17ca05 --- /dev/null +++ b/apprunner-cdk-dotnet/src/ApprunnerCdkDotnet/Program.cs @@ -0,0 +1,41 @@ +using Amazon.CDK; + +namespace ApprunnerCdkDotnet +{ + sealed class Program + { + public static void Main(string[] args) + { + var app = new App(); + new ApprunnerCdkDotnetStack(app, "ApprunnerCdkDotnetStack", new StackProps + { + // If you don't specify 'env', this stack will be environment-agnostic. + // Account/Region-dependent features and context lookups will not work, + // but a single synthesized template can be deployed anywhere. + + // Uncomment the next block to specialize this stack for the AWS Account + // and Region that are implied by the current CLI configuration. + /* + Env = new Amazon.CDK.Environment + { + Account = System.Environment.GetEnvironmentVariable("CDK_DEFAULT_ACCOUNT"), + Region = System.Environment.GetEnvironmentVariable("CDK_DEFAULT_REGION"), + } + */ + + // Uncomment the next block if you know exactly what Account and Region you + // want to deploy the stack to. + /* + Env = new Amazon.CDK.Environment + { + Account = "123456789012", + Region = "us-east-1", + } + */ + + // For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html + }); + app.Synth(); + } + } +} diff --git a/apprunner-cdk-dotnet/src/DemoApplication.API/.dockerignore b/apprunner-cdk-dotnet/src/DemoApplication.API/.dockerignore new file mode 100644 index 000000000..fe1152bdb --- /dev/null +++ b/apprunner-cdk-dotnet/src/DemoApplication.API/.dockerignore @@ -0,0 +1,30 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md +!**/.gitignore +!.git/HEAD +!.git/config +!.git/packed-refs +!.git/refs/heads/** \ No newline at end of file diff --git a/apprunner-cdk-dotnet/src/DemoApplication.API/Controllers/WeatherForecastController.cs b/apprunner-cdk-dotnet/src/DemoApplication.API/Controllers/WeatherForecastController.cs new file mode 100644 index 000000000..5aeb388d3 --- /dev/null +++ b/apprunner-cdk-dotnet/src/DemoApplication.API/Controllers/WeatherForecastController.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; + +namespace DemoApplication.API.Controllers +{ + [ApiController] + [Route("[controller]")] + public class WeatherForecastController : ControllerBase + { + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet] + public IEnumerable Get() + { + return Enumerable.Range(1, 2).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } + } +} diff --git a/apprunner-cdk-dotnet/src/DemoApplication.API/DemoApplication.API.csproj b/apprunner-cdk-dotnet/src/DemoApplication.API/DemoApplication.API.csproj new file mode 100644 index 000000000..ad2fdc215 --- /dev/null +++ b/apprunner-cdk-dotnet/src/DemoApplication.API/DemoApplication.API.csproj @@ -0,0 +1,16 @@ + + + + net6.0 + enable + enable + 0184ec82-c0d0-49e2-a657-82d5d9b36cbf + Linux + . + + + + + + + diff --git a/apprunner-cdk-dotnet/src/DemoApplication.API/DemoApplication.API.sln b/apprunner-cdk-dotnet/src/DemoApplication.API/DemoApplication.API.sln new file mode 100644 index 000000000..475775a97 --- /dev/null +++ b/apprunner-cdk-dotnet/src/DemoApplication.API/DemoApplication.API.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoApplication.API", "DemoApplication.API.csproj", "{2FD76002-0515-4208-88C3-5668846117B8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2FD76002-0515-4208-88C3-5668846117B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2FD76002-0515-4208-88C3-5668846117B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2FD76002-0515-4208-88C3-5668846117B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2FD76002-0515-4208-88C3-5668846117B8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E114F706-0092-44BA-B8A2-496C31216875} + EndGlobalSection +EndGlobal diff --git a/apprunner-cdk-dotnet/src/DemoApplication.API/Dockerfile b/apprunner-cdk-dotnet/src/DemoApplication.API/Dockerfile new file mode 100644 index 000000000..1ea4a177c --- /dev/null +++ b/apprunner-cdk-dotnet/src/DemoApplication.API/Dockerfile @@ -0,0 +1,24 @@ +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["DemoApplication.API.csproj", "."] +RUN dotnet restore "./././DemoApplication.API.csproj" +COPY . . +WORKDIR "/src/." +RUN dotnet build "./DemoApplication.API.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./DemoApplication.API.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "DemoApplication.API.dll"] \ No newline at end of file diff --git a/apprunner-cdk-dotnet/src/DemoApplication.API/Program.cs b/apprunner-cdk-dotnet/src/DemoApplication.API/Program.cs new file mode 100644 index 000000000..65d7166c3 --- /dev/null +++ b/apprunner-cdk-dotnet/src/DemoApplication.API/Program.cs @@ -0,0 +1,27 @@ +namespace DemoApplication.API +{ + public class Program + { + public static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + + // Add services to the container. + + builder.Services.AddControllers(); + + var app = builder.Build(); + + // Configure the HTTP request pipeline. + + app.UseHttpsRedirection(); + + app.UseAuthorization(); + + + app.MapControllers(); + + app.Run(); + } + } +} diff --git a/apprunner-cdk-dotnet/src/DemoApplication.API/Properties/launchSettings.json b/apprunner-cdk-dotnet/src/DemoApplication.API/Properties/launchSettings.json new file mode 100644 index 000000000..c7b1ec662 --- /dev/null +++ b/apprunner-cdk-dotnet/src/DemoApplication.API/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "profiles": { + "DemoApplication.API": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "weatherforecast", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7260;http://localhost:5257" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "weatherforecast", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/weatherforecast", + "environmentVariables": { + "ASPNETCORE_URLS": "https://+:443;http://+:80" + }, + "publishAllPorts": true, + "useSSL": true + } + }, + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:16387", + "sslPort": 44322 + } + } +} \ No newline at end of file diff --git a/apprunner-cdk-dotnet/src/DemoApplication.API/WeatherForecast.cs b/apprunner-cdk-dotnet/src/DemoApplication.API/WeatherForecast.cs new file mode 100644 index 000000000..3a4a712cb --- /dev/null +++ b/apprunner-cdk-dotnet/src/DemoApplication.API/WeatherForecast.cs @@ -0,0 +1,13 @@ +namespace DemoApplication.API +{ + public class WeatherForecast + { + public DateTime Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string? Summary { get; set; } + } +} diff --git a/apprunner-cdk-dotnet/src/DemoApplication.API/appsettings.Development.json b/apprunner-cdk-dotnet/src/DemoApplication.API/appsettings.Development.json new file mode 100644 index 000000000..0c208ae91 --- /dev/null +++ b/apprunner-cdk-dotnet/src/DemoApplication.API/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/apprunner-cdk-dotnet/src/DemoApplication.API/appsettings.json b/apprunner-cdk-dotnet/src/DemoApplication.API/appsettings.json new file mode 100644 index 000000000..10f68b8c8 --- /dev/null +++ b/apprunner-cdk-dotnet/src/DemoApplication.API/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +}