After 24 minutes of compilation (code generation f...
# dotnet
n
After 24 minutes of compilation (code generation from JSON schema takes a while), I finally got a NuGet package that supports all Pulumi Azure resources as F# computational expressions! https://github.com/UnoSD/Pulumi.FSharp.Azure
🎆 2
❤️ 4
t
Looks awesome! Is that the generation time or compilation time?
w
Is it possible to set a “fixed” name as well? I guess the name here is the one that will get a suffix?
Awesome work! I’m super curious.
Is the generated code somewhere as well? I guess the code that is checked in is the one you created manually, the rest of the resources are generated by myriad?
Figured out how you solve the “fixed” name part. It is possible to set it as part of the arguments as well. Nice.
tried to compile it on my machine (in WSL2), it only took 19 minutes 🙃 . I wonder how is possible to optimize of it, maybe not much. With that said, it is super cool! The generated file small and easy to read, only 33000 lines of code :).
Tried to run it on the kubenetes schema and it works almost fine. I needed to make some minor adjustments so now I generate it for kubernetes... however, the code isn't correct in my case since I just wanted to see if I could generate it... now I need to tweak it to make it correct 🙂
t
yeah, I wonder why the generation is so slow. our own C# generation completes within a couple seconds
w
even if it is slow I think this could be a super nice addition to iterate on and make faster. One thought I have is that it might be multiple lookups against the underlying json maybe, not sure if that is "moved" up to one instance in one go... but that is just a guess.
n
@tall-librarian-49374 it's called Myriad, it's an MSBuild task that generates code at compile time.
w
I have created a fork for kubernetes which I now have running (almost). I one issue regarding some types that wants InputJson, I guess it is the
$ref
part that says it should be json:
Copy code
data: {
   type: "object",
   $ref: "pulumi.json#/Json",
   description: "Data is the serialized representation of the state."
},
Do you know if that is correct @tall-librarian-49374? If you are interested in the progress it is in this branch: https://github.com/mastoj/Pulumi.FSharp.Azure/tree/k8sversion
n
@wet-noon-14291 the name is the same as the Pulumi resource name, so yes, it will get suffixed by Pulumi. If I got your question
Thanks, and yes, I decided to .gitignore the Generated file, it gets massive when you generate the whole JSON.
I left the original non-generated resources there as they have still better syntax for other things. They support passing the resource group object instead of doing rg.Name (tiny difference, but less code is always better) and strongly typed arguments for Tiers etc... but I will do that also on generation at some point, it just takes longer and now you can get full compatibility already.
Sorry, reading one message at the time... Yes, compilation takes a while, got 8 minutes on a build agent for DevOps,
I have not had time to investigate why it is so slow, but I will do. May be a limitation of Myriad itself, though.
Being a one-off, it's not a big deal, for debugging, I filter the array and generate only one resource.
Btw, I need to support nested types, when I do so, also the complex properties will be nicer.
t
@wet-noon-14291 there are some hacks in C# generation to make it backwards-compatible to the pre-schema version. They are likely to screw then around, see the usage of this flag https://github.com/pulumi/pulumi/blob/d611740ab0fa5c100b3d1d1228d695c3d1328e59/pkg/codegen/dotnet/gen.go#L175
Also, we ignore
$
in names like
$ref
so it becomes
Ref
w
Couldn't figure out a reliable and easy fix for the inputjson stuff so I dropped the "ControllerRevision" resource in this verison.
And now a really simple one for kubernetes is working (nothing published yet):
Copy code
let appDeploy = 
    deployment {
      name "MyDeploy"
      spec deploySpec
    }
Sample usage here: https://github.com/mastoj/Pulumi.FSharp.Azure/blob/k8sversion/samples/KubernetesSample/Program.fs To make it really useful nested types also needs to be generated.
🚀 1
A small step closer on the nested types, this compile:
Copy code
let appDeploy = 
    deployment {
      name "MyDeploy"
      spec (deploymentSpec {
        replicas 1
      })
    }
t
I think there’s a theoretic possibility to make it
Copy code
let appDeploy = 
    deployment {
      name "MyDeploy"
      deploymentSpec {
        replicas 1
      }
    }
w
Might be, not an CE expert so I'm just tweaking around with what @numerous-artist-1705 created. Will run with that first and then improve. I do it as a learning exercise as well 🙂
@tall-librarian-49374 do you have some sample code I could look at for creating such a CE?
n
Yep, when I had in mind nested types, I was thinking about that ^. I would like to reduce parenthesis as much as possible.
w
I agree. But I also think it is good to get something working and then figure out how to remove parenthesis :)
👍 1
@tall-librarian-49374 did you have an example of nested CE? Tried to check your POC repo and also search for it in general but can’t find a good example showing it is possible.
t
I don’t think I ever published it. I had this shape that compiled but didn’t do anything useful.
n
@wet-noon-14291 I'll see if I can get something done this week (no promises) if you want a working example.
w
I got a more complete sample compiling now:
Copy code
let appDeployCe = 
    deployment {
      name "MyDeploy"
      spec (deploymentSpec {
        replicas 1
        selector (labelSelector {
          matchLabels ["app", input "nginx" ]
        })
        template (podTemplateSpec {
          metadata (ObjectMetaArgs(Labels = appLabels))
          spec (podSpec {
            containers [
              input (container {
                name "nginx"
                image "nginx"
                ports [
                  input (containerPort {
                    containerPortValue 80
                  })
                ]
              })
            ]
          })
        })
      })
    }
and yes, it would be nice if we could remove some parenthesis 🙂 It takes a while to run this for kubernetes as well, around 15 minutes... but then I also process the types and not just the resources.
It shouldn't be too hard to generalize the code to deal with nested CE, if I just knew how to create nested CE... if you still have your sample on your disk @tall-librarian-49374 I would appreciate it. The answers I've found so far online says that it can't be done... 🤷
t
Here is a gist: https://gist.github.com/mikhailshilkov/12b59e60c3ad9bc2c982578276fb7c64 It compiles with a “good” shape, but does nothing else
w
Awesome, will have a look later this week. I think it might be solved by having some mutable state in the builder that you work with. That way the yield can also modify the state. Sort of a hack but doable I think at first glance.
Been playing with the yield tonight, by modifying a small sample of my generated code, and I don't get my sample to work as your for some reason. For me the compiler warns about not ignoring, to avoid that I have to put
yield
in front of the nested CE. Also, I do think this might be abusing the CE quite a lot and the tooling will struggle to help suggesting where to use nested CEs I think. When using custom operations the available operations in a CE is given to you by the tooling, and I don't think that is the case with the yields. My feeling is that the "correct" way is to use custom operations and live with the extra parenthesis.... but I'm more than glad to be proven wrong here 🙂. Here's my manually modified builder code: https://github.com/mastoj/Pulumi.FSharp.Azure/blob/k8sversion/samples/KubernetesSample/Modified.fs And I get the warning here: https://github.com/mastoj/Pulumi.FSharp.Azure/blob/k8sversion/samples/KubernetesSample/Program.fs#L48-L50 (if I don't use yield)
n
it's a bit late so I may not be able to look at the code, but usually that means you need a Zero and Yield method overload that supports the nested type
👍 1
w
I also needed combine I think. But then I had problem combining with the custom operations. Not sure I’ll spend that much more time on the nested CE, not convinced it is the way to go. If it was intended to do it I think it would be easier :)