Search code examples
amazon-web-servicesazureinfrastructure-as-code

Can we use "normal" languages to build IaC in Microsoft Azure (similarly to AWS's CDK)?


From what I can tell, it appears that Microsoft Azure only allows YAML, Terraform, or Bicep for defining infrastructure in code. AWS's CDK, however, allows one to build out the infrastructure using common programming languages like C# and TypeScript (which I find much easier to work with than the above).

Am I missing something, or is there in fact a way to build Azure IaC with ordinary languages (either natively or via third-party frameworks)? Alternatively, does Microsoft intend on providing this functionality in the foreseeable future?


Solution

  • As I mentioned you can use Azure SDK to create any resources in Azure Subscription.

    Also as @Rui Jarimba mentioned pulumi also can be used.

    I have created Storage account with both method using C#.

    Azure SDK:

    In dotnet to create resource Azure.ResourceManager package is used.

    I am using the following packages;

    • Azure.ResourceManager.Storage for storage account creation.
    • Azure.Identity for authentication.
    • Azure.Core for other azure utilities.
    using Azure;
    using Azure.Core;
    using Azure.Identity;
    using Azure.ResourceManager;
    using Azure.ResourceManager.Storage;
    using Azure.ResourceManager.Resources;
    using Azure.ResourceManager.Storage.Models;
    
    
    class Program
    {
        static async Task Main(string[] args)
        {
            string subscriptionId = "xxxxxxxxxxxxxxxxxxxxx";
            string rgName = "Azure-SDK-RG";
            var credentials = new DefaultAzureCredential();
            var armClient = new ArmClient(credentials);
    
            SubscriptionResource subscription = armClient.GetSubscriptionResource(new ResourceIdentifier($"/subscriptions/{subscriptionId}")); // `GetSubscriptionResource` to be used when you have multiple subscription in tenant
    
            // for single or default subscription you can use 
            /*
            
            SubscriptionResource subscription = await armClient.GetDefaultSubscriptionAsync();
            
            */
    
            var location = AzureLocation.AustraliaEast;
    
            ArmOperation<ResourceGroupResource> operation = await subscription.GetResourceGroups().CreateOrUpdateAsync(WaitUntil.Completed, rgName, new ResourceGroupData(location));
            ResourceGroupResource resourceGroup = operation.Value;
    
            string accountName = "azuresdkstorage";
            var sku = new StorageSku(StorageSkuName.StandardGrs);
            var kind = StorageKind.Storage;
    
    
            var storageParameters = new StorageAccountCreateOrUpdateContent(sku,kind,location);
    
            var storageAccountResource = resourceGroup.GetStorageAccounts();
    
            ArmOperation<StorageAccountResource> armOperation = await storageAccountResource.CreateOrUpdateAsync(WaitUntil.Completed, accountName, storageParameters);
            var storageAccount = armOperation.Value;
    
            Console.WriteLine($"Storage Account '{storageAccount.Data.Name}' created successfully.");
        }
    }
    

    OUTPUT:

    For reference check this github document

    Pulumi:

    Requirements.

    • Install pulumi

    To create project I followed following steps:

    • pulumi new command to select template
    • azure-csharp template selected
    • provide project description (optional)
    • create a stack,

    default name dev

    • pulumi up to deploy the created code

    pulumi adds additional string in the name for unique-names

    using Pulumi;
    using Pulumi.AzureNative.Resources;
    using Pulumi.AzureNative.Storage;
    using Pulumi.AzureNative.Storage.Inputs;
    using System.Collections.Generic;
    
    return await Pulumi.Deployment.RunAsync(() =>
    {
        // Create an Azure Resource Group
        var resourceGroup = new ResourceGroup("pulumi-RG");
    
        // Create an Azure resource (Storage Account)
        var storageAccount = new StorageAccount("sa5aug", new StorageAccountArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Sku = new SkuArgs
            {
                Name = SkuName.Standard_LRS
            },
            Kind = Kind.StorageV2
        });
    
        var storageAccountKeys = ListStorageAccountKeys.Invoke(new ListStorageAccountKeysInvokeArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AccountName = storageAccount.Name
        });
    
        var primaryStorageKey = storageAccountKeys.Apply(accountKeys =>
        {
            var firstKey = accountKeys.Keys[0].Value;
            return Output.CreateSecret(firstKey);
        });
    
        return new Dictionary<string, object?>
        {
            ["primaryStorageKey"] = primaryStorageKey
        };
    });
    

    OUTPUT: