Code Monkey home page Code Monkey logo

arm2pulumi's Introduction

Slack GitHub Discussions NPM version Python version NuGet version GoDoc License Gitpod ready-to-code

Pulumi's Infrastructure as Code SDK is the easiest way to build and deploy infrastructure, of any architecture and on any cloud, using programming languages that you already know and love. Code and ship infrastructure faster with your favorite languages and tools, and embed IaC anywhere with Automation API.

Simply write code in your favorite language and Pulumi automatically provisions and manages your resources on AWS, Azure, Google Cloud Platform, Kubernetes, and 120+ providers using an infrastructure-as-code approach. Skip the YAML, and use standard language features like loops, functions, classes, and package management that you already know and love.

For example, create three web servers:

const aws = require("@pulumi/aws");
const sg = new aws.ec2.SecurityGroup("web-sg", {
    ingress: [{ protocol: "tcp", fromPort: 80, toPort: 80, cidrBlocks: ["0.0.0.0/0"] }],
});
for (let i = 0; i < 3; i++) {
    new aws.ec2.Instance(`web-${i}`, {
        ami: "ami-7172b611",
        instanceType: "t2.micro",
        vpcSecurityGroupIds: [sg.id],
        userData: `#!/bin/bash
            echo "Hello, World!" > index.html
            nohup python -m SimpleHTTPServer 80 &`,
    });
}

Or a simple serverless timer that archives Hacker News every day at 8:30AM:

const aws = require("@pulumi/aws");

const snapshots = new aws.dynamodb.Table("snapshots", {
    attributes: [{ name: "id", type: "S", }],
    hashKey: "id", billingMode: "PAY_PER_REQUEST",
});

aws.cloudwatch.onSchedule("daily-yc-snapshot", "cron(30 8 * * ? *)", () => {
    require("https").get("https://news.ycombinator.com", res => {
        let content = "";
        res.setEncoding("utf8");
        res.on("data", chunk => content += chunk);
        res.on("end", () => new aws.sdk.DynamoDB.DocumentClient().put({
            TableName: snapshots.name.get(),
            Item: { date: Date.now(), content },
        }).promise());
    }).end();
});

Many examples are available spanning containers, serverless, and infrastructure in pulumi/examples.

Pulumi is open source under the Apache 2.0 license, supports many languages and clouds, and is easy to extend. This repo contains the pulumi CLI, language SDKs, and core Pulumi engine, and individual libraries are in their own repos.

Welcome

  • Get Started with Pulumi: Deploy a simple application in AWS, Azure, Google Cloud, or Kubernetes using Pulumi.

  • Learn: Follow Pulumi learning pathways to learn best practices and architectural patterns through authentic examples.

  • Examples: Browse several examples across many languages, clouds, and scenarios including containers, serverless, and infrastructure.

  • Docs: Learn about Pulumi concepts, follow user-guides, and consult the reference documentation.

  • Registry: Find the Pulumi Package with the resources you need. Install the package directly into your project, browse the API documentation, and start building.

  • Pulumi Roadmap: Review the planned work for the upcoming quarter and a selected backlog of issues that are on our mind but not yet scheduled.

  • Community Slack: Join us in Pulumi Community Slack. All conversations and questions are welcome.

  • GitHub Discussions: Ask questions or share what you're building with Pulumi.

Getting Started

Watch the video

See the Get Started guide to quickly get started with Pulumi on your platform and cloud of choice.

Otherwise, the following steps demonstrate how to deploy your first Pulumi program, using AWS Serverless Lambdas, in minutes:

  1. Install:

    To install the latest Pulumi release, run the following (see full installation instructions for additional installation options):

    $ curl -fsSL https://get.pulumi.com/ | sh
  2. Create a Project:

    After installing, you can get started with the pulumi new command:

    $ mkdir pulumi-demo && cd pulumi-demo
    $ pulumi new hello-aws-javascript

    The new command offers templates for all languages and clouds. Run it without an argument and it'll prompt you with available projects. This command created an AWS Serverless Lambda project written in JavaScript.

  3. Deploy to the Cloud:

    Run pulumi up to get your code to the cloud:

    $ pulumi up

    This makes all cloud resources needed to run your code. Simply make edits to your project, and subsequent pulumi ups will compute the minimal diff to deploy your changes.

  4. Use Your Program:

    Now that your code is deployed, you can interact with it. In the above example, we can curl the endpoint:

    $ curl $(pulumi stack output url)
  5. Access the Logs:

    If you're using containers or functions, Pulumi's unified logging command will show all of your logs:

    $ pulumi logs -f
  6. Destroy your Resources:

    After you're done, you can remove all resources created by your program:

    $ pulumi destroy -y

To learn more, head over to pulumi.com for much more information, including tutorials, examples, and details of the core Pulumi CLI and programming model concepts.

Platform

Languages

Language Status Runtime Versions
JavaScript Stable Node.js Current, Active and Maintenance LTS versions
TypeScript Stable Node.js Current, Active and Maintenance LTS versions
Python Stable Python Supported versions
Go Stable Go Supported versions
.NET (C#/F#/VB.NET) Stable .NET Supported versions
Java Public Preview JDK 11+
YAML Stable n/a n/a

EOL Releases

The Pulumi CLI v1 and v2 are no longer supported. If you are not yet running v3, please consider migrating to v3 to continue getting the latest and greatest Pulumi has to offer! ๐Ÿ’ช

Clouds

Visit the Registry for the full list of supported cloud and infrastructure providers.

Contributing

Visit CONTRIBUTING.md for information on building Pulumi from source or contributing improvements.

arm2pulumi's People

Contributors

lukehoban avatar mikhailshilkov avatar viveklak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arm2pulumi's Issues

Sub resource links back to parent missing in code generated by arm2pulumi

Converting sub resources in arm templates to code requires establishing links back to the parent, e.g.:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "variables": {
    "profileName": "test-profile",
    "endpointName": "test-endpoint",
    "skuName": "Standard_Microsoft"
  },
  "resources": [
    {
      "name": "[variables('profileName')]",
      "type": "Microsoft.Cdn/profiles",
      "location": "northcentralus",
      "apiVersion": "2019-04-15",
      "sku": {
        "name": "[variables('skuName')]"
      },
      "resources": [
        {
          "apiVersion": "2019-04-15",
          "dependsOn": [
            "[resourceId('Microsoft.Cdn/profiles', variables('profileName'))]"
          ],
          "location": "northcentralus",
          "name": "[variables('endpointName')]",
          "type": "endpoints",
          "properties": {
            "originHostHeader": "astorageaccount.a33.web.core.windows.net",
            "isHttpAllowed": true,
            "isHttpsAllowed": true,
            "queryStringCachingBehavior": "IgnoreQueryString",
            "contentTypesToCompress": [
              "text/plain",
              "text/html"
            ],
            "isCompressionEnabled": true,
            "origins": [
              {
                "name": "origin",
                "properties": {
                  "hostName": "astorageaccount.a33.web.core.windows.net"
                }
              }
            ]
          },
          "resources":[
            {
              "apiVersion": "2019-04-15",
              "name": "Custom Domain",
              "type": "customDomains",
              "properties": {
                "hostName": "custom.domain.com"
              }
            }
          ]
        }
      ]
    }
  ],
  "outputs": {
  }
}

should convert to

import * as azure_nextgen from "@pulumi/azure-nextgen";
import * as pulumi from "@pulumi/pulumi";

const endpointNameVar = "test-endpoint";
const profileNameVar = "test-profile";
const config = new pulumi.Config();
const resourceGroupNameParam = config.require("resourceGroupNameParam");
const skuNameVar = "Standard_Microsoft";
const profileResource = new azure_nextgen.cdn.v20190415.Profile("profileResource", {
    location: "northcentralus",
    profileName: profileNameVar,
    resourceGroupName: resourceGroupNameParam,
    sku: {
        name: skuNameVar,
    },
});
const endpointResource = new azure_nextgen.cdn.v20190415.Endpoint("endpointResource", {
    contentTypesToCompress: [
        "text/plain",
        "text/html",
    ],
    endpointName: endpointNameVar,
    profileName: profileResource.name, // missing link back to parent
    isCompressionEnabled: true,
    isHttpAllowed: true,
    isHttpsAllowed: true,
    location: "northcentralus",
    originHostHeader: "astorageaccount.a33.web.core.windows.net",
    origins: [{
        hostName: "astorageaccount.a33.web.core.windows.net",
        name: "origin",
    }],
    queryStringCachingBehavior: "IgnoreQueryString",
    resourceGroupName: resourceGroupNameParam,
});
const customDomainResource = new azure_nextgen.cdn.v20190415.CustomDomain("customDomainResource", {
    customDomainName: `Custom Domain`,
    hostName: "custom.domain.com",
    resourceGroupName: resourceGroupNameParam,
    profileName: profileResource.name, // missing link back to parent
    endpointName: endpointResource.name, // missing link back to parent
});

Note the missing link back to parent items which are currently missing in the generated code.

Incomplete Conversion of an App Service

Hi! I tried to convert an App Service (Web App) that I exported from Azure Portal. It's not a particularly complicated site. When I ran the arm2pulumi tool, it gave me the warning about a partial conversion with the following message:

configResource no metadata found for resource type 'Microsoft.Web/sites/config' and version '2018-11-01'

I also noticed that the code generated just sort of stops with the WebApp.

SiteConfig = ,

The reason I call this out is I tried it earlier with a smaller site and it successfully generated code, but it did the same thing with SiteConfig.

arm2pulumi cannot handle storage account 'tier'

Hi,

I'm trying to convert an arm template for an azure storage account to pulumi using arm2pulumi (linux ubuntu 64bit). however, i get the following error

`2023/03/06 15:46:48 Starting render
Error: unknown property 'tier' among [name]

on program.pp line 311:
312: tier = "Standard"

Error: unknown property 'tier' among [name]

on program.pp line 311:
312: tier = "Standard"

Error: cannot traverse value of type union(object({name = union(enum(azure-native:storage/v20220901:SkuName(string): cty.StringVal("Standard_LRS"),cty.StringVal("Standard_GRS"),cty.StringVal("Standard_RAGRS"),cty.StringVal("Standard_ZRS"),cty.StringVal("Premium_LRS"),cty.StringVal("Premium_ZRS"),cty.StringVal("Standard_GZRS"),cty.StringVal("Standard_RAGZRS")), output(enum(azure-native:storage/v20220901:SkuName(string): cty.StringVal("Standard_LRS"),cty.StringVal("Standard_GRS"),cty.StringVal("Standard_RAGRS"),cty.StringVal("Standard_ZRS"),cty.StringVal("Premium_LRS"),cty.StringVal("Premium_ZRS"),cty.StringVal("Standard_GZRS"),cty.StringVal("Standard_RAGZRS"))), output(string), output(union(enum(azure-native:storage/v20220901:SkuName(string): cty.StringVal("Standard_LRS"),cty.StringVal("Standard_GRS"),cty.StringVal("Standard_RAGRS"),cty.StringVal("Standard_ZRS"),cty.StringVal("Premium_LRS"),cty.StringVal("Premium_ZRS"),cty.StringVal("Standard_GZRS"),cty.StringVal("Standard_RAGZRS")), string)), string, annotated(0xc03a4709c0))}, annotated(0xc03a470600)), output(object({name = union(enum(azure-native:storage/v20220901:SkuName(string): cty.StringVal("Standard_LRS"),cty.StringVal("Standard_GRS"),cty.StringVal("Standard_RAGRS"),cty.StringVal("Standard_ZRS"),cty.StringVal("Premium_LRS"),cty.StringVal("Premium_ZRS"),cty.StringVal("Standard_GZRS"),cty.StringVal("Standard_RAGZRS")), string)}, annotated(0xc03a470a80))), annotated(0xc03a470b40))

on program.pp line 311:
312: tier = "Standard"

2023/03/06 15:46:57 IR generation: 385 ms, program gen 9141 ms`

the arm template is as follows:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "storageAccounts_tu2tjvkutjz26sastate_name": {
      "type": "String"
    },
    "virtualNetworks_vnet_tu2tjvkutjz26_externalid": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2022-09-01",
      "kind": "StorageV2",
      "location": "westeurope",
      "name": "[parameters('storageAccounts_tu2tjvkutjz26sastate_name')]",
      "properties": {
        "accessTier": "Hot",
        "allowBlobPublicAccess": false,
        "encryption": {
          "keySource": "Microsoft.Storage",
          "requireInfrastructureEncryption": true,
          "services": {
            "blob": {
              "enabled": true,
              "keyType": "Account"
            },
            "file": {
              "enabled": true,
              "keyType": "Account"
            }
          }
        },
        "minimumTlsVersion": "TLS1_2",
        "networkAcls": {
          "bypass": "AzureServices",
          "defaultAction": "Deny",
          "ipRules": [
            {
              "action": "Allow",
              "value": "redacted-ip-address"
            }
          ],
          "resourceAccessRules": [],
          "virtualNetworkRules": [
            {
              "action": "Allow",
              "id": "[concat(parameters('virtualNetworks_vnet_tu2tjvkutjz26_externalid'), '/subnets/CoreSubnet')]",
              "state": "Succeeded"
            }
          ]
        },
        "publicNetworkAccess": "Enabled",
        "supportsHttpsTrafficOnly": true
      },
      "sku": {
        "name": "Standard_GRS",
        "tier": "Standard"
      },
      "tags": {
        "Purpose": "xxxx",
        "_0_WTWRegion": "xxxx",
        "_1_BusinessUnit": "xxxx",
        "_2_PointOfContact": "sdwd",
        "_3_BillingCode": "260",
        "_4_ApplicationCode": "NGIT",
        "_5_Environment": "Q",
        "client": "76e3921f-489b-4b7e-9547-xxxx",
        "client_application_id": "tu2tjvkutjz26",
        "env": "Q",
        "organization": "xxxx",
        "saexclude": "UC5",
        "service": "nimbuspoc01",
        "source": "azure",
        "terminationDate": "2023-03-08T08:09:39.8945983Z"
      },
      "type": "Microsoft.Storage/storageAccounts"
    },
    {
      "apiVersion": "2022-09-01",
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_tu2tjvkutjz26sastate_name'))]"
      ],
      "name": "[concat(parameters('storageAccounts_tu2tjvkutjz26sastate_name'), '/default')]",
      "properties": {
        "cors": {
          "corsRules": []
        },
        "deleteRetentionPolicy": {
          "allowPermanentDelete": false,
          "enabled": false
        }
      },
      "sku": {
        "name": "Standard_GRS",
        "tier": "Standard"
      },
      "type": "Microsoft.Storage/storageAccounts/blobServices"
    },
    {
      "apiVersion": "2022-09-01",
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_tu2tjvkutjz26sastate_name'))]"
      ],
      "name": "[concat(parameters('storageAccounts_tu2tjvkutjz26sastate_name'), '/default')]",
      "properties": {
        "cors": {
          "corsRules": []
        },
        "protocolSettings": {
          "smb": {}
        },
        "shareDeleteRetentionPolicy": {
          "days": 7,
          "enabled": true
        }
      },
      "sku": {
        "name": "Standard_GRS",
        "tier": "Standard"
      },
      "type": "Microsoft.Storage/storageAccounts/fileServices"
    },
    {
      "apiVersion": "2022-09-01",
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_tu2tjvkutjz26sastate_name'))]"
      ],
      "name": "[concat(parameters('storageAccounts_tu2tjvkutjz26sastate_name'), '/default')]",
      "properties": {
        "cors": {
          "corsRules": []
        }
      },
      "type": "Microsoft.Storage/storageAccounts/queueServices"
    },
    {
      "apiVersion": "2022-09-01",
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_tu2tjvkutjz26sastate_name'))]"
      ],
      "name": "[concat(parameters('storageAccounts_tu2tjvkutjz26sastate_name'), '/default')]",
      "properties": {
        "cors": {
          "corsRules": []
        }
      },
      "type": "Microsoft.Storage/storageAccounts/tableServices"
    },
    {
      "apiVersion": "2022-09-01",
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts/blobServices', parameters('storageAccounts_tu2tjvkutjz26sastate_name'), 'default')]",
        "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_tu2tjvkutjz26sastate_name'))]"
      ],
      "name": "[concat(parameters('storageAccounts_tu2tjvkutjz26sastate_name'), '/default/state')]",
      "properties": {
        "defaultEncryptionScope": "$account-encryption-key",
        "denyEncryptionScopeOverride": false,
        "immutableStorageWithVersioning": {
          "enabled": false
        },
        "publicAccess": "None"
      },
      "type": "Microsoft.Storage/storageAccounts/blobServices/containers"
    }
  ],
  "variables": {}
}

arm2pulumi template needed massaging

Currently, arm2pulumi produces code (C# tested) that isn't immediately useful and discards information.

Here's the original Azure RM Template input:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageAccounts_mnuposloadqueueae_name": {
            "defaultValue": "mnuposloadqueueae",
            "type": "String"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2019-06-01",
            "name": "[parameters('storageAccounts_mnuposloadqueueae_name')]",
            "location": "australiaeast",
            "sku": {
                "name": "Standard_LRS",
                "tier": "Standard"
            },
            "kind": "Storage",
            "properties": {
                "networkAcls": {
                    "bypass": "AzureServices",
                    "virtualNetworkRules": [],
                    "ipRules": [],
                    "defaultAction": "Allow"
                },
                "supportsHttpsTrafficOnly": false,
                "encryption": {
                    "services": {
                        "file": {
                            "keyType": "Account",
                            "enabled": true
                        },
                        "blob": {
                            "keyType": "Account",
                            "enabled": true
                        }
                    },
                    "keySource": "Microsoft.Storage"
                }
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/blobServices",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "sku": {
                "name": "Standard_LRS",
                "tier": "Standard"
            },
            "properties": {
                "cors": {
                    "corsRules": []
                },
                "deleteRetentionPolicy": {
                    "enabled": false
                }
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/fileServices",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "sku": {
                "name": "Standard_LRS",
                "tier": "Standard"
            },
            "properties": {
                "cors": {
                    "corsRules": []
                }
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/queueServices",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "properties": {
                "cors": {
                    "corsRules": []
                }
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/tableServices",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "properties": {
                "cors": {
                    "corsRules": []
                }
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/azure-webjobs-hosts')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/blobServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "properties": {
                "defaultEncryptionScope": "$account-encryption-key",
                "denyEncryptionScopeOverride": false,
                "publicAccess": "None"
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/azure-webjobs-secrets')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/blobServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "properties": {
                "defaultEncryptionScope": "$account-encryption-key",
                "denyEncryptionScopeOverride": false,
                "publicAccess": "None"
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/mnuposloadapiae')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/fileServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "properties": {
                "accessTier": "TransactionOptimized",
                "shareQuota": 5120,
                "enabledProtocols": "SMB"
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/queueServices/queues",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/createorder-handl')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/queueServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "properties": {
                "metadata": {}
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/queueServices/queues",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/createorder-mock')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/queueServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "properties": {
                "metadata": {}
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/queueServices/queues",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/createorder-mock-poison')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/queueServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "properties": {
                "metadata": {}
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/queueServices/queues",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/createorder-null')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/queueServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "properties": {
                "metadata": {}
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/queueServices/queues",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/pollordertatus')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/queueServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "properties": {
                "metadata": {}
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/queueServices/queues",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/posorderupdate')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/queueServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "properties": {
                "metadata": {}
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/queueServices/queues",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/posorderupdate-poison')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/queueServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ],
            "properties": {
                "metadata": {}
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/tableServices/tables",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/AzureWebJobsHostLogs202007')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/tableServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ]
        },
        {
            "type": "Microsoft.Storage/storageAccounts/tableServices/tables",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/AzureWebJobsHostLogs202008')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/tableServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ]
        },
        {
            "type": "Microsoft.Storage/storageAccounts/tableServices/tables",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/AzureWebJobsHostLogs202009')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/tableServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ]
        },
        {
            "type": "Microsoft.Storage/storageAccounts/tableServices/tables",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/AzureWebJobsHostLogs202010')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/tableServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ]
        },
        {
            "type": "Microsoft.Storage/storageAccounts/tableServices/tables",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccounts_mnuposloadqueueae_name'), '/default/AzureWebJobsHostLogscommon')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/tableServices', parameters('storageAccounts_mnuposloadqueueae_name'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_mnuposloadqueueae_name'))]"
            ]
        }
    ]
}

This is the output from arm2pulumi to C#:

using Pulumi;
using AzureNextGen = Pulumi.AzureNextGen;

class MyStack : Stack
{
    public MyStack()
    {
        var config = new Config();
        var storageAccountsMnuposloadqueueaeNameParam = config.Get("storageAccountsMnuposloadqueueaeNameParam") ?? "mnuposloadqueueae";
        var blobServiceResource = null;
        var containerResource = null;
        var containerResource0 = null;
        var fileServiceResource = null;
        var resourceGroupNameParam = config.Require("resourceGroupNameParam");
        var queueResource = new AzureNextGen.Storage.V20190601.Queue("queueResource", new AzureNextGen.Storage.V20190601.QueueArgs
        {
            Metadata = ,
            QueueName = $"{storageAccountsMnuposloadqueueaeNameParam}/default/createorder-handl",
            ResourceGroupName = resourceGroupNameParam,
        });
        var queueResource0 = new AzureNextGen.Storage.V20190601.Queue("queueResource0", new AzureNextGen.Storage.V20190601.QueueArgs
        {
            Metadata = ,
            QueueName = $"{storageAccountsMnuposloadqueueaeNameParam}/default/createorder-mock",
            ResourceGroupName = resourceGroupNameParam,
        });
        var queueResource1 = new AzureNextGen.Storage.V20190601.Queue("queueResource1", new AzureNextGen.Storage.V20190601.QueueArgs
        {
            Metadata = ,
            QueueName = $"{storageAccountsMnuposloadqueueaeNameParam}/default/createorder-mock-poison",
            ResourceGroupName = resourceGroupNameParam,
        });
        var queueResource2 = new AzureNextGen.Storage.V20190601.Queue("queueResource2", new AzureNextGen.Storage.V20190601.QueueArgs
        {
            Metadata = ,
            QueueName = $"{storageAccountsMnuposloadqueueaeNameParam}/default/createorder-null",
            ResourceGroupName = resourceGroupNameParam,
        });
        var queueResource3 = new AzureNextGen.Storage.V20190601.Queue("queueResource3", new AzureNextGen.Storage.V20190601.QueueArgs
        {
            Metadata = ,
            QueueName = $"{storageAccountsMnuposloadqueueaeNameParam}/default/pollordertatus",
            ResourceGroupName = resourceGroupNameParam,
        });
        var queueResource4 = new AzureNextGen.Storage.V20190601.Queue("queueResource4", new AzureNextGen.Storage.V20190601.QueueArgs
        {
            Metadata = ,
            QueueName = $"{storageAccountsMnuposloadqueueaeNameParam}/default/posorderupdate",
            ResourceGroupName = resourceGroupNameParam,
        });
        var queueResource5 = new AzureNextGen.Storage.V20190601.Queue("queueResource5", new AzureNextGen.Storage.V20190601.QueueArgs
        {
            Metadata = ,
            QueueName = $"{storageAccountsMnuposloadqueueaeNameParam}/default/posorderupdate-poison",
            ResourceGroupName = resourceGroupNameParam,
        });
        var queueServiceResource = null;
        var shareResource = null;
        var storageAccountResource = new AzureNextGen.Storage.V20190601.StorageAccount("storageAccountResource", new AzureNextGen.Storage.V20190601.StorageAccountArgs
        {
            AccountName = storageAccountsMnuposloadqueueaeNameParam,
            EnableHttpsTrafficOnly = false,
            Encryption = new AzureNextGen.Storage.V20190601.Inputs.EncryptionArgs
            {
                KeySource = "Microsoft.Storage",
                Services = new AzureNextGen.Storage.V20190601.Inputs.EncryptionServicesArgs
                {
                    Blob = new AzureNextGen.Storage.V20190601.Inputs.EncryptionServiceArgs
                    {
                        Enabled = true,
                        KeyType = "Account",
                    },
                    File = new AzureNextGen.Storage.V20190601.Inputs.EncryptionServiceArgs
                    {
                        Enabled = true,
                        KeyType = "Account",
                    },
                },
            },
            Kind = "Storage",
            Location = "australiaeast",
            NetworkRuleSet = new AzureNextGen.Storage.V20190601.Inputs.NetworkRuleSetArgs
            {
                Bypass = "AzureServices",
                DefaultAction = "Allow",
                IpRules = {},
                VirtualNetworkRules = {},
            },
            ResourceGroupName = resourceGroupNameParam,
            Sku = new AzureNextGen.Storage.V20190601.Inputs.SkuArgs
            {
                Name = "Standard_LRS",
                Tier = "Standard",
            },
        });
        var tableResource = new AzureNextGen.Storage.V20190601.Table("tableResource", new AzureNextGen.Storage.V20190601.TableArgs
        {
            ResourceGroupName = resourceGroupNameParam,
            TableName = $"{storageAccountsMnuposloadqueueaeNameParam}/default/AzureWebJobsHostLogs202007",
        });
        var tableResource0 = new AzureNextGen.Storage.V20190601.Table("tableResource0", new AzureNextGen.Storage.V20190601.TableArgs
        {
            ResourceGroupName = resourceGroupNameParam,
            TableName = $"{storageAccountsMnuposloadqueueaeNameParam}/default/AzureWebJobsHostLogs202008",
        });
        var tableResource1 = new AzureNextGen.Storage.V20190601.Table("tableResource1", new AzureNextGen.Storage.V20190601.TableArgs
        {
            ResourceGroupName = resourceGroupNameParam,
            TableName = $"{storageAccountsMnuposloadqueueaeNameParam}/default/AzureWebJobsHostLogs202009",
        });
        var tableResource2 = new AzureNextGen.Storage.V20190601.Table("tableResource2", new AzureNextGen.Storage.V20190601.TableArgs
        {
            ResourceGroupName = resourceGroupNameParam,
            TableName = $"{storageAccountsMnuposloadqueueaeNameParam}/default/AzureWebJobsHostLogs202010",
        });
        var tableResource3 = new AzureNextGen.Storage.V20190601.Table("tableResource3", new AzureNextGen.Storage.V20190601.TableArgs
        {
            ResourceGroupName = resourceGroupNameParam,
            TableName = $"{storageAccountsMnuposloadqueueaeNameParam}/default/AzureWebJobsHostLogscommon",
        });
        var tableServiceResource = null;
    }

}

and here is what I ended up with (transforming the Stack to ComponentResource to include in an existing Stack):

using Pulumi;
using Storage = Pulumi.AzureNextGen.Storage.V20190601;

class PosQueueSaArgs
{
    public Input<string> ResourceGroupName { get; set; } = "autobots";
    public Input<string> StorageAccountName { get; set; } = "mnuposautoqueueae";
}

class PosQueueSa : ComponentResource
{
    public PosQueueSa(string name, PosQueueSaArgs args, ComponentResourceOptions? options = null)
    : base("PQ", name, options)
    {
        //var config = new Config();
        //var storageAccountName = config.Get("storageAccountName") ?? "mnuposautoqueueae";
        //var blobServiceResource = null;
        //var containerResource = null;
        //var containerResource0 = null;
        //var fileServiceResource = null;
        //var resourceGroupName = config.Require("resourceGroupName");
        //var queueServiceResource = null;
        //var shareResource = null;
        var storageAccountResource = new Storage.StorageAccount("storageAccountResource", new Storage.StorageAccountArgs
        {
            AccountName = args.StorageAccountName,
            EnableHttpsTrafficOnly = false,
            Encryption = new Storage.Inputs.EncryptionArgs
            {
                KeySource = "Microsoft.Storage",
                Services = new Storage.Inputs.EncryptionServicesArgs
                {
                    Blob = new Storage.Inputs.EncryptionServiceArgs
                    {
                        Enabled = true,
                        KeyType = "Account",
                    },
                    File = new Storage.Inputs.EncryptionServiceArgs
                    {
                        Enabled = true,
                        KeyType = "Account",
                    },
                },
            },
            Kind = "Storage",
            Location = "australiaeast",
            NetworkRuleSet = new Storage.Inputs.NetworkRuleSetArgs
            {
                Bypass = "AzureServices",
                DefaultAction = "Allow",
                IpRules = {},
                VirtualNetworkRules = {},
            },
            ResourceGroupName = args.ResourceGroupName,
            Sku = new Storage.Inputs.SkuArgs
            {
                Name = "Standard_LRS",
                //Tier = "Standard",
            },
        });
        var queueResource = new Storage.Queue("queueResource", new Storage.QueueArgs
        {
            //Metadata = ,
            AccountName = storageAccountResource.Name,
            QueueName = "createorder-handl",
            ResourceGroupName = args.ResourceGroupName,
        });
        var queueResource0 = new Storage.Queue("queueResource0", new Storage.QueueArgs
        {
            //Metadata = ,
            AccountName = storageAccountResource.Name,
            QueueName = "createorder-mock",
            ResourceGroupName = args.ResourceGroupName,
        });
        var queueResource1 = new Storage.Queue("queueResource1", new Storage.QueueArgs
        {
            //Metadata = ,
            AccountName = storageAccountResource.Name,
            QueueName = "createorder-mock-poison",
            ResourceGroupName = args.ResourceGroupName,
        });
        var queueResource2 = new Storage.Queue("queueResource2", new Storage.QueueArgs
        {
            //Metadata = ,
            AccountName = storageAccountResource.Name,
            QueueName = "createorder-null",
            ResourceGroupName = args.ResourceGroupName,
        });
        var queueResource3 = new Storage.Queue("queueResource3", new Storage.QueueArgs
        {
            //Metadata = ,
            AccountName = storageAccountResource.Name,
            QueueName = "pollordertatus",
            ResourceGroupName = args.ResourceGroupName,
        });
        var queueResource4 = new Storage.Queue("queueResource4", new Storage.QueueArgs
        {
            //Metadata = ,
            AccountName = storageAccountResource.Name,
            QueueName = "posorderupdate",
            ResourceGroupName = args.ResourceGroupName,
        });
        var queueResource5 = new Storage.Queue("queueResource5", new Storage.QueueArgs
        {
            //Metadata = ,
            AccountName = storageAccountResource.Name,
            QueueName = "posorderupdate-poison",
            ResourceGroupName = args.ResourceGroupName,
        });
        var tableResource = new Storage.Table("tableResource", new Storage.TableArgs
        {
            AccountName = storageAccountResource.Name,
            ResourceGroupName = args.ResourceGroupName,
            TableName = "AzureWebJobsHostLogs202007",
        });
        var tableResource0 = new Storage.Table("tableResource0", new Storage.TableArgs
        {
            AccountName = storageAccountResource.Name,
            ResourceGroupName = args.ResourceGroupName,
            TableName = "AzureWebJobsHostLogs202008",
        });
        var tableResource1 = new Storage.Table("tableResource1", new Storage.TableArgs
        {
            AccountName = storageAccountResource.Name,
            ResourceGroupName = args.ResourceGroupName,
            TableName = "AzureWebJobsHostLogs202009",
        });
        var tableResource2 = new Storage.Table("tableResource2", new Storage.TableArgs
        {
            AccountName = storageAccountResource.Name,
            ResourceGroupName = args.ResourceGroupName,
            TableName = "AzureWebJobsHostLogs202010",
        });
        var tableResource3 = new Storage.Table("tableResource3", new Storage.TableArgs
        {
            AccountName = storageAccountResource.Name,
            ResourceGroupName = args.ResourceGroupName,
            TableName = "AzureWebJobsHostLogscommon",
        });
        //var tableServiceResource = null;
    }
}

Notice that I had to make the following changes:
a) all the "Metadata = ," lines errored out
b) all the "var = ... null" lines errored out
c) lines that were commented out to prevent errors turned out to not be used or required
d) the required AccountName parameter for each Queue and Table resource was omitted
e) the Queue resources were declared before the StorageAccountResource and had no stated dependency on it
f) there was no way for Pulumi to work out that Queue and Tables resources depended on StorageAccountResource
g) even though the Table resources were declared after the StorageAccountResource there was no stated dependency
h) the fully specified TableName and QueueName parameters were always too long (e.g. error: azure-nextgen:storage/v20190601:Table resource 'tableResource3' has a problem: 'tableName' is too long (64): at most 63 characters allowed)
i) the TableName parameters had unexpected characters (e.g. error: azure-nextgen:storage/v20190601:Table resource 'tableResource3' has a problem: 'tableName' does not match expression '^[A-Za-z][A-Za-z0-9]{2,62}$')
j) not all original information in the template makes it through to complete C# code (e.g. dependsOn, fileServiceResource, queueServiceResource, shareResource, blobServices, containers)

[arm2pulumi] Tracker for resources missing support

This is a list of known resources that aren't being converted by arm2pulumi. The reasons for the missing resources are varied - e.g. missing in REST API or singletons which are not being processed correctly. However, this should provide the up-to-date state of providers and resources which aren't working at the moment.

TODO: Group by reasons for missing support.

'Microsoft.ApiManagement/service/groups/users'
'Microsoft.ApiManagement/service/products/apis'
'Microsoft.ApiManagement/service/providers/diagnosticSettings'
'Microsoft.Authorization/roleAssignments'
'Microsoft.Automation/automationAccounts'
'Microsoft.Automation/automationAccounts/credentials'
'Microsoft.Automation/automationAccounts/jobSchedules'
'Microsoft.Automation/automationAccounts/modules'
'Microsoft.Automation/automationAccounts/schedules'
'Microsoft.Automation/automationAccounts/variables'
'Microsoft.Backup/BackupVault/registeredContainers/protectedItems'
'Microsoft.Cache/Redis'
'Microsoft.Cache/redis/providers/diagnosticsettings'
'Microsoft.Compute/virtualMachines/providers/roleAssignments'
'Microsoft.CustomProviders/resourceProviders/customResources'
'Microsoft.DataFactory/dataFactories/gateways'
'Microsoft.DataFactory/datafactories'
'Microsoft.DataFactory/datafactories/dataPipelines'
'Microsoft.DataFactory/datafactories/datasets'
'Microsoft.DataFactory/datafactories/gateways'
'Microsoft.DataFactory/datafactories/linkedservices'
'Microsoft.DataLakeStore/accounts'
'Microsoft.DocumentDB/databaseAccounts/providers/advancedThreatProtectionSettings'
'Microsoft.EventGrid/topics/providers/eventSubscriptions'
'Microsoft.KeyVault/vaults/accessPolicies'
'Microsoft.KeyVault/vaults/providers/diagnosticsettings'
'Microsoft.KeyVault/vaults/secrets'
'Microsoft.Maps/accounts/providers/roleAssignments'
'Microsoft.Network/dnsZones/A'
'Microsoft.Network/frontdoors/providers/diagnosticsettings'
'Microsoft.Network/localNetworkGateways'
'Microsoft.Network/networkProfiles/providers/roleAssignments'
'Microsoft.Network/privateDnsZones'
'Microsoft.Network/privateDnsZones/virtualNetworkLinks'
'Microsoft.Network/trafficManagerProfiles'
'Microsoft.Network/trafficManagerProfiles/azureEndpoints'
'Microsoft.Network/virtualNetworkGateways'
'Microsoft.RecoveryServices/vaults'
'Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers'
'Microsoft.RecoveryServices/vaults/backupPolicies'
'Microsoft.RecoveryServices/vaults/backupstorageconfig'
'Microsoft.RecoveryServices/vaults/providers/diagnosticSettings'
'Microsoft.Relay/namespaces/providers/roleAssignments'
'Microsoft.Sql/servers'
'Microsoft.Sql/servers/auditingSettings'
'Microsoft.Sql/servers/connectionPolicies'
'Microsoft.Sql/servers/databases'
'Microsoft.Sql/servers/databases/extensions'
'Microsoft.Sql/servers/databases/providers/diagnosticSettings'
'Microsoft.Sql/servers/databases/securityAlertPolicies'
'Microsoft.Sql/servers/databases/transparentDataEncryption'
'Microsoft.Sql/servers/encryptionProtector'
'Microsoft.Sql/servers/failoverGroups'
'Microsoft.Sql/servers/firewallRules'
'Microsoft.Sql/servers/securityAlertPolicies'
'Microsoft.Storage/storageAccounts/blobServices'
'Microsoft.Storage/storageAccounts/blobServices/containers'
'Microsoft.Storage/storageAccounts/blobServices/containers'
'Microsoft.Storage/storageAccounts/fileServices'
'Microsoft.Storage/storageAccounts/fileServices'
'Microsoft.Storage/storageAccounts/fileServices/shares'
'Microsoft.Storage/storageAccounts/fileServices/shares'
'Microsoft.Storage/storageAccounts/providers/advancedThreatProtectionSettings'
'Microsoft.Storage/storageAccounts/providers/roleAssignments'
'Microsoft.Storage/storageAccounts/queueServices'
'Microsoft.Storage/storageAccounts/queueServices/queues'
'Microsoft.Storage/storageAccounts/tableServices'
'Microsoft.Storage/storageAccounts/tableServices/tables'
'Microsoft.StreamAnalytics/StreamingJobs'
'Microsoft.Synapse/workspaces/managedIdentitySqlControlSettings'
'Microsoft.Synapse/workspaces/sqlPools/metadataSync'
'Microsoft.Web/Sites/Extensions'
'Microsoft.Web/Sites/config'
'Microsoft.Web/connections'
'Microsoft.Web/sites/config'
'Microsoft.Web/sites/extensions'
'Microsoft.Web/sites/networkConfig'
'Microsoft.Web/sites/providers/links'
'Microsoft.Web/sites/sourcecontrols'
'microsoft.visualstudio/account/project'

[arm2pulumi] object parameters w/ default value results in compilation issue

Given the following ARM template:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "resourceTags": {
        "type": "object",
        "defaultValue": {
          "BU1": "BusinessName"
        }
      }
    },
    "resources": [
      {
        "type": "Microsoft.Storage/storageAccounts",
        "name": "someAccountName",
        "apiVersion": "2016-12-01",
        "location": "CentralUS",
        "tags": "[parameters('resourceTags')]",
        "kind": "Storage",
        "sku": {
          "name": "Standard_LRS"
        }
      },
    ],
  }

Converting it to C# results in

using Pulumi;
using AzureNextGen = Pulumi.AzureNextGen;

class MyStack : Stack
{
    public MyStack()
    {
        var config = new Config();
        var resourceGroupNameParam = config.Require("resourceGroupNameParam");
        var resourceTagsParam = config.GetObject<dynamic>("resourceTagsParam") ?? 
        {
            { "BU1", "BusinessName" },
        };
        var someAccountName = new AzureNextGen.Storage.V20161201.StorageAccount("someAccountName", new AzureNextGen.Storage.V20161201.StorageAccountArgs
        {
            AccountName = "someAccountName",
            Kind = "Storage",
            Location = "CentralUS",
            ResourceGroupName = resourceGroupNameParam,
            Sku = new AzureNextGen.Storage.V20161201.Inputs.SkuArgs
            {
                Name = "Standard_LRS",
            },
            Tags = resourceTagsParam,
        });
    }
}

The problem lines are

        var resourceTagsParam = config.GetObject<dynamic>("resourceTagsParam") ??
        {
            { "BU1", "Winfield United" },
        };

which has compilation errors:

image

String concatenation should use Output.Format

[concat(parameters('resourceNamePrefix'),'storage')] converts to
$"{resourceNamePrefixParam}storage", but it should convert to
Output.Format($"{resourceNamePrefixParam}storage")

ARM

{  
	"$schema":"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
	"contentVersion":"1.0.0.0",
	"parameters":{  
	   "resourceNamePrefix":{  
		  "defaultValue":"[resourceGroup().name]",
		  "type":"string",
		  "metadata":{  
			 "description":"Prefix for resource names."
		  }
	   },
	},
	"variables":{},
	"resources":[  
        {
          "type": "Microsoft.Storage/storageAccounts",
          "apiVersion": "2019-06-01",
          "name":"[concat(parameters('resourceNamePrefix'),'storage')]",
          "location":"[resourceGroup().location]",
          "sku": {
            "name": "Standard_LRS"
          },
          "kind": "StorageV2",
          "properties": {}
        }
    ]
  }

C#

using Pulumi;
using AzureNextGen = Pulumi.AzureNextGen;

class MyStack : Stack
{
    public MyStack()
    {
        var config = new Config();
        var resourceGroupNameParam = config.Require("resourceGroupNameParam");
        var resourceGroupVar = Output.Create(AzureNextGen.Resources.Latest.GetResourceGroup.InvokeAsync(new AzureNextGen.Resources.Latest.GetResourceGroupArgs
        {
            ResourceGroupName = resourceGroupNameParam,
        }));
        var resourceNamePrefixParam = Output.Create(config.Get("resourceNamePrefixParam")) ?? resourceGroupVar.Apply(resourceGroupVar => resourceGroupVar.Name);
        var storageAccountResource = new AzureNextGen.Storage.V20190601.StorageAccount("storageAccountResource", new AzureNextGen.Storage.V20190601.StorageAccountArgs
        {
            AccountName = $"{resourceNamePrefixParam}storage",
            Kind = "StorageV2",
            Location = resourceGroupVar.Apply(resourceGroupVar => resourceGroupVar.Location),
            ResourceGroupName = resourceGroupNameParam,
            Sku = new AzureNextGen.Storage.V20190601.Inputs.SkuArgs
            {
                Name = "Standard_LRS",
            },
        });
    }
}

arm2pulumi Unable to generate completely

What happened?

Hi All,
I'm trying my first project with pulumi. I had created some resources in the Azure portal. I exported the same as json file. I copied the contents of template.json file in the arm2pulumi input box. The out was generated with below error

collectionResource no metadata found for resource type 'Microsoft.DocumentDB/databaseAccounts/mongodbDatabases/collections' and version '2023-03-15'
storageAccountResource no metadata found for resource type 'Microsoft.Storage/storageAccounts' and version '2022-09-01'
mongodbDatabaseResource no metadata found for resource type 'Microsoft.DocumentDB/databaseAccounts/mongodbDatabases' and version '2023-03-15'
fileServiceResource no metadata found for resource type 'Microsoft.Storage/storageAccounts/fileServices' and version '2022-09-01'
tableServiceResource no metadata found for resource type 'Microsoft.Storage/storageAccounts/tableServices' and version '2022-09-01'
queueResource no metadata found for resource type 'Microsoft.Storage/storageAccounts/queueServices/queues' and version '2022-09-01'
queueServiceResource no metadata found for resource type 'Microsoft.Storage/storageAccounts/queueServices' and version '2022-09-01'
databaseAccountResource no metadata found for resource type 'Microsoft.DocumentDB/databaseAccounts' and version '2023-03-15'
blobServiceResource no metadata found for resource type 'Microsoft.Storage/storageAccounts/blobServices' and version '2022-09-01'
collectionResource0 no metadata found for resource type 'Microsoft.DocumentDB/databaseAccounts/mongodbDatabases/collections' and version '2023-03-15'

Expected Behavior

I expected the code to be generated with out errors.

Steps to reproduce

Please use the Azure resource template in the attached zip file and try it yourself in the tool
ExportedTemplate-caliber.zip

Output of pulumi about

generated source code attached herewith and error stated above
arm2pulumi.zip

Additional context

No response

Contributing

Vote on this issue by adding a ๐Ÿ‘ reaction.
To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

[arm2pulumi] KeyVault SkuArgs incorrect

Given the following template:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "key_name": {
            "defaultValue": "keyvault-01",
            "type": "String"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.KeyVault/vaults",
            "apiVersion": "2016-10-01",
            "name": "[parameters('key_name')]",
            "location": "westeurope",
            "properties": {
                "sku": {
                    "family": "A",
                    "name": "Standard"
                },
                "tenantId": "xxxxxx",
                "accessPolicies": [],
                "enabledForDeployment": false,
                "enabledForDiskEncryption": false,
                "enabledForTemplateDeployment": false,
                "enableSoftDelete": true
            }
        }
    ]
}

which produces the following C# code:

using Pulumi;
using AzureNextGen = Pulumi.AzureNextGen;

class MyStack : Stack
{
    public MyStack()
    {
        var config = new Config();
        var keyNameParam = config.Get("keyNameParam") ?? "keyvault-01";
        var resourceGroupNameParam = config.Require("resourceGroupNameParam");
        var vaultResource = new AzureNextGen.KeyVault.V20161001.Vault("vaultResource", new AzureNextGen.KeyVault.V20161001.VaultArgs
        {
            Location = "westeurope",
            Properties = new AzureNextGen.KeyVault.V20161001.Inputs.VaultPropertiesArgs
            {
                AccessPolicies = {},
                EnableSoftDelete = true,
                EnabledForDeployment = false,
                EnabledForDiskEncryption = false,
                EnabledForTemplateDeployment = false,
                Sku = new AzureNextGen.KeyVault.V20161001.Inputs.SkuArgs
                {
                    Family = "A",
                    Name = "Standard",
                },
                TenantId = "xxxx",
            },
            ResourceGroupName = resourceGroupNameParam,
            VaultName = keyNameParam,
        });
    }

}

which is not correct since SkuArgs.Name expects an SkuName and not a string.

The expected output should be

Name = SkuName.Standard

[arm2pulumi] Empty objects are not converted to anything

Take the following example ARM resource:

{
	"apiVersion": "2015-05-01",
	"name": "ExampleAppName",
	"type": "microsoft.insights/components",
	"location": "centralus",
	"tags": {},
	"properties": {
		"ApplicationId": "[parameters('name')]",
		"Request_Source": "IbizaWebAppExtensionCreate"
	}
}

When converted, it results as:

var exampleAppName = Component("exampleAppName", new ComponentArgs
{
	Location = "centralus",
	RequestSource = "IbizaWebAppExtensionCreate",
	ResourceGroupName = resourceGroupNameParam,
	ResourceName = "ExampleAppName",
	Tags = ,
});

It should probably be

Tags = { },

arm2pulumi v2 fails for explicit versions of types

Disabled template test for testdata/templates/quickstart/storageAccount.json for go fails with:

@@ -33,3 +33,3 @@
                        ResourceGroupName: pulumi.String(resourceGroupNameParam),
-                       Sku: &storage.SkuArgs{
+                       Sku: &v20210201.SkuArgs{
                                Name: pulumi.String(storageAccountTypeParam),

Generated string concatenation is not correct

Generated string concatenation should use Output.Format() when necessary

Repro:

Convert this ARM template:

{  
	"$schema":"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
	"contentVersion":"1.0.0.0",
	"parameters":{  
	   "ResourceNamePrefix":{  
		  "defaultValue":"[resourceGroup().name]",
		  "type":"string",
		  "metadata":{  
			 "description":"Prefix for resource names."
		  }
	   }
	},
	"resources":[  
	   {
		"type": "Microsoft.Storage/storageAccounts",
		"apiVersion": "2019-06-01",
		"name": "[concat(parameters('ResourceNamePrefix'),'storage')]",
		"location": "[resourceGroup().location]",
		"sku": {
			"name": "Standard_LRS",
			"tier": "Standard"
		},
		"kind": "Storage"
	  }
	]
  }

ACTUAL:

[concat(parameters('ResourceNamePrefix'),'storage')] is converted to $"{resourceNamePrefixParam}storage"

which results in something like Output<T>storage

EXPECTED:

[concat(parameters('ResourceNamePrefix'),'storage')] is converted to Output.Format($"{resourceNamePrefixParam}storage")

Accepts any language without validation

What happened?

arm2pulumi $template csharp seemed to work fine. On a closer look, it printed only the intermediate representation, but no code at all. That is because the argument needs to be dotnet. In fact, any argument like foo will seemingly work.

Expected Behavior

An error or at least a warning that csharp or foo are not supported languages.

Steps to reproduce

see above

Output of pulumi about

arm2pulumi is from the latest azure-native v1.102.0.

Additional context

No response

Contributing

Vote on this issue by adding a ๐Ÿ‘ reaction.
To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

Non-deterministic result when translating certain inputs

Certain ARM template inputs seem to cause non-deterministic output when passed through the converter tool. Specifically, they either return a partial conversion (with the accompanying diagnostic message) or a fatal error (detected cycle in <some>Resource). Additionally, the specific diagnostic message sometimes varies between runs, as well as the resource the cycle is detected in.

Here are some example templates that cause this with some additional information based on manual trials done via arm2pulumi.

  • https://github.com/Azure/azure-quickstart-templates/tree/master/101-asev2-appservice-sql-vpngw
    • Sometimes gives partial conversions, sometimes give cycle error (using web UI for conversion)
    • Partial conversion diagnostics:
      vaultResource  NYI: 'subscription' not supported as yet
      vaultResource  NYI: 'resourceId' not supported as yet
      vaultResource  NYI: 'resourceId' not supported as yet
      serverResource  NYI: 'subscription' not supported as yet
      siteResource  NYI: 'resourceId' not supported as yet
      privateDbDnsZoneNameParam  NYI: 'environment' not supported as yet
      administratorResource  NYI: 'subscription' not supported as yet
      vmNameVar  NYI: 'substring' not supported as yet
      containerResource  no metadata found for resource type 'Microsoft.Storage/storageAccounts/blobServices/containers' and version '2019-06-01'
      configResource  no metadata found for resource type 'Microsoft.Web/sites/config' and version '2020-06-01'
      loginUserVar  NYI: 'substring' not supported as yet
      
    • Fatal error message: detected cycle at serverfarmResource or detected cycle at siteResource
  • https://github.com/Azure/azure-quickstart-templates/tree/master/101-sql-logical-server
    • Sometimes gives partial conversions, sometimes give cycle error (using web UI for conversion)
    • Partial conversion diagnostics:
      subscriptionIdVar  NYI: 'subscription' not supported as yet
      uniqueStorageVar  NYI: 'uniqueString' not supported as yet
      storageNameVar  NYI: 'tolower' not supported as yet
      vulnerabilityAssessmentResource  NYI: 'if' not supported as yet
      storageBlobContributorVar  NYI: 'subscriptionResourceId' not supported as yet
      securityAlertPolicyResource  no metadata found for resource type 'Microsoft.Sql/servers/securityAlertPolicies' and version '2020-02-02-preview'
      serverNameParam  NYI: 'uniqueString' not supported as yet
      uniqueRoleGuidVar  NYI: 'guid' not supported as yet
      serverResource  NYI: 'if' not supported as yet
      serverResource  NYI: 'if' not supported as yet
      roleAssignmentResource  NYI: 'resourceId' not supported as yet
      connectionPolicyResource  no metadata found for resource type 'Microsoft.Sql/servers/connectionPolicies' and version '2014-04-01'
      
    • Fatal error message: detected cycle at vulnerabilityAssessmentResource
  • https://github.com/Azure/azure-quickstart-templates/tree/master/101-redis-cache
    • Sometimes gives partial conversions, sometimes give cycle error (using web UI for conversion)
    • Partial conversion diagnostics: diagnosticsettingResource NYI: 'format' not supported as yet
      • Still occasionally got cycle fatal error when that 'format' parameter was removed
      • All conversion errors (including fatal) disappeared if that resource was removed completely though (not sure about resulting code compiling, etc.)
    • Fatal error message: detected cycle at diagnosticsettingResource
  • https://github.com/Azure/azure-quickstart-templates/tree/master/101-functions-managed-identity
    • Sometimes gives partial conversions, sometimes give cycle error (using web UI for conversion)
    • Partial conversion diagnostics:
      siteResource  NYI: 'environment' not supported as yet
      siteResource  NYI: 'environment' not supported as yet
      siteResource  NYI: 'toLower' not supported as yet
      siteResource  NYI: 'resourceId' not supported as yet
      componentResource  NYI: 'environment' not supported as yet
      storageAccountNameVar  NYI: 'uniquestring' not supported as yet
      functionAppNameParam  NYI: 'uniqueString' not supported as yet
      principalIdOut  NYI: 'resourceId' not supported as yet
      
    • Fatal error message: detected cycle at siteResource
  • https://github.com/Azure/azure-quickstart-templates/tree/master/101-custom-rp-with-function
    • Sometimes gives partial conversions, sometimes give cycle error (using web UI for conversion)
    • Partial conversion diagnostics:
      funcNameParam  NYI: 'uniqueString' not supported as yet
      storageAccountNameParam  NYI: 'uniqueString' not supported as yet
      siteResource  NYI: 'listKeys' not supported as yet
      siteResource  NYI: 'toLower' not supported as yet
      siteResource  NYI: 'uri' not supported as yet
      resourceProviderResource  NYI: 'listSecrets' not supported as yet
      customResourceResource  no metadata found for resource type 'Microsoft.CustomProviders/resourceProviders/customResources' and version '2018-09-01-preview'
      
  • Fatal error message: detected cycle at resourceProviderResource

Generated parameter expressions don't assign as expected

Generated parameter expressions, that involve use of Output<T>, never make use of the right side of the null coalesce operator.

var functionAppNameParam = Output.Create(config.Get("functionAppNameParam")) 
    ?? resourceGroupVar.Apply(resourceGroupVar => $"{resourceGroupVar.Name}func");

This is wrong because Output.Create() can never be null and so the right side of the null coalesce operator can never be evaluated.

It actually needs to be

var functionAppNameParam = config.Get("functionAppNameParam") is string functionAppNameParamString
    ? Output.Create(functionAppNameParamString) 
    : resourceGroupVar.Apply(resourceGroupVar => Output.Format($"{resourceGroupVar.Name}func"));

Example ARM template:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "functionAppName": {
            "defaultValue": "[concat(resourceGroup().name, 'func')]",
            "type": "String",
        },
    },
    "variables": {
        "someOtherName": "[parameters('functionAppName')]",
    },
    "resources": [
    ]
}

arm2pulumi: Not handling case-insensitivity correctly

If I have a variable declared, as, say, "VNetName," ARM templates are case-insensitive and will work even if later I reference that variable as, say, "VnetName."
However, arm2pulumi fails when trying to convert an ARM template with those sorts of case changes.
It appears to be related to a virtual network name and/or related references.

An ARM template that demonstrates this can be provided on demand.

arm2pulumi Various issues converting CDN-oriented ARM template to typescript

How to recreate:
Convert this ARM template to pulumi typescript
https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/201-cdn-with-ruleseengine-rewriteandredirect/azuredeploy.json

The generated code will have a few "compile" time issue and a run time issue.

"compile" time issues:

  • The deliveryPolicy section uses "@odata.type" as the property name when it should be odataType
  • The deliveryPolicy section uses strings for the order property value when it should be a number.
  • The generated code creates a profile resource but doesn't reference it in the endpoint resource.

"run" time issue

  • The generated code sets the endpoint name to \${profileNameParam}/${endpointNameParam}`but Azure doesn't appear to like this naming convention. Using justendpointNameParam` works.

I've attached a copy of the generated code with the corrections (and a few other changes I made for testing purposes).
index_ts.txt

Failure translating default sub-resources

There are a number of default/singleton sub-resources commonly seen in ARM templates. Normally sub resources follow the pattern of API path URL: parent-type + parent-name + sub-resource type but many of these default sub-resources have distinct handling requirements:
e.g.

{
      "type": "Microsoft.Web/sites",
      "apiVersion": "2019-08-01",
      "name": "[variables('functionAppName')]",
      "location": "[parameters('location')]",
      ...
      "resources": [
        {
          "type": "config", # can also be networkConfig
          "apiVersion": "2019-08-01",
          "name": "virtualNetwork",
          "properties": {
            "subnetResourceId": ...,
            "isSwift": true
          }
        }
      ]
    }

corresponds to "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/networkConfig/virtualNetwork"

Using the above heuristic fails for some of these resources. ARM2Pulumi needs to correctly translate such resources.

Here are the currently supported default resource paths in the provider that need to be correctly translated:

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DBForMariaDB/servers/{serverName}/configurations/{configurationName}

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DBForMySQL/servers/{serverName}/configurations/{configurationName}

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DBForPostgreSQL/servers/{serverName}/configurations/{configurationName}

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.EventHub/namespaces/{namespaceName}/networkRuleSets/default

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Insights/components/{resourceName}/currentbillingfeatures

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ServiceBus/namespaces/{namespaceName}/networkRuleSets/default

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Sql/servers/{serverName}/databases/{databaseName}/geoBackupPolicies/{geoBackupPolicyName}

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Sql/servers/{serverName}/databases/{databaseName}/securityAlertPolicies/{securityAlertPolicyName}

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Sql/servers/{serverName}/databases/{databaseName}/transparentDataEncryption/{transparentDataEncryptionName}

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/blobServices/{BlobServicesName}

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/fileServices/{FileServicesName}

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/queueServices/{queueServiceName}

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/tableServices/{tableServiceName}

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Synapse/workspaces/{workspaceName}/sqlPools/{sqlPoolName}/transparentDataEncryption/{transparentDataEncryptionName}

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/logs

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/slotConfigNames

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/networkConfig/virtualNetwork

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/networkConfig/virtualNetwork

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/sourcecontrols/web

Various build errors with StorageAccount conversion

The conversion process for a StorageAccount results in various build error.

Using:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "sku": {
        "name": "Standard_GRS",
        "tier": "Standard"
      },
      "kind": "Storage",
      "name": "somestoragename",
      "apiVersion": "2018-07-01",
      "location": "WestUS",
      "properties": {
        "networkAcls": {
          "defaultAction": "Allow"
        },
      },
    },
  ],
}

Expected conversion

var somestoragename = new AzureNextGen.Storage.V20180701.StorageAccount("somestoragename", new AzureNextGen.Storage.V20180701.StorageAccountArgs
{
    AccountName = "somestoragename",
    Kind = AzureNextGen.Storage.V20180701.Kind.Storage,
    Location = "WestUS",
    NetworkRuleSet = new AzureNextGen.Storage.V20180701.Inputs.NetworkRuleSetArgs
    {
        DefaultAction = AzureNextGen.Storage.V20180701.DefaultAction.Allow,
    },
    ResourceGroupName = resourceGroupNameParam,
    Sku = new AzureNextGen.Storage.V20180701.Inputs.SkuArgs
    {
        Name = AzureNextGen.Storage.V20180701.SkuName.Standard_GRS,
    },
});

Current conversion

var somestoragename = new AzureNextGen.Storage.V20180701.StorageAccount("somestoragename", new AzureNextGen.Storage.V20180701.StorageAccountArgs
{
    AccountName = "somestoragename",
    Kind = "Storage",  // Error
    Location = "WestUS",
    NetworkRuleSet = new AzureNextGen.Storage.V20180701.Inputs.NetworkRuleSetArgs
    {
        DefaultAction = "Allow",  // Error
    },
    ResourceGroupName = resourceGroupNameParam,
    Sku = new AzureNextGen.Storage.V20180701.Inputs.SkuArgs
    {
        Name = "Standard_GRS",  // Error
        Tier = "Standard",  // Error
    },
});

[arm2pulumi] `object` type parameters result in a runtime exception

Given the ARM template:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "resourceTags": {
        "type": "object",
        "defaultValue": {
          "BU1": "BusinessName"
        }
      }
    },
    "resources": [
      {
        "type": "Microsoft.Storage/storageAccounts",
        "name": "someAccountName",
        "apiVersion": "2016-12-01",
        "location": "CentralUS",
        "tags": "[parameters('resourceTags')]",
        "kind": "Storage",
        "sku": {
          "name": "Standard_LRS"
        }
      },
    ],
  }

Converting it to C# results in

using Pulumi;
using AzureNextGen = Pulumi.AzureNextGen;

class TagsStack : Stack
{
    public TagsStack()
    {
        var config = new Config();
        var resourceGroupNameParam = config.Require("resourceGroupNameParam");
        var resourceTagsParam = config.RequireObject<dynamic>("resourceTagsParam");
        var someAccountName = new AzureNextGen.Storage.V20161201.StorageAccount("someAccountName", new AzureNextGen.Storage.V20161201.StorageAccountArgs
        {
            AccountName = "someAccountName",
            Kind = "Storage",
            Location = "CentralUS",
            ResourceGroupName = resourceGroupNameParam,
            Sku = new AzureNextGen.Storage.V20161201.Inputs.SkuArgs
            {
                Name = "Standard_LRS",
            },
            Tags = resourceTagsParam,
        });
    }
}

If I run pulumi up with the following config:

config:
  PulumiNextGenPort:resourceTagsParam:
    BU1: lkasdlk
    CC: e123

then I get a runtime exception:

Diagnostics:
pulumi:pulumi:Stack (PulumiNextGenPort-dev):
error: Running program 'C:\repos\ArmVSPulumi\function-app-consumption\PulumiNextGenPort\bin\Debug\netcoreapp3.1\PulumiNextGenPort.dll' failed with an unhandled exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot implicitly convert type 'System.Text.Json.JsonElement' to 'Pulumi.InputMap'
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at TagsStack..ctor() in C:\repos\ArmVSPulumi\function-app-consumption\PulumiNextGenPort\TagsStack.cs:line 11
--- End of inner exception stack trace ---
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& hasNoDefaultCtor)
at System.RuntimeType.CreateInstanceDefaultCtorSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean fillCache)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, Boolean wrapExceptions)
at System.Activator.CreateInstanceT
at Pulumi.Deployment.Runner.RunAsyncTStack

I've narrowed down the exception to this line:

            Tags = resourceTagsParam,

Workaround:

var resourceTagsParam = config.GetObject<Dictionary<string, string>>("resourceTags");

Consider removing `using AzureNextGen` alias

The converter adds

using AzureNextGen = Pulumi.AzureNextGen;

This shortens a lot of namespace qualifiers for a class, but it also makes moving all the namespaces to the top a little more annoying.

Can we consider removing the using AzureNextGen = Pulumi.AzureNextGen from the top of generated files?

Assume the following generated code:

var serverfarmResource = new AzureNextGen.Web.V20180201.AppServicePlan("serverfarmResource", new AzureNextGen.Web.V20180201.AppServicePlanArgs
{
    Location = resourceGroupVar.Apply(resourceGroupVar => resourceGroupVar.Location),
    Name = resourceGroupVar.Apply(resourceGroupVar => $"{resourceGroupVar.Name}-rotation-fnapp-plan"),
    ResourceGroupName = resourceGroupNameParam,
    Sku = new AzureNextGen.Web.V20180201.Inputs.SkuDescriptionArgs
    {
        Name = appServiceSKUVar,
    },
});

Current Steps:

  1. Copy AzureNextGen.Web.V20180201 from the first class initializers (i.e. new AzureNextGen.Web.V20180201.AppServicePlan)
  2. Add using AzureNextGen.Web.V20180201; to the top of the file.
  3. ERROR: The type or namespace name 'AzureNextGen' could not be found
  4. Prepend Pulumi to get using Pulumi.AzureNextGen.Web.V20180201;
  5. Go to the previously used AppServicePlan class initializer and use the light bulb to simplify name
  6. NOTE: None of the other namespaces can be automatically simplified
  7. Find all other initializers and remove all the AzureNextGen.Web.V20181101 namespaces

Desired Steps:

Assume:

//using static AzureNextGen;
  1. Copy Pulumi.AzureNextGen.Web.V20180201 from the first class initializers (i.e. new Pulumi.AzureNextGen.Web.V20180201.AppServicePlan)
  2. Add using Pulumi.AzureNextGen.Web.V20180201; to the top of the file.
  3. Go to any AppServicePlan (or AppServicePlanArgs) class initializer and use the light bulb to simplify name for the whole document

As you can see, this has decreased our number of steps from 7 to 3, but also it's turned from an O(n) manual operation to an O(1) manual operation, saving the developer a lot of keystrokes and wasted time.

This has the small disadvantage of making the namespaces longer in the actual code, but it also gives the developer more flexibility to easily use namespaces how they want.

arm2pulumi generates incorrect C# for CosmosDB

The following arm template fragment:

"resources": [
        {
            "type": "Microsoft.DocumentDB/databaseAccounts",
            "apiVersion": "2020-06-01-preview",
            "name": "[parameters('databaseAccountName')]",
            "location": "Australia East",
            "tags": {
                "defaultExperience": "Azure Cosmos DB for MongoDB API",
                "hidden-cosmos-mmspecial": "",
                "CosmosAccountType": "production"
            },
            "kind": "MongoDB",
            "identity": {
                "type": "None"
            },
            "properties": {
                "publicNetworkAccess": "Enabled",
                "enableAutomaticFailover": false,
                "enableMultipleWriteLocations": false,
                "isVirtualNetworkFilterEnabled": false,
                "virtualNetworkRules": [],
                "disableKeyBasedMetadataWriteAccess": false,
                "enableFreeTier": false,
                "enableAnalyticalStorage": false,
                "createMode": "Default",
                "databaseAccountOfferType": "Standard",
                "consistencyPolicy": {
                    "defaultConsistencyLevel": "BoundedStaleness",
                    "maxIntervalInSeconds": 5,
                    "maxStalenessPrefix": 100
                },
                "apiProperties": {
                    "serverVersion": "3.6"
                },
                "locations": [
                    {
                        "locationName": "Australia East",
                        "provisioningState": "Succeeded",
                        "failoverPriority": 0,
                        "isZoneRedundant": false
                    }
                ],
                "cors": [],
                "capabilities": [
                    {
                        "name": "EnableMongo"
                    },
                    {
                        "name": "DisableRateLimitingResponses"
                    }
                ],
                "ipRules": [],
                "backupPolicy": {
                    "type": "Periodic",
                    "periodicModeProperties": {
                        "backupIntervalInMinutes": 240,
                        "backupRetentionIntervalInHours": 8
                    }
                }
            }
        },

generates this invalid C# code:

        var databaseAccountResource = new DocumentDB.DatabaseAccount("databaseAccountResource", new DocumentDB.DatabaseAccountArgs
        {
            AccountName = databaseAccountName,
            Kind = "MongoDB",
            Location = "Australia East",
            Properties = 
            {
                { "apiProperties", new DocumentDB.Inputs.ApiPropertiesArgs
                {
                    ServerVersion = "3.2",
                } },
                { "backupPolicy", 
                {
                    { "periodicModeProperties", new DocumentDB.Inputs.PeriodicModePropertiesArgs
                    {
                        BackupIntervalInMinutes = 240,
                        BackupRetentionIntervalInHours = 8,
                    } },
                    { "type", "Periodic" },
                } },
                { "capabilities", 
                {
                    new DocumentDB.Inputs.CapabilityArgs
                    {
                        Name = "EnableAggregationPipeline",
                    },
                    new DocumentDB.Inputs.CapabilityArgs
                    {
                        Name = "AllowSelfServeUpgradeToMongo36",
                    },
                    new DocumentDB.Inputs.CapabilityArgs
                    {
                        Name = "DisableRateLimitingResponses",
                    },
                } },
                { "consistencyPolicy", new DocumentDB.Inputs.ConsistencyPolicyArgs
                {
                    DefaultConsistencyLevel = "BoundedStaleness",
                    MaxIntervalInSeconds = 5,
                    MaxStalenessPrefix = 100,
                } },
                { "cors", {} },
                { "createMode", "Default" },
                { "databaseAccountOfferType", "Standard" },
                { "disableKeyBasedMetadataWriteAccess", false },
                { "enableAnalyticalStorage", false },
                { "enableAutomaticFailover", false },
                { "enableFreeTier", false },
                { "enableMultipleWriteLocations", false },
                { "ipRules", {} },
                { "isVirtualNetworkFilterEnabled", false },
                { "locations", 
                {
                    new DocumentDB.Inputs.LocationArgs
                    {
                        FailoverPriority = 0,
                        IsZoneRedundant = false,
                        LocationName = "Australia East",
                    },
                } },
                { "virtualNetworkRules", {} },
            },
            ResourceGroupName = resourceGroupName,
            Tags = 
            {
                { "defaultExperience", "MongoDB" },
            },
        });

Errors include (starting at { "backupPolicy", ):

   example.cs(415,34): error CS1003: Syntax error, ',' expected
   example.cs(415,34): error CS1513: } expected
   example.cs(416,18): error CS1003: Syntax error, ',' expected
   example.cs(416,18): error CS1513: } expected
   example.cs(423,21): error CS1026: ) expected
   example.cs(423,21): error CS1525: Invalid expression term '{'
   example.cs(438,17): error CS1733: Expected expression
   example.cs(438,21): error CS1001: Identifier expected
   example.cs(438,21): error CS1002: ; expected
   example.cs(439,38): error CS1002: ; expected
   example.cs(439,38): error CS1513: } expected
   example.cs(444,19): error CS1002: ; expected
   example.cs(444,20): error CS1513: } expected
   example.cs(445,25): error CS1002: ; expected
   example.cs(445,25): error CS1513: } expected
   example.cs(445,31): error CS1513: } expected
   example.cs(446,31): error CS1002: ; expected
   example.cs(446,31): error CS1513: } expected
   example.cs(446,43): error CS1002: ; expected
   example.cs(446,44): error CS1513: } expected
   example.cs(447,45): error CS1002: ; expected
   example.cs(447,45): error CS1513: } expected
   example.cs(447,58): error CS1002: ; expected
   example.cs(447,59): error CS1513: } expected
   example.cs(448,55): error CS1002: ; expected
   example.cs(448,55): error CS1513: } expected
   example.cs(448,63): error CS1002: ; expected
   example.cs(448,64): error CS1513: } expected
   example.cs(449,44): error CS1002: ; expected
   example.cs(449,44): error CS1513: } expected
   example.cs(449,52): error CS1002: ; expected
   example.cs(449,53): error CS1513: } expected
   example.cs(450,44): error CS1002: ; expected
   example.cs(450,44): error CS1513: } expected
   example.cs(450,52): error CS1002: ; expected
   example.cs(450,53): error CS1513: } expected
   example.cs(451,35): error CS1002: ; expected
   example.cs(451,35): error CS1513: } expected
   example.cs(451,43): error CS1002: ; expected
   example.cs(451,44): error CS1513: } expected
   example.cs(452,49): error CS1002: ; expected
   example.cs(452,49): error CS1513: } expected
   example.cs(452,57): error CS1002: ; expected
   example.cs(452,58): error CS1513: } expected
   example.cs(453,28): error CS1002: ; expected
   example.cs(453,28): error CS1513: } expected
   example.cs(453,34): error CS1513: } expected
   example.cs(454,50): error CS1002: ; expected
   example.cs(454,50): error CS1513: } expected
   example.cs(454,58): error CS1002: ; expected
   example.cs(454,59): error CS1513: } expected
   example.cs(455,30): error CS1002: ; expected
   example.cs(455,30): error CS1513: } expected
   example.cs(462,22): error CS1002: ; expected
   example.cs(462,22): error CS1513: } expected
   example.cs(463,20): error CS1513: } expected
   example.cs(464,40): error CS1002: ; expected
   example.cs(464,40): error CS1513: } expected
   example.cs(464,46): error CS1513: } expected
   example.cs(465,14): error CS1519: Invalid token ',' in class, struct, or interface member declaration
   example.cs(466,31): error CS1519: Invalid token '=' in class, struct, or interface member declaration
   example.cs(466,50): error CS1519: Invalid token ',' in class, struct, or interface member declaration
   example.cs(467,18): error CS1519: Invalid token '=' in class, struct, or interface member declaration
   example.cs(471,10): error CS1022: Type or namespace definition, or end-of-file expected
   example.cs(471,11): error CS8652: The feature 'top-level statements' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
   example.cs(471,11): error CS8803: Top-level statements must precede namespace and type declarations.
   example.cs(515,5): error CS1022: Type or namespace definition, or end-of-file expected
   example.cs(516,1): error CS1022: Type or namespace definition, or end-of-file expected

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.