Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic implementation for managed identity for create function app #4213

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 28 additions & 31 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,7 @@
"dependencies": {
"@azure/arm-appinsights": "^5.0.0-alpha.20230530.1",
"@azure/arm-appservice": "^15.0.0",
"@azure/arm-authorization-profile-2020-09-01-hybrid": "^2.1.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious: Were you forced to use 2020-09-01-hybrid for some reason?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just following this documentation. Didn't even really think about how the @azure/arm-authorization-profile package would exist.

https://learn.microsoft.com/en-us/javascript/api/overview/azure/arm-authorization-profile-2020-09-01-hybrid-readme?view=azure-node-latest

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"@azure/arm-cosmosdb": "^15.0.0",
"@azure/arm-eventhub": "^5.1.0",
"@azure/arm-servicebus": "^5.0.0",
Expand Down
19 changes: 15 additions & 4 deletions src/commands/createFunctionApp/FunctionAppCreateStep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import { type NameValuePair, type Site, type SiteConfig, type WebSiteManagementClient } from '@azure/arm-appservice';
import { AuthorizationManagementClient } from '@azure/arm-authorization-profile-2020-09-01-hybrid';
import { BlobServiceClient } from '@azure/storage-blob';
import { ParsedSite, WebsiteOS, type CustomLocation, type IAppServiceWizardContext } from '@microsoft/vscode-azext-azureappservice';
import { LocationListStep } from '@microsoft/vscode-azext-azureutils';
Expand Down Expand Up @@ -56,7 +57,16 @@ export class FunctionAppCreateStep extends AzureWizardExecuteStep<IFunctionAppWi
context.telemetry.properties.fileLoggingError = parseError(error).message;
}
}

const principalId = nonNullProp(nonNullProp(context.site, 'identity'), 'principalId');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit cleaner to do

Suggested change
const principalId = nonNullProp(nonNullProp(context.site, 'identity'), 'principalId');
const principalId = nonNullValueAndProp(context.site.identity, 'principalId');

and I think it does the same thing.

// this is the same apiVersion being used by the portal
const apiVersion = '2020-06-01';
const amClient = new AuthorizationManagementClient(context.credentials, context.subscriptionId, { apiVersion });

const scope = nonNullProp(nonNullProp(context, 'storageAccount'), 'id');
const guid = crypto.randomUUID();
// this roleDefintionId cooresponds to the "Storage Blob Data Contributor" role
const roleDefinitionId = '/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe';
await amClient.roleAssignments.create(scope, guid, { properties: { roleDefinitionId, principalId } });
showSiteCreated(site, context);
}

Expand All @@ -73,7 +83,8 @@ export class FunctionAppCreateStep extends AzureWizardExecuteStep<IFunctionAppWi
serverFarmId: context.plan?.id,
clientAffinityEnabled: false,
siteConfig: await this.getNewSiteConfig(context, stack),
reserved: context.newSiteOS === WebsiteOS.linux // The secret property - must be set to true to make it a Linux plan. Confirmed by the team who owns this API.
reserved: context.newSiteOS === WebsiteOS.linux, // The secret property - must be set to true to make it a Linux plan. Confirmed by the team who owns this API.
identity: { type: 'SystemAssigned' }
};

if (context.customLocation) {
Expand Down Expand Up @@ -142,8 +153,8 @@ export class FunctionAppCreateStep extends AzureWizardExecuteStep<IFunctionAppWi
const storageConnectionString: string = (await getStorageConnectionString(context)).connectionString;
let appSettings: NameValuePair[] = [
{
name: ConnectionKey.Storage,
value: storageConnectionString
name: `${ConnectionKey.Storage}__accountName`,
value: context.newStorageAccountName ?? context.storageAccount?.name
Comment on lines +156 to +157
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where a lot of our customer scenarios will break since we relied on that setting for a lot, so still plenty of work to do there.

Can you outline which scenarios you expect to break? Have you verified them breaking?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Deployment: We rely/enforce having the AzureWebJobsStorage setting
  • Debugging: Same thing as above

Those are the main scenarios. We were discussing maybe having two different settings.json files-- one for remote and one for local settings. I'm not actually sure if the AzureWebJobsStorage__accountName setting works locally since you would need an app that has an identity with RBAC to the storage account. That's kind of the main push as to why we'd want to have two separate settings.

}
];

Expand Down
Loading