Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions sdk/resourcemanager/azure-resourcemanager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ See [API design][design] for general introduction on design and key concepts on

See [Samples][sample] for code snippets and samples.

See [runnable samples][samples_readme] for self-contained programs demonstrating common management scenarios.

## Troubleshooting

## Next steps
Expand All @@ -82,4 +84,5 @@ For details on contributing to this repository, see the [contributing guide](htt
[azure_core_http_netty]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/core/azure-core-http-netty
[authenticate]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/docs/AUTH.md
[sample]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/docs/SAMPLE.md
[samples_readme]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/README.md
[design]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/docs/DESIGN.md
2 changes: 1 addition & 1 deletion sdk/resourcemanager/azure-resourcemanager/assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "java",
"TagPrefix": "java/resourcemanager/azure-resourcemanager",
"Tag": "java/resourcemanager/azure-resourcemanager_ac929eccb7"
"Tag": "java/resourcemanager/azure-resourcemanager_b40f5da6f5"
}
23 changes: 23 additions & 0 deletions sdk/resourcemanager/azure-resourcemanager/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,29 @@
</configuration>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.6.1</version> <!-- {x-version-update;org.codehaus.mojo:build-helper-maven-plugin;external_dependency} -->
<executions>
<!-- Makes files under src/samples/resources available to samples (which run as tests). -->
<execution>
<id>add-samples-resources</id>
<phase>generate-test-resources</phase>
<goals>
<goal>add-test-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/samples/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
Expand Down
94 changes: 94 additions & 0 deletions sdk/resourcemanager/azure-resourcemanager/src/samples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
page_type: sample
languages:
- java
products:
- azure
urlFragment: azure-resourcemanager-samples
---

# Azure Resource Manager samples for Java

This contains Java samples for managing Azure resources with the Azure Resource Manager client library. Each sample is
self-contained, focuses on a specific scenario, and exposes a `main()` entrypoint so it can be run directly.

## Getting started

Getting started is explained in detail [here][RESOURCEMANAGER_README_GETTING_STARTED].
Please refer to it to add the dependency and configure the authentication environment variables.

For general documentation on how to use the management libraries, please [visit here][MGMT_SDK_LINK].
For additional code snippets grouped by service, see [SAMPLE.md][RESOURCEMANAGER_SAMPLE_DOC].

## Sample details

### App Service

- [Connect a web app to a SQL database (passwordless)][sample_connect_web_app_to_sql_database]
- [Connect a web app to a storage account (passwordless)][sample_connect_web_app_to_storage_account]
- [Deploy an image from Azure Container Registry to a Linux web app][sample_deploy_image_from_acr_to_linux_web_app]
- [Manage web app deployment slots][sample_manage_web_app_slots]
- [Manage a web app with a custom domain][sample_manage_web_app_with_custom_domain]
- [Scale a web app across multiple regions with a Traffic Manager][sample_scale_web_app_with_traffic_manager]

### Authorization (Microsoft Entra ID / RBAC)

- [Manage users, groups and roles][sample_manage_users_groups_and_roles]
- [Manage service principals][sample_manage_service_principal]

### Compute

- [Create a virtual machine from a custom image][sample_create_vm_using_custom_image_from_vm]
- [Create a virtual machine from a specialized managed disk (snapshot)][sample_create_vm_using_specialized_disk_from_snapshot]
- [Create multiple virtual machines in parallel in the same network][sample_manage_vms_in_parallel]

### Container Registry

- [Manage container registries][sample_manage_container_registry]

### Container Service

- [Manage an Azure Kubernetes Service (AKS) cluster][sample_manage_kubernetes_cluster]

### SQL Database

- [Create and manage a SQL database][sample_manage_sql_database]
- [Manage SQL databases across multiple regions][sample_manage_sql_databases_across_regions]

## Next steps

Start using the Azure Resource Manager Java SDK in your solutions. Our SDK details can be found at [SDK README][RESOURCEMANAGER_SDK_README].

For more information about other Azure Management SDKs, refer [here][MGMT_SDK_LINK].

## Contributing

For details on contributing to this repository, see the [contributing guide][RESOURCEMANAGER_README_CONTRIBUTING].

1. Fork it
1. Create your feature branch (`git checkout -b my-new-feature`)
1. Commit your changes (`git commit -am 'Add some feature'`)
1. Push to the branch (`git push origin my-new-feature`)
1. Create new Pull Request

<!-- LINKS -->
[MGMT_SDK_LINK]: https://aka.ms/azsdk/java/mgmt
[RESOURCEMANAGER_SDK_README]: https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/resourcemanager/azure-resourcemanager
[RESOURCEMANAGER_README_GETTING_STARTED]: https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/resourcemanager/azure-resourcemanager#getting-started
[RESOURCEMANAGER_README_CONTRIBUTING]: https://github.com/Azure/azure-sdk-for-java/blob/main/CONTRIBUTING.md
[RESOURCEMANAGER_SAMPLE_DOC]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/docs/SAMPLE.md
[sample_connect_web_app_to_sql_database]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/appservice/samples/ConnectWebAppToSqlDatabase.java
[sample_connect_web_app_to_storage_account]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/appservice/samples/ConnectWebAppToStorageAccount.java
[sample_deploy_image_from_acr_to_linux_web_app]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/appservice/samples/DeployImageFromAcrToLinuxWebApp.java
[sample_manage_web_app_slots]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/appservice/samples/ManageWebAppSlots.java
[sample_manage_web_app_with_custom_domain]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/appservice/samples/ManageWebAppWithCustomDomain.java
[sample_scale_web_app_with_traffic_manager]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/appservice/samples/ScaleWebAppWithTrafficManager.java
[sample_manage_users_groups_and_roles]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/authorization/samples/ManageUsersGroupsAndRoles.java
[sample_manage_service_principal]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/authorization/samples/ManageServicePrincipal.java
[sample_create_vm_using_custom_image_from_vm]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/compute/samples/CreateVirtualMachineUsingCustomImageFromVM.java
[sample_create_vm_using_specialized_disk_from_snapshot]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/compute/samples/CreateVirtualMachineUsingSpecializedDiskFromSnapshot.java
[sample_manage_vms_in_parallel]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/compute/samples/ManageVirtualMachinesInParallel.java
[sample_manage_container_registry]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/containerregistry/samples/ManageContainerRegistry.java
[sample_manage_kubernetes_cluster]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/containerservice/samples/ManageKubernetesCluster.java
[sample_manage_sql_database]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/sql/samples/ManageSqlDatabase.java
[sample_manage_sql_databases_across_regions]: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/sql/samples/ManageSqlDatabasesAcrossRegions.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,15 @@ public static boolean runSample(AzureResourceManager azureResourceManager) {

try {
// Create a web app with a system-assigned managed identity; that identity is used to reach SQL.
// HTTPS-only is enforced; minimum TLS 1.2 and FTPS-only are already the App Service defaults.
WebApp app = azureResourceManager.webApps()
.define(appName)
.withRegion(Region.US_WEST)
.withNewResourceGroup(rgName)
.withNewWindowsPlan(PricingTier.STANDARD_S1)
.withJavaVersion(JavaVersion.JAVA_11)
.withWebContainer(WebContainer.TOMCAT_9_0_NEWEST)
.withHttpsOnly(true)
.withSystemAssignedManagedServiceIdentity()
.create();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,41 @@
package com.azure.resourcemanager.appservice.samples;

import com.azure.core.credential.TokenCredential;
import com.azure.core.exception.HttpResponseException;
import com.azure.core.http.policy.HttpLogDetailLevel;
import com.azure.core.management.Region;
import com.azure.core.management.profile.AzureProfile;
import com.azure.core.models.AzureCloud;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.resourcemanager.AzureResourceManager;
import com.azure.resourcemanager.appservice.models.ConnectionStringType;
import com.azure.resourcemanager.appservice.models.JavaVersion;
import com.azure.resourcemanager.appservice.models.PricingTier;
import com.azure.resourcemanager.appservice.models.RuntimeStack;
import com.azure.resourcemanager.appservice.models.WebApp;
import com.azure.resourcemanager.appservice.models.WebContainer;
import com.azure.resourcemanager.authorization.models.BuiltInRole;
import com.azure.resourcemanager.resources.fluentcore.utils.ResourceManagerUtils;
import com.azure.resourcemanager.samples.SampleUtils;
import com.azure.resourcemanager.storage.models.StorageAccount;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.time.Duration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
* Azure App Service sample for connecting a web app to a storage account.
* - Create a storage account
* - Create a web app
* - Add the storage account connection string to the web app settings
* Azure App Service sample for connecting a web app to a storage account without secrets (passwordless).
* - Create a storage account with shared-key access disabled
* - Create a Node.js web app with a system-assigned managed identity
* - Grant that identity the Storage Blob Data Contributor role on the account
* - Expose only the blob endpoint (no account key or connection string) to the web app
* - Deploy a small Node.js app that reads/writes a blob using that managed identity
* <p>
* The deployed app authenticates to Blob storage with {@code DefaultAzureCredential}, which picks up the web app's
* managed identity. Its source is under {@code src/samples/resources/appservice/mi-blob-verify}.
*/
public final class ConnectWebAppToStorageAccount {

Expand All @@ -39,30 +55,57 @@ public static boolean runSample(AzureResourceManager azureResourceManager) {
final String containerName = SampleUtils.randomResourceName(azureResourceManager, "jcontainer", 20);

try {
// Create a storage account for the web app to use.
// Create a storage account with shared-key access disabled, so data-plane access requires
// Microsoft Entra credentials (passwordless) rather than an account key.
StorageAccount storageAccount = azureResourceManager.storageAccounts()
.define(storageName)
.withRegion(Region.JAPAN_EAST)
.withNewResourceGroup(rgName)
.disableSharedKeyAccess()
.create();

String accountKey = storageAccount.getKeys().get(0).value();
String connectionString = String.format("DefaultEndpointsProtocol=https;AccountName=%s;AccountKey=%s",
storageAccount.name(), accountKey);

// Create a web app and store the storage connection string in its settings.
// Create a Node.js web app with a system-assigned managed identity and expose only the blob endpoint.
// HTTPS-only is enforced here; minimum TLS 1.2 and FTPS-only are already the App Service defaults.
WebApp app = azureResourceManager.webApps()
.define(appName)
.withRegion(Region.JAPAN_EAST)
.withExistingResourceGroup(rgName)
.withNewWindowsPlan(PricingTier.STANDARD_S1)
.withJavaVersion(JavaVersion.JAVA_11)
.withWebContainer(WebContainer.TOMCAT_9_0_NEWEST)
.withConnectionString("storage.connectionString", connectionString, ConnectionStringType.CUSTOM)
.withAppSetting("storage.containerName", containerName)
.withNewLinuxPlan(PricingTier.STANDARD_S1)
.withBuiltInImage(RuntimeStack.NODEJS_22_LTS)
.withHttpsOnly(true)
.withSystemAssignedManagedServiceIdentity()
.withAppSetting("STORAGE_BLOB_ENDPOINT", storageAccount.endPoints().primary().blob())
.withAppSetting("STORAGE_CONTAINER_NAME", containerName)
.create();

// Grant the web app's managed identity data-plane access to blobs (least-privilege, passwordless).
azureResourceManager.accessManagement()
.roleAssignments()
.define(SampleUtils.randomUuid(azureResourceManager))
.forObjectId(app.systemAssignedManagedServiceIdentityPrincipalId())
.withBuiltInRole(BuiltInRole.STORAGE_BLOB_DATA_CONTRIBUTOR)
.withResourceScope(storageAccount)
.create();

// Deploy the small Node.js app that touches a blob using the web app's managed identity.
// A freshly created web app may briefly have an initial deployment in progress, so retry on HTTP 409.
File appPackage = nodeAppPackage();
for (int i = 0;; i++) {
try {
app.zipDeploy(appPackage);
break;
} catch (HttpResponseException e) {
if (i >= 5 || e.getResponse() == null || e.getResponse().getStatusCode() != 409) {
throw e;
}
ResourceManagerUtils.sleep(Duration.ofSeconds(30));
}
}

System.out.println("Connected web app " + app.name() + " to storage account " + storageAccount.name());
// To verify manually, browse to https://<app>.azurewebsites.net/ once role assignment has propagated;
// the app returns {"ok":true,...} when it can read/write a blob using its managed identity.
System.out.println("Verify passwordless access at: https://" + app.defaultHostname() + "/");
return true;
} finally {
azureResourceManager.resourceGroups().beginDeleteByName(rgName);
Expand Down Expand Up @@ -92,6 +135,41 @@ public static void main(String[] args) {
}
}

/**
* Builds a zip package (server.js + package.json) for the small Node.js verification app from the sample
* resources. The verifier has no npm dependencies, so App Service deploys it without a build step.
*
* @return the zip package file
*/
private static File nodeAppPackage() {
String[] files = { "server.js", "package.json" };
try {
File zipFile = File.createTempFile("mi-blob-verify", ".zip");
zipFile.deleteOnExit();
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) {
byte[] buffer = new byte[4096];
for (String file : files) {
zos.putNextEntry(new ZipEntry(file));
try (InputStream is = ConnectWebAppToStorageAccount.class
.getResourceAsStream("/appservice/mi-blob-verify/" + file)) {
if (is == null) {
throw new FileNotFoundException(
"Sample resource not found on classpath: /appservice/mi-blob-verify/" + file);
}
int read;
while ((read = is.read(buffer)) > 0) {
zos.write(buffer, 0, read);
}
}
zos.closeEntry();
}
}
return zipFile;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

private ConnectWebAppToStorageAccount() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public static boolean runSample(AzureResourceManager azureResourceManager) {
String privateImage = azureRegistry.loginServerUrl() + "/samples/tomcat:latest";

// Create a Linux web app that pulls its image from the private registry.
// HTTPS-only is enforced; minimum TLS 1.2 and FTPS-only are already the App Service defaults.
WebApp app = azureResourceManager.webApps()
.define(appName)
.withRegion(region)
Expand All @@ -60,6 +61,7 @@ public static boolean runSample(AzureResourceManager azureResourceManager) {
.withPrivateRegistryImage(privateImage, "https://" + azureRegistry.loginServerUrl())
.withCredentials(acrCredentials.username(), acrCredentials.accessKeys().get(AccessKeyType.PRIMARY))
.withAppSetting("PORT", "8080")
.withHttpsOnly(true)
.create();

System.out.println("Deployed image " + privateImage + " to web app " + app.defaultHostname());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ public static boolean runSample(AzureResourceManager azureResourceManager) {

try {
// Create a web app running Tomcat on a Windows plan.
// HTTPS-only is enforced; minimum TLS 1.2 and FTPS-only are already the App Service defaults.
WebApp app = azureResourceManager.webApps()
.define(appName)
.withRegion(Region.US_EAST)
.withNewResourceGroup(rgName)
.withNewWindowsPlan(PricingTier.STANDARD_S1)
.withJavaVersion(JavaVersion.JAVA_11)
.withWebContainer(WebContainer.TOMCAT_9_0_NEWEST)
.withHttpsOnly(true)
.create();

// Create a staging deployment slot that inherits the production configuration.
Expand Down
Loading
Loading