Skip to content

Commit

Permalink
Merge pull request #141 from ddouglas-msft/ddouglas/SendEmailWithMana…
Browse files Browse the repository at this point in the history
…gedIdentity

SendEmailWithManagedIdentity Quickstart
  • Loading branch information
kagbakpem authored Feb 1, 2024
2 parents d0ae5b4 + 032c441 commit 4e1f056
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 0 deletions.
1 change: 1 addition & 0 deletions SendEmailAdvanced/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Additional documentation for this sample can be found on [Microsoft Docs](https:
- ./SendEmailWithAttachments/Program.cs: Entry point for sending email with attachments.
- ./SendEmailWithManualPollingForStatus/Program.cs: Entry point for sending emails and manually poll for the email send status.
- ./SendHighImportanceEmailToMultipleRecipients/Program.cs: Entry point for sending high importance email to multiple recipients.
- ./SendEmailWithManagedIdentity/SendEmailWithManagedIdentityFunction.cs: Entry point for sending an email using a function app with a managed identity.

## Before running the sample for the first time

Expand Down
66 changes: 66 additions & 0 deletions SendEmailAdvanced/SendEmailWithManagedIdentity/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
page_type: sample
languages:
- csharp
products:
- azure
- azure-communication-services
---

# Email Sample Send Email With Managed Identity

[Microsoft Managed Identities](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/overview) are a secure way for Azure services and resources to authenticate to other Azure services, eliminating the need for explicit credentials or secrets. It provides an automatically managed identity in Microsoft Entra for applications to use when connecting to resources that support Microsoft Entra authentication. Resources such as [Azure Functions](https://learn.microsoft.com/azure/azure-functions/functions-overview) and [Azure Logic Apps](https://learn.microsoft.com/azure/logic-apps/logic-apps-overview) can be given a managed identity. The managed identity can then be given access to an Azure Communication Services resource.

This sample sends an email to the selected recipients of any domain using an [Email Communication Services resource](https://docs.microsoft.com/azure/communication-services/quickstarts/email/create-email-communication-resource).
using an [Azure Function configured to use identies instead of secrets](https://learn.microsoft.com/en-us/azure/azure-functions/functions-identity-access-azure-sql-with-managed-identity#enable-system-assigned-managed-identity-on-azure-function). Additional documentation for this sample can be found on [Microsoft Docs](https://docs.microsoft.com/azure/communication-services/concepts/email/email-overview).

## Prerequisites

- Create an Azure account with an active subscription. For details, see [Create an account for free](https://azure.microsoft.com/free/).
- [Visual Studio (2019 and above)](https://visualstudio.microsoft.com/vs/).
- [.NET 6.0](https://dotnet.microsoft.com/download/dotnet/6.0) (Make sure to install version that corresponds with your Visual Studio instance, 32 vs 64 bit).
- Create an Azure Communication Services resource. For details, see [Create an Azure Communication Resource](https://docs.microsoft.com/azure/communication-services/quickstarts/create-communication-resource).
- Create an [Azure Function](https://learn.microsoft.com/azure/azure-functions/functions-overview?pivots=programming-language-csharp).

> Note: We can send an email from our own verified domain also [Add custom verified domains to Email Communication Service](https://docs.microsoft.com/azure/communication-services/quickstarts/email/add-custom-verified-domains).
## Granting the system-assigned identity for the Azure Function access to the Azure Communication Services Resource

To grant an Azure Function access to an Azure Communication Services resource using managed identities, the Azure Function should first be assigned a [system-assigned managed identity](https://learn.microsoft.com/en-us/azure/azure-functions/functions-identity-access-azure-sql-with-managed-identity#enable-system-assigned-managed-identity-on-azure-function).

Next, in the Azure portal, navigate to the Azure Communication Services resource.

1. Select Access Control (IAM). This is where you can view and configure who has access to the resource.
2. Click Add and select add role assignment. The supported roles are 'Contributor' or a custom role that includes both the 'Microsoft.Communication/CommunicationServices/Read' and 'Microsoft.Communication/CommunicationServices/Write' permissions.
3. On the Members tab, under Assign access to, choose Managed Identity
4. Click Select members to open the Select managed identities panel.
5. Confirm that the Subscription is the one in which you created the resources earlier.
6. In the Managed identity selector, choose Function App from the System-assigned managed identity category. The label "Function App" may have a number in parentheses next to it, indicating the number of apps in the subscription with system-assigned identities.
7. Your app should appear in a list below the input fields. If you don't see it, you can use the Select box to filter the results with your app's name.
8. Click on your application. It should move down into the Selected members section. Click Select.
9. Back on the Add role assignment screen, click Review + assign. Review the configuration, and then click Review + assign.

## Code structure

This sample uses an [Azure Functions project created using Visual Studio](https://learn.microsoft.com/azure/azure-functions/functions-create-your-first-function-visual-studio).

- SendEmailWithManagedIdentityFunction.cs: Entry point for sending an email using a function app with a managed identity.

## Before running the sample for the first time

1. Open an instance of PowerShell, Windows Terminal, Command Prompt or equivalent program and navigate to the directory that you would like to clone the sample to.
2. `git clone https://github.com/Azure-Samples/communication-services-dotnet-quickstarts.git`

### Locally configuring the application

1. Navigate to the SendEmailAdvanced folder and open the `SendMailAdvanced.sln` solution in Visual Studio.
1. Open the program.cs file of each project in code structure to configure the following settings:

- `endpoint`: Replace `<ACS_RESOURCE_ENDPOINT>` with the Azure Communication Service resource's endpoint.
- `sender`: Replace `<SENDER_EMAIL>` with the sender email obtained from Azure Communication Service.
- `recipient`: Replace `<RECIPIENT_EMAIL>` with the recipient email.
1. Run respective project.

## ❤️ Feedback

We appreciate your feedback and energy in helping us improve our services. [Please let us know if you are satisfied with ACS through this survey](https://microsoft.qualtrics.com/jfe/form/SV_5dtYL81xwHnUVue).
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Communication.Email" Version="1.0.1" />
<PackageReference Include="Azure.Identity" Version="1.10.4" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.2.0" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Azure;
using Azure.Communication.Email;
using Azure.Identity;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;

namespace SendEmailWithManagedIdentity
{
// This code demonstrates how to authenticate to your Communication Service resource using Managed Identities.
// This function app should be given a managed identity with "Contributor" access to the Azure Communication
// Service resouce or a custom role with both the "Microsoft.Communication/CommunicationServices/Read" and
// "Microsoft.Communication/CommunicationServices/Write" can also be used.
// This example uses DefaultAzureCredential, but ManagedIdentityCredential could have also been used.
// DefaultAzureCredential allows the same code to be used during local development and in the deployed environment
// because DefaultAzureCredential supports many authentication types.
public static class SendEmailWithManagedIdentityFunction
{
[FunctionName("SendEmailWithManagedIdentity")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");

string resourceEndpoint = "<ACS_RESOURCE_ENDPOINT>";
EmailClient emailClient = new EmailClient(new Uri(resourceEndpoint), new DefaultAzureCredential());

var subject = "Welcome to Azure Communication Service Email APIs.";
var htmlContent = "<html><body><h1>Quick send email managed identity test</h1><br/><h4>This email message is sent from Azure Communication Service Email using a function app.</h4><p>This mail was sent using .NET SDK!!</p></body></html>";
var sender = "<SENDER_EMAIL>";
var recipient = "<RECIPIENT_EMAIL>";

try
{
log.LogInformation("Sending email...");
EmailSendOperation emailSendOperation = await emailClient.SendAsync(
Azure.WaitUntil.Completed,
sender,
recipient,
subject,
htmlContent);
EmailSendResult statusMonitor = emailSendOperation.Value;

log.LogInformation($"Email Sent. Status = {emailSendOperation.Value.Status}");

/// Get the OperationId so that it can be used for tracking the message for troubleshooting
string operationId = emailSendOperation.Id;
log.LogInformation($"Email operation id = {operationId}");

return new OkObjectResult(operationId);
}
catch (RequestFailedException ex)
{
return new ObjectResult($"Email send operation failed with error code: {ex.ErrorCode}, message: {ex.Message}")
{
StatusCode = 500,
};
}
}
}
}
12 changes: 12 additions & 0 deletions SendEmailAdvanced/SendEmailWithManagedIdentity/host.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
},
"enableLiveMetricsFilters": true
}
}
}
5 changes: 5 additions & 0 deletions SendEmailAdvanced/SendMailAdvanced.sln
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SendEmailWithManagedIdentity", "SendEmailWithManagedIdentity\SendEmailWithManagedIdentity.csproj", "{921687CF-2217-4906-AA2F-2464E5C54C2C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SendBulkEmailWithOptionalThrottlingPolicy", "SendBulkEmailWithOptionalThrottlingPolicy\SendBulkEmailWithOptionalThrottlingPolicy.csproj", "{91D7D038-B1C1-4905-9AEC-B23F7C8485B1}"
EndProject
Global
Expand All @@ -40,6 +41,10 @@ Global
{EF6A7D57-769A-40B3-B9FF-8165A657B304}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF6A7D57-769A-40B3-B9FF-8165A657B304}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF6A7D57-769A-40B3-B9FF-8165A657B304}.Release|Any CPU.Build.0 = Release|Any CPU
{921687CF-2217-4906-AA2F-2464E5C54C2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{921687CF-2217-4906-AA2F-2464E5C54C2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{921687CF-2217-4906-AA2F-2464E5C54C2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{921687CF-2217-4906-AA2F-2464E5C54C2C}.Release|Any CPU.Build.0 = Release|Any CPU
{91D7D038-B1C1-4905-9AEC-B23F7C8485B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{91D7D038-B1C1-4905-9AEC-B23F7C8485B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{91D7D038-B1C1-4905-9AEC-B23F7C8485B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down

0 comments on commit 4e1f056

Please sign in to comment.