From 216af67ce484c267f67ac48191215328e0717069 Mon Sep 17 00:00:00 2001 From: Mikhail Shilkov Date: Thu, 5 Mar 2020 21:14:47 +0100 Subject: [PATCH] Add sample showing AKS + private ACR (#574) * Add sample showing AKS + private ACR The sample further demonstrates building & pushing a .NET Core docker image to the registry, and then deploying a container of that image onto the cluster. * PR feedback * Fix typo * Update README files * Update README.md --- README.md | 1 + .../.gitignore | 353 ++++++++++++++++++ .../Azure.AKS.PrivateContainerRegistry.csproj | 24 ++ .../Program.cs | 255 +++++++++++++ .../Pulumi.yaml | 3 + .../README.md | 69 ++++ .../SampleApplication/Dockerfile | 17 + .../SampleApplication/SampleApplication.sln | 27 ++ .../SampleApplication/docker-compose.yaml | 7 + .../src/SampleApplication.Web/Program.cs | 17 + .../Properties/launchSettings.json | 12 + .../SampleApplication.Web.csproj | 7 + .../src/SampleApplication.Web/Startup.cs | 9 + .../SampleApplication.Web/appsettings.json | 10 + 14 files changed, 811 insertions(+) create mode 100644 azure-cs-aks-private-container-registry/.gitignore create mode 100644 azure-cs-aks-private-container-registry/Azure.AKS.PrivateContainerRegistry.csproj create mode 100644 azure-cs-aks-private-container-registry/Program.cs create mode 100644 azure-cs-aks-private-container-registry/Pulumi.yaml create mode 100644 azure-cs-aks-private-container-registry/README.md create mode 100644 azure-cs-aks-private-container-registry/SampleApplication/Dockerfile create mode 100644 azure-cs-aks-private-container-registry/SampleApplication/SampleApplication.sln create mode 100644 azure-cs-aks-private-container-registry/SampleApplication/docker-compose.yaml create mode 100644 azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/Program.cs create mode 100644 azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/Properties/launchSettings.json create mode 100644 azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/SampleApplication.Web.csproj create mode 100644 azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/Startup.cs create mode 100644 azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/appsettings.json diff --git a/README.md b/README.md index 26a9093ca..9bb0ec7d9 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,7 @@ Example | Description | Example | Description | ----- | --------- | [AKS](azure-cs-aks) | Stand up an Azure Kubernetes Service (AKS) cluster. +[AKS and Private Container Registry](azure-cs-aks-private-container-registry) | Stand up an Azure Kubernetes Service (AKS) cluster, a private Azure Container Registry, and deploys an image to the cluster. [App Service](azure-cs-appservice) | Build a web application hosted in App Service and provision Azure SQL Database and Azure Application Insights. [Bot Service](azure-cs-botservice) | Build an Azure Bot Service hosted in Azure App Service. [Cosmos App Component](azure-cs-cosmosapp-component) | Use a reusable component to create globally-distributed applications with Azure Cosmos DB. diff --git a/azure-cs-aks-private-container-registry/.gitignore b/azure-cs-aks-private-container-registry/.gitignore new file mode 100644 index 000000000..e64527066 --- /dev/null +++ b/azure-cs-aks-private-container-registry/.gitignore @@ -0,0 +1,353 @@ +## 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/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# 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 +nunit-*.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 +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.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 +# NuGet Symbol Packages +*.snupkg +# 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 +*.appxbundle +*.appxupload + +# 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 +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# 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/ + +# CodeRush personal settings +.cr/personal + +# 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/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ diff --git a/azure-cs-aks-private-container-registry/Azure.AKS.PrivateContainerRegistry.csproj b/azure-cs-aks-private-container-registry/Azure.AKS.PrivateContainerRegistry.csproj new file mode 100644 index 000000000..7e24e2c1a --- /dev/null +++ b/azure-cs-aks-private-container-registry/Azure.AKS.PrivateContainerRegistry.csproj @@ -0,0 +1,24 @@ + + + + Exe + netcoreapp3.1 + enable + + + + + + + + + + + + + + + + + + diff --git a/azure-cs-aks-private-container-registry/Program.cs b/azure-cs-aks-private-container-registry/Program.cs new file mode 100644 index 000000000..a7bc62e29 --- /dev/null +++ b/azure-cs-aks-private-container-registry/Program.cs @@ -0,0 +1,255 @@ +// Copyright 2016-2020, Pulumi Corporation. All rights reserved. + +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Pulumi; +using Pulumi.AzureAD; +using Pulumi.Azure.ContainerService; +using Pulumi.Azure.ContainerService.Inputs; +using Pulumi.Azure.Core; +using Pulumi.Azure.Network; +using Pulumi.Azure.Role; +using Pulumi.Docker; +using Pulumi.Kubernetes.Types.Inputs.Apps.V1; +using Pulumi.Kubernetes.Types.Inputs.Core.V1; +using Pulumi.Kubernetes.Types.Inputs.Meta.V1; +using Pulumi.Random; +using Pulumi.Tls; +using ContainerArgs = Pulumi.Kubernetes.Types.Inputs.Core.V1.ContainerArgs; +using SecretArgs = Pulumi.Kubernetes.Types.Inputs.Core.V1.SecretArgs; +using ServiceArgs = Pulumi.Kubernetes.Types.Inputs.Core.V1.ServiceArgs; + +class Program +{ + static Task Main() + { + return Deployment.RunAsync(() => + { + var resourceGroup = new ResourceGroup("aks-rg"); + + var randomPassword = new RandomPassword("password", new RandomPasswordArgs + { + Length = 20, + Special = true, + }).Result; + + var sshPublicKey = new PrivateKey("ssh-key", new PrivateKeyArgs + { + Algorithm = "RSA", + RsaBits = 4096, + }).PublicKeyOpenssh; + + // Create the AD service principal for the K8s cluster. + var adApp = new Application("aks"); + var adSp = new ServicePrincipal("aksSp", new ServicePrincipalArgs { ApplicationId = adApp.ApplicationId }); + var adSpPassword = new ServicePrincipalPassword("aksSpPassword", new ServicePrincipalPasswordArgs + { + ServicePrincipalId = adSp.Id, + Value = randomPassword, + EndDate = "2099-01-01T00:00:00Z", + }); + + // Grant networking permissions to the SP (needed e.g. to provision Load Balancers). + var assignment = new Assignment("role-assignment", new AssignmentArgs + { + PrincipalId = adSp.Id, + Scope = resourceGroup.Id, + RoleDefinitionName = "Network Contributor" + }); + + // Create a Virtual Network for the cluster. + var vnet = new VirtualNetwork("vnet", new VirtualNetworkArgs + { + ResourceGroupName = resourceGroup.Name, + AddressSpaces = { "10.2.0.0/16" }, + }); + + // Create a Subnet for the cluster. + var subnet = new Subnet("subnet", new SubnetArgs + { + ResourceGroupName = resourceGroup.Name, + VirtualNetworkName = vnet.Name, + AddressPrefix = "10.2.1.0/24", + }); + + // Now allocate an AKS cluster. + var cluster = new KubernetesCluster("aksCluster", new KubernetesClusterArgs + { + ResourceGroupName = resourceGroup.Name, + AgentPoolProfiles = new KubernetesClusterAgentPoolProfilesArgs + { + Name = "aksagentpool", + Count = 3, + VmSize = "Standard_B2s", + OsDiskSizeGb = 30, + VnetSubnetId = subnet.Id + }, + DnsPrefix = "sampleaks", + LinuxProfile = new KubernetesClusterLinuxProfileArgs + { + AdminUsername = "aksuser", + SshKey = new KubernetesClusterLinuxProfileSshKeyArgs + { + KeyData = sshPublicKey, + }, + }, + ServicePrincipal = new KubernetesClusterServicePrincipalArgs + { + ClientId = adApp.ApplicationId, + ClientSecret = adSpPassword.Value, + }, + KubernetesVersion = "1.15.7", + RoleBasedAccessControl = new KubernetesClusterRoleBasedAccessControlArgs { Enabled = true }, + NetworkProfile = new KubernetesClusterNetworkProfileArgs + { + NetworkPlugin = "azure", + DnsServiceIp = "10.2.2.254", + ServiceCidr = "10.2.2.0/24", + DockerBridgeCidr = "172.17.0.1/16", + }, + }); + + // Create a k8s provider pointing to the kubeconfig. + var k8sProvider = new Pulumi.Kubernetes.Provider("k8s", new Pulumi.Kubernetes.ProviderArgs + { + KubeConfig = cluster.KubeConfigRaw + }); + + var customResourceOptions = new CustomResourceOptions + { + Provider = k8sProvider + }; + + // Create a Container Registry. + var registry = new Registry("acregistry", new RegistryArgs + { + ResourceGroupName = resourceGroup.Name, + Sku = "Basic", + AdminEnabled = true + }); + + // Build & push the sample application to the registry. + var applicationName = "sample-application"; + var imageName = registry.LoginServer.Apply(value => $"{value}/{applicationName}"); + + var image = new Image(applicationName, new ImageArgs + { + Build = "./SampleApplication", + Registry = new ImageRegistry + { + Server = registry.LoginServer, + Username = registry.AdminUsername, + Password = registry.AdminPassword + }, + ImageName = imageName + }, new ComponentResourceOptions + { + Provider = k8sProvider + }); + + // Create a k8s secret for use when pulling images from the container registry when deploying the sample application. + var dockerCfg = Output.All(registry.LoginServer, registry.AdminUsername, registry.AdminPassword).Apply(values => + { + var r = new Dictionary(); + var server = values[0]; + var username = values[1]; + var password = values[2]; + + r[server] = new + { + email = "notneeded@notneeded.com", + username, + password + }; + + return r; + }); + + var dockerCfgString = dockerCfg.Apply(x => + Convert.ToBase64String(Encoding.UTF8.GetBytes(System.Text.Json.JsonSerializer.Serialize(x)))); + + var dockerCfgSecretName = "dockercfg-secret"; + + var dockerCfgSecret = new Pulumi.Kubernetes.Core.V1.Secret(dockerCfgSecretName, new SecretArgs + { + Data = + { + { ".dockercfg", dockerCfgString } + }, + Type = "kubernetes.io/dockercfg", + Metadata = new ObjectMetaArgs + { + Name = dockerCfgSecretName, + } + }, customResourceOptions); + + // Deploy the sample application to the cluster. + var labels = new InputMap + { + { "app", $"app-{applicationName}" }, + }; + + var deployment = new Pulumi.Kubernetes.Apps.V1.Deployment(applicationName, new DeploymentArgs + { + Spec = new DeploymentSpecArgs + { + Selector = new LabelSelectorArgs + { + MatchLabels = labels, + }, + Replicas = 1, + Template = new PodTemplateSpecArgs + { + Metadata = new ObjectMetaArgs + { + Labels = labels, + Name = applicationName + }, + Spec = new PodSpecArgs + { + Containers = new List + { + new ContainerArgs + { + Name = applicationName, + Image = image.ImageName, + } + }, + ImagePullSecrets = new LocalObjectReferenceArgs + { + Name = dockerCfgSecretName + } + } + } + } + }, customResourceOptions); + + // Create a new service. + var service = new Pulumi.Kubernetes.Core.V1.Service(applicationName, new ServiceArgs + { + Metadata = new ObjectMetaArgs + { + Name = applicationName, + Labels = labels + }, + Spec = new ServiceSpecArgs + { + Type = "LoadBalancer", + Selector = deployment.Spec.Apply(x => x.Template.Metadata.Labels), + Ports = new ServicePortArgs + { + Port = 80 + } + } + }, customResourceOptions); + + return new Dictionary + { + ["kubeconfig"] = cluster.KubeConfigRaw, + ["dockercfg-secret-name"] = dockerCfgSecret.Metadata.Apply(x => x.Name), + }; + }); + } +} \ No newline at end of file diff --git a/azure-cs-aks-private-container-registry/Pulumi.yaml b/azure-cs-aks-private-container-registry/Pulumi.yaml new file mode 100644 index 000000000..516d7a684 --- /dev/null +++ b/azure-cs-aks-private-container-registry/Pulumi.yaml @@ -0,0 +1,3 @@ +name: azure-cs-aks-private-container-registry +description: Creates an Azure Kubernetes Service (AKS) cluster and deploys a sample .NET application after bulding & pushing it to a private Azure Container Registry. +runtime: dotnet diff --git a/azure-cs-aks-private-container-registry/README.md b/azure-cs-aks-private-container-registry/README.md new file mode 100644 index 000000000..10c74ecaf --- /dev/null +++ b/azure-cs-aks-private-container-registry/README.md @@ -0,0 +1,69 @@ +[![Deploy](https://get.pulumi.com/new/button.svg)](https://app.pulumi.com/new) + +# Azure Kubernetes Service (AKS) Cluster + Build & Deploy from Private Container Registry + +This sample setup demonstrates the following: + +* Stands up an [Azure Kubernetes Service](https://azure.microsoft.com/en-us/services/kubernetes-service/) (AKS) cluster. +* Creates an Azure Container Registry. +* Builds & pushes a sample application as a Docker image to the registry. +* Deploys the sample application from the registry onto the cluster. +* Exports a container registry secret for use by other stacks. For example, "service" projects that create kubernetes deployments that need to be able to pull images from the registry. + +## Deploying the App + +To deploy your infrastructure, follow the below steps. + +### Prerequisites + +1. [Install Pulumi](https://www.pulumi.com/docs/get-started/install/) +2. [Install .NET Core 3.1+](https://dotnet.microsoft.com/download) + +### Steps + +1. Create a new stack: + + ```sh + $ pulumi stack init + Enter a stack name: dev + ``` + +1. Set the required configuration variable for this program: + + ```bash + $ pulumi config set azure:location westus + $ az login + ``` + +4. Stand up the AKS cluster: + + > **Note**: Due to an [issue](https://github.com/terraform-providers/terraform-provider-azuread/issues/156) in Azure Terraform Provider, the + > creation of an Azure Service Principal, which is needed to create the Kubernetes cluster, is delayed and may not + > be available when the cluster is created. If you get a "Service Principal not found" error, as a work around, you should be able to run `pulumi up` + > again, at which time the Service Principal replication should have been completed. See [this issue](https://github.com/Azure/AKS/issues/1206) and + > [this doc](https://docs.microsoft.com/en-us/azure/aks/troubleshooting#im-receiving-errors-that-my-service-principal-was-not-found-when-i-try-to-create-a-new-cluster-without-passing-in-an-existing-one) + > for further details. + + ```bash + $ pulumi up + ``` + +5. After 10-15 minutes, your cluster will be ready, and the kubeconfig YAML you'll use to connect to the cluster will be available as an output. You can save this kubeconfig to a file like so: + + ```bash + $ pulumi stack output kubeconfig > kubeconfig.yaml + ``` + + Once you have this file in hand, you can interact with your new cluster as usual via `kubectl`: + + ```bash + $ KUBECONFIG=./kubeconfig.yaml kubectl get nodes + ``` +6. From there, feel free to experiment. Simply making edits and running `pulumi up` will incrementally update your stack. + +7. Once you've finished experimenting, tear down your stack's resources by destroying and removing it: + + ```bash + $ pulumi destroy --yes + $ pulumi stack rm --yes + ``` diff --git a/azure-cs-aks-private-container-registry/SampleApplication/Dockerfile b/azure-cs-aks-private-container-registry/SampleApplication/Dockerfile new file mode 100644 index 000000000..e62d19b65 --- /dev/null +++ b/azure-cs-aks-private-container-registry/SampleApplication/Dockerfile @@ -0,0 +1,17 @@ +FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env +WORKDIR /app + +# Copy csproj and restore as distinct layers +COPY src/SampleApplication.Web/*.csproj ./src/SampleApplication.Web/ +COPY SampleApplication.sln ./ +RUN dotnet restore ./SampleApplication.sln + +# Copy everything else and build +COPY src ./src +RUN dotnet publish ./SampleApplication.sln -c Release -o out + +# Build runtime image +FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 +WORKDIR /app +COPY --from=build-env /app/out . +ENTRYPOINT ["dotnet", "SampleApplication.Web.dll"] diff --git a/azure-cs-aks-private-container-registry/SampleApplication/SampleApplication.sln b/azure-cs-aks-private-container-registry/SampleApplication/SampleApplication.sln new file mode 100644 index 000000000..1b4a594f9 --- /dev/null +++ b/azure-cs-aks-private-container-registry/SampleApplication/SampleApplication.sln @@ -0,0 +1,27 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{1F7D45BD-9A1F-4376-A138-B3A9FC474A98}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "items", "items", "{0BA2646E-7BFB-4F7F-A813-77F91141BE2C}" +ProjectSection(SolutionItems) = preProject + Dockerfile = Dockerfile + docker-compose.yaml = docker-compose.yaml +EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleApplication.Web", "src\SampleApplication.Web\SampleApplication.Web.csproj", "{85D64E00-0137-43D5-A8B9-D0B8F9FBA659}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {85D64E00-0137-43D5-A8B9-D0B8F9FBA659}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {85D64E00-0137-43D5-A8B9-D0B8F9FBA659}.Debug|Any CPU.Build.0 = Debug|Any CPU + {85D64E00-0137-43D5-A8B9-D0B8F9FBA659}.Release|Any CPU.ActiveCfg = Release|Any CPU + {85D64E00-0137-43D5-A8B9-D0B8F9FBA659}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {85D64E00-0137-43D5-A8B9-D0B8F9FBA659} = {1F7D45BD-9A1F-4376-A138-B3A9FC474A98} + EndGlobalSection +EndGlobal diff --git a/azure-cs-aks-private-container-registry/SampleApplication/docker-compose.yaml b/azure-cs-aks-private-container-registry/SampleApplication/docker-compose.yaml new file mode 100644 index 000000000..b68abe57c --- /dev/null +++ b/azure-cs-aks-private-container-registry/SampleApplication/docker-compose.yaml @@ -0,0 +1,7 @@ +version: '3.7' + +services: + web: + build: . + ports: + - "4100:80" diff --git a/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/Program.cs b/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/Program.cs new file mode 100644 index 000000000..b5c19ad9b --- /dev/null +++ b/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/Program.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + +namespace SampleApplication.Web +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); + } +} diff --git a/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/Properties/launchSettings.json b/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/Properties/launchSettings.json new file mode 100644 index 000000000..722f393dd --- /dev/null +++ b/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "SampleApplication": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "https://localhost:4001;http://localhost:4000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/SampleApplication.Web.csproj b/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/SampleApplication.Web.csproj new file mode 100644 index 000000000..42b3f9486 --- /dev/null +++ b/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/SampleApplication.Web.csproj @@ -0,0 +1,7 @@ + + + + netcoreapp3.1 + + + diff --git a/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/Startup.cs b/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/Startup.cs new file mode 100644 index 000000000..86c72983d --- /dev/null +++ b/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/Startup.cs @@ -0,0 +1,9 @@ +using Microsoft.AspNetCore.Builder; + +namespace SampleApplication.Web +{ + public class Startup + { + public void Configure(IApplicationBuilder app) => app.UseWelcomePage(); + } +} diff --git a/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/appsettings.json b/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/appsettings.json new file mode 100644 index 000000000..d9d9a9bff --- /dev/null +++ b/azure-cs-aks-private-container-registry/SampleApplication/src/SampleApplication.Web/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +}