n3wt0n / azurewebappsslmanager Goto Github PK
View Code? Open in Web Editor NEWAcquires and manages free SSL certificates for Azure Web App and Azure Functions applications.
License: MIT License
Acquires and manages free SSL certificates for Azure Web App and Azure Functions applications.
License: MIT License
Hello,
I have my DNS Zone in a different subscription from the AzureWebAppSSLManager and the App Services which it is servicing. I think this is a problem. The code is currently not able to reference a DNS Zone in another subscription, am I correct?
Dave.
I am trying to figure out an issue with my App Service where a certificate is being created but cannot be installed. I pretty quickly hit the production rate limit, and there doesn't seem to be a way to allow using the staging environment to debug the issue.
You should also change the compares to something like this: .SingleOrDefault(w => w.Name.Equals(_webAppName, StringComparison.CurrentCultureIgnoreCase)); Your code was lowering one side but not the other.
Originally posted by @bbakermmc in #8 (comment)
hi, this part of the code returns an error message "Operation returned an invalid status code 'NotFound'". I have created a certificate and host name properly.
webApp = await webApp
.Update()
.DefineSslBinding()
.ForHostname(hostname)
.WithExistingCertificate(certificateThumbPrint)
.WithSniBasedSsl()
.Attach()
.ApplyAsync();
Error updating binding for 'test4.rhplus.cloud' with certificate 'BF7DA709EBA510CD325AA9652FC76F0C510C3561'Microsoft.Azure.Management.AppService.Fluent.Models.DefaultErrorResponseException : Operation returned an invalid status code 'NotFound'at async Microsoft.Azure.Management.AppService.Fluent.WebAppsOperations.BeginCreateOrUpdateWithHttpMessagesAsync(String resourceGroupName,String name,SiteInner siteEnvelope,Dictionary2 customHeaders,CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.AppService.Fluent.WebAppsOperations.CreateOrUpdateWithHttpMessagesAsync(String resourceGroupName,String name,SiteInner siteEnvelope,Dictionary
2 customHeaders,CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.AppService.Fluent.WebAppsOperationsExtensions.CreateOrUpdateAsync(IWebAppsOperations operations,String resourceGroupName,String name,SiteInner siteEnvelope,CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.AppService.Fluent.AppServiceBaseImpl6.CreateOrUpdateInnerAsync[FluentT,FluentImplT,FluentWithCreateT,DefAfterRegionT,DefAfterGroupT,UpdateT](SiteInner site,CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.AppService.Fluent.WebAppBaseImpl
5.CreateResourceInternalAsync[FluentT,FluentImplT,DefAfterRegionT,DefAfterGroupT,UpdateT](CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.AppService.Fluent.WebAppBaseImpl5.CreateResourceAsync[FluentT,FluentImplT,DefAfterRegionT,DefAfterGroupT,UpdateT](CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.ResourceManager.Fluent.Core.ResourceActions.Creatable
4.-CreateResourceAsyncIFluentResourceT,InnerResourceT,FluentResourceT,IResourceTat System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.ResourceManager.Fluent.Core.DAG.CreatorTaskItem1.ExecuteAsync[IResourceT](CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.ResourceManager.Fluent.Core.DAG.TaskGroupBase
1.ExecuteNodeTaskAsync[TaskResultT](DAGNode1 node,CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.ResourceManager.Fluent.Core.ResourceActions.CreatableUpdatable
5.ApplyAsync[IFluentResourceT,InnerResourceT,FluentResourceT,IResourceT,IUpdatableT](CancellationToken cancellationToken,Boolean multiThreaded)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async WebAppSSLManager.AzureHelper.AddCertificateAsync() at C:\home\site\repository\src\WebAppSSLManager\AzureHelper.cs : 237
2021-06-07T13:52:02.847 [Error] Unable to complete the processing for test4.rhplus.cloudMicrosoft.Azure.Management.AppService.Fluent.Models.DefaultErrorResponseException : Operation returned an invalid status code 'NotFound'at async Microsoft.Azure.Management.AppService.Fluent.WebAppsOperations.BeginCreateOrUpdateWithHttpMessagesAsync(String resourceGroupName,String name,SiteInner siteEnvelope,Dictionary2 customHeaders,CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.AppService.Fluent.WebAppsOperations.CreateOrUpdateWithHttpMessagesAsync(String resourceGroupName,String name,SiteInner siteEnvelope,Dictionary
2 customHeaders,CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.AppService.Fluent.WebAppsOperationsExtensions.CreateOrUpdateAsync(IWebAppsOperations operations,String resourceGroupName,String name,SiteInner siteEnvelope,CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.AppService.Fluent.AppServiceBaseImpl6.CreateOrUpdateInnerAsync[FluentT,FluentImplT,FluentWithCreateT,DefAfterRegionT,DefAfterGroupT,UpdateT](SiteInner site,CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.AppService.Fluent.WebAppBaseImpl
5.CreateResourceInternalAsync[FluentT,FluentImplT,DefAfterRegionT,DefAfterGroupT,UpdateT](CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.AppService.Fluent.WebAppBaseImpl5.CreateResourceAsync[FluentT,FluentImplT,DefAfterRegionT,DefAfterGroupT,UpdateT](CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.ResourceManager.Fluent.Core.ResourceActions.Creatable
4.-CreateResourceAsyncIFluentResourceT,InnerResourceT,FluentResourceT,IResourceTat System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.ResourceManager.Fluent.Core.DAG.CreatorTaskItem1.ExecuteAsync[IResourceT](CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.ResourceManager.Fluent.Core.DAG.TaskGroupBase
1.ExecuteNodeTaskAsync[TaskResultT](DAGNode1 node,CancellationToken cancellationToken)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async Microsoft.Azure.Management.ResourceManager.Fluent.Core.ResourceActions.CreatableUpdatable
5.ApplyAsync[IFluentResourceT,InnerResourceT,FluentResourceT,IResourceT,IUpdatableT](CancellationToken cancellationToken,Boolean multiThreaded)at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async WebAppSSLManager.AzureHelper.AddCertificateAsync() at C:\home\site\repository\src\WebAppSSLManager\AzureHelper.cs : 237at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at async WebAppSSLManager.WebAppSSLManager.Run(TimerInfo myTimer,IAsyncCollector`1 messageCollector,ILogger logger) at C:\home\site\repository\src\WebAppSSLManager\WebAppSSLManager.cs : 56
This is exactly what i'm looking for.
An enhancement I'd love to see is saving the pfx to keyvault along with the password.
Awesome work!
Have you tried using a managed idenity instead of a service provider account, this way we dont need to have an extra account, the MI is seen as a user in AAD, so we can give it permissions it needs, but we dont need to manage a password etc, and if we remove the function app the user account is also auto removed, no lingering service accounts that could get compromised.
Issue
It is currently impossible to create certificates for domains hosted by national registries (e.g. .co.uk) due to the way the DNS record is being created.
Reproduction
www.domain.co.uk
.AppProperty.BaseDomain == ".co.uk"
and thereforeSolution
Use the name of the zone in Azure DNS as the BaseDomain as this is the way Azure DNS works.
Looking at the code, I assume these should be configured also?
AzureWebAppSSLManager/src/WebAppSSLManager/CertificatesHelper.cs
Lines 125 to 132 in cfa7613
for testing, I just deployed it to a new resource group, so I got a new function app, storage, app service plan..., and the function is running successfully without any errors. after the function run for the first time, I found only the file accountkey.pem in the storage, in the certificates container. But where do I locate the main certificate file...
Did I miss anything?
Since it needs to do many things, register dns entries, upload certificates, change bindings, what are the minimum demand for access rights for the service provider.
Dns zone, contributor seems to be enough.
App Service, have assigned contributor but gets an error when it tries to upload the certificate to the webapp.
The WebAppSSLManager Azure Function has encountered an error.
Unable to complete the processing for *.somedomain.com
Exception Message: Operation returned an invalid status code 'Forbidden' Exception
StackTrace:
at Microsoft.Azure.Management.AppService.Fluent.CertificatesOperations.CreateOrUpdateWithHttpMessagesAsync(String resourceGroupName, String name, CertificateInner certificateEnvelope, Dictionary`2 customHeaders, CancellationToken cancellationToken)
at Microsoft.Azure.Management.AppService.Fluent.CertificatesOperationsExtensions.CreateOrUpdateAsync(ICertificatesOperations operations, String resourceGroupName, String name, CertificateInner certificateEnvelope, CancellationToken cancellationToken)
at Microsoft.Azure.Management.AppService.Fluent.AppServiceCertificateImpl.CreateResourceAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Management.ResourceManager.Fluent.Core.ResourceActions.Creatable`4.Microsoft.Azure.Management.ResourceManager.Fluent.Core.ResourceActions.IResourceCreator.CreateResourceAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Management.ResourceManager.Fluent.Core.DAG.CreatorTaskItem`1.ExecuteAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Management.ResourceManager.Fluent.Core.DAG.TaskGroupBase`1.ExecuteNodeTaskAsync(DAGNode`1 node, CancellationToken cancellationToken)
at WebAppSSLManager.AzureHelper.AddCertificateToWebAppAsync() in D:\home\site\repository\src\WebAppSSLManager\AzureHelper.cs:line 159
at WebAppSSLManager.WebAppSSLManager.Run(TimerInfo myTimer, IAsyncCollector`1 messageCollector, ILogger logger) in D:\home\site\repository\src\WebAppSSLManager\WebAppSSLManager.cs:line 51
Why not set the cert password/container names via Env variables?
This needs more investigation, but there seems to be an issue with installing the certificate to the app service when using a Linux App Service. It might even be an Azure/SDK issue, but logging for further investigation.
Essentially the issue seems to be that the certificate obtained from from LetsEncrypt won't upload or isn't visible to the app service, so when creating the hostname binding, the thumbprint results in a not found exception.
It's not currently possible to configure a certificate for a root domain. The error "root hostname cannot be assigned with a CName record" is returned. This is due to the way domains are split in AzureHelper.cs:210. e.g. for the domain 'google.com' the domain will be set as "com" and the subdomain as "google". It works correctly for "www.google.com" though as it's correctly parsed.
Whats the app name when you want to deploy to a slot?
IE: 1 site with 3 slots. www.site.com, dev.site.com, stage.site.com
Hey Davide,
I'm trying to deploy the app to Azure through the provided template.
I've created the Service Principal, SendGrid etc and created also a new Ressource Group.
I've assigned to all parameters the corresponding values
The deployment of the webapp leads to a failure with reason "Conflict"
Any idea what could be the reason?
Best regards,
Robert
Update the function app to runtime 4.x as this app is using 3.x and will be discontinued in Dec 3rd, 2022 according to Microsoft.
Can we add CSV/Array of URL to the hostnames so we can generate 1 cert for multiple sites IE:
*.dev.site.com
*.stage.site.com
The code currently doesnt work with Function Apps.
In the code AddCertificateToWebAppAsync
If webApp is null you should error, currently code breaks further down where you reference the the Region etc.
You will probably need to do this: Then make a new DTO for the fields you need, you could split this if you wanted as a "Type" in the JSON
var funApp = _azure.AppServices.FunctionApps.ListByResourceGroup(_webAppResGroup).SingleOrDefault(w => w.Name == _webAppName.ToLower());
var webApp = _azure.AppServices.WebApps.ListByResourceGroup(_webAppResGroup).SingleOrDefault(w => w.Name == _webAppName.ToLower());
There some .Where().SingleOrDefault() that can be replaced with just .SingleOrDefault
Yet another way of deploying websites on Azure is Azure Static Web Apps. Again there are custom domains and certificates to be managed and bound.
The service isn't really part of App Services, but some things are related. Especially it can also use App Service Certificates.
I really like ASWs, but I'd also like to have my certs renewed without buying the expensive ones from Azure.
I'm wondering what I would have to do to make this library refresh the bindings in ASWs - the other two steps (cert and dns updates) should be the same, right?
I had some brief look at the source code and the Azure Docs for ASW, but so far I can't find C# bindings for the ASW REST API and I also can't find cert binding functions in the REST API itself.
I'm writing this both as a feature request and maybe someone already has a bit of info what needs to be done here.
Describe the bug
DNS TXT record is deleted and recreated during verification to Let's Encrypt Servers but changes do not refresh in Azure immediately.
Fix is to wait before validating for Azure DNS zone to update
Thread.Sleep(10 * 1000);
var validatedChallege = await dnsChallenge.Validate();
To Reproduce
Steps to reproduce the behavior. For Example:
Try to issue new cert.
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Additional context
Add any other context about the problem here.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.