I have a time trigger function in my azure function app that uses httpclient to request a snapshot from a camera.
The camera itself is behind a firewall however the camera is accessable from our office network.
In azure we allow azure to use our office network. Which from my perspective means that azure should be able to reach the camera.
When i test this localy when on our office network everything works. Once deployed to azure it no longer works.
Here is my time trigger function:
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
namespace PlaygroundAzureFunctions
{
public class PictureToStorageFunnyTest
{
[FunctionName("PictureToStorage")]
public async Task RunAsync([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"Timer trigger started executed at: {DateTime.Now}");
// Create an HttpClientHandler object and set to use default credentials
HttpClientHandler handler = new HttpClientHandler();
var credCache = new CredentialCache();
var user = "User";
var secret = "Secret";
var domain = "urlToPictureAPI";
credCache.Add(new Uri(domain), "Digest", new NetworkCredential(user, secret));
handler.Credentials = credCache;
// Create an HttpClient object
HttpClient client = new HttpClient(handler);
try
{
using HttpResponseMessage response = await client.GetAsync(domain);
response.EnsureSuccessStatusCode();
byte[] responseBody = await response.Content.ReadAsByteArrayAsync();
// Above three lines can be replaced with new helper method below
// string responseBody = await client.GetStringAsync(uri);
//For Console printout test
//Console.WriteLine(responseBody);
//For local storage testing
//File.WriteAllBytes("TestPicture.jpeg", responseBody);
string Connection = Environment.GetEnvironmentVariable("AzureWebJobsStorage");
string containerName = Environment.GetEnvironmentVariable("ContainerName");
var blobClient = new BlobContainerClient(Connection, containerName);
var blob = blobClient.GetBlobClient("TestPicture.jpeg");
var blobHttpHeader = new BlobHttpHeaders { ContentType = "image/jpeg" };
byte[] sourceData = responseBody;
BinaryData uploadData = new BinaryData(sourceData);
await blob.UploadAsync(uploadData, new BlobUploadOptions { HttpHeaders = blobHttpHeader });
log.LogInformation($"Picture Uploaded Successfully at: {DateTime.Now}");
}
catch (HttpRequestException e)
{
//Console.WriteLine("\nException Caught!");
//Console.WriteLine("Message :{0} ", e.Message);
log.LogInformation("\nException Caught!\n" + $"Message :{{0}} at: {DateTime.Now}", e.Message);
}
// Need to call dispose on the HttpClient and HttpClientHandler objects
// when done using them, so the app doesn't leak resources
handler.Dispose();
client.Dispose();
log.LogInformation($"Timer trigger ended executed at: {DateTime.Now}");
}
}
}
The time trigger and the app has been deployed with the lowest plan and from what i have read it might need to be a higher plan to solve this.
How do i make the function app use the azure network that is allowed to access our office network and from here will be able to reach the camera?
We dont control the firewall on the camera ourself (yet). We do control the firewall on our office and i hereby thought it maybe was possible to route azure function to act like it called its requests from our office network.
Interconnection between a corporate network and Azure can be done in several ways (site to site VPN, ExpressRoute, etc.) but it always lands in an Azure Virtual Network (VNET).
To connect your Azure function to a VNET you will need to setup VNET integration for outbound traffic. If you also need inbound traffic from the VNET to reach the function a private endpoint can be setup.