Giter Site home page Giter Site logo

achieve.aspire's People

Contributors

rudiv avatar whitwaldo avatar

Stargazers

 avatar

Watchers

 avatar

Forkers

whitwaldo

achieve.aspire's Issues

Better Builder API

Resources such as Cosmos or Batch that have multiple resource types are responsible for having their own builders that register the sub-types in the file.

Following on from #7, it's perhaps more pertinent to have the builder API represent a single file of Bicep that's output by Achieve. This would basically make the builder represent any related groups of resources (like in #7 the Role Assignment) but also for things like Cosmos and Batch where there are child resources that are created.

However, what if there's a tree of resources such as the Cosmos Account -> Database -> Container tree, if it was just extension methods (think builder.AddAzureCosmosDbAccount().AddDatabase().AddContainer()) the tree wouldn't make sense, you would still have to capture the individual databases, so like:

var acc = builder.AddAzureCosmosDbAccount(..);
var db1 = acc.AddDatabase(...);
var cnt1 = db1.AddContainer(...);
var cnt2 = db1.AddContainer(...);
var db2 = acc.AddDatabase(...);

Unless it was just known that Containers always come under a database so it kinda breaks convention a bit:

var acc = builder.AddAzureCosmosDbAccount(...)
    .AddRoleAssignment(...) // Azure RBAC Role Assignment (Control Plane)
    .AddCosmosRoleAssignment(...) // Cosmos RBAC Role Assignment (Data Plane)
    .AddDatabase("db", db => {
        db.AddCosmosRoleAssignment(...);
        db.AddContainer(...)
            .AddCosmosRoleAssignment(...);
        db.AddContainer(...);
    })
    .AddDatabase("db", db => {
        db.AddContainer(...);
    });

Tidy Cosmos Definition API

Currently the way Cosmos DBs are defined is rough, as below:

var cosmos = builder.AddAzureCosmosDbNoSqlAccount("cosmos", acc =>
{
    // During Development, you can either use the emulator (suggest using the Aspire.Hosting.Azure.CosmosDB package), or
    // provision it in the cloud with development defaults (public access, serverless, etc).  
    if (builder.ExecutionContext.IsRunMode) {
        acc.Resource.WithDevelopmentDefaults();
        acc.WithDevelopmentGlobalAccess(); // Adds your local principal to have access to everything in the account
    }
    var db = acc.AddDatabase("db");
    var cn = db.AddContainer("cn", cn =>
    {
        cn.PartitionKey = new CosmosDbSqlContainerPartitionKey("/id");
    });
    
    if (builder.ExecutionContext.IsPublishMode) {
        // Add a Managed Identity to the Cosmos DB
        acc.AddRoleAssignment(acc.Resource, id, CosmosDbSqlBuiltInRoles.Contributor);
        //acc.AddRoleAssignment(db.Resource, id, CosmosDbSqlBuiltInRoles.Contributor); // Or the Database
        //acc.AddRoleAssignment(cn, id, CosmosDbSqlBuiltInRoles.Contributor); // Or the Container
    }
});

I want to make it a little more fluent when it comes to DBs/Containers as they are essentially a tree of resources, and streamline the addition of Role Assignments so the underlying resources don't have to be used as much.

Example:

var cosmos = builder.AddAzureCosmosDbNoSqlAccount("cosmos", acc =>
{
    acc.AddRoleAssignment(id, CosmosDbSqlBuiltInRoles.Reader);
    // or acc.AddReader(id); ??

    acc.AddDatabase("db", db => {
        db.AddRoleAssignment(id, CosmosDbSqlBuiltInRoles.Contributor);
        // or db.AddContributor(id); ??

        db.AddContainer("cn", cn => {
            cn.PartitionKey = new CosmosDbSqlContainerPartitionKey("/id");
            // or cn.PartitionKey("/id"); .. cn.PartitionKey("/docType", "/id") ??
            cn.AddRoleAssignment(id, CosmosDbSqlBuiltInRoles.Contributor);
            // or cn.AddContributor(id); ??
        });
    });
});

Resolve 'Name' Ambiguity

Bicep resources sometimes effectively have 2 "Name"s.

The first (which is Name in the internal API) is the actual Bicep Resource Name, ie.

          \/ This
resource test 'Test/test@2023-01-01' = {

The second, which almost has a convention of AccountName for the existing few resources is the actual name of the resource, example in Cosmos DB:

resource cosmosDbAccount 'Microsoft.DocumentDB/databaseAccounts@2023-11-15' = {
                              name: 'cosmos${uniqueString(resourceGroup().id)}'
                                        ^ This

To avoid the ambiguity of Name being used for both there are a couple of options neither of which I'm sure is really better than the other:

  1. Remove the concept of the Resource Name as being customisable, so we would always "auto generate" a unique (but constant) string, which could be based off the "Account Name". This has the upside of removing any ambiguity as it becomes internal, but the downside of making Bicep (if synthed) more unreadable / usable outside of tooling.
  2. Standardise Name as ResourceName that can be overridden and used internally, leaving Name to be used when required by the resource definition itself.

Either of those work to remove the less defined Name property used for Bicep and reduce confusion when implementing new resources.

Add ability to make RoleAssignments directly against the Resource being created

When creating a RoleAssignment, a separate Bicep Resource file is created that has an existing resource to scope against, as part of the overall rethink of the API to make it more "production-ready", think specifically about this.

Something such as a follow-on from the base builder would work great.

var id = builder.AddManagedIdentity("myidentity");
var maps = builder.AddAzureMapsAccount("maps")
    .AddRoleAssignment(id, MapsRoles.DataReader);

This could then add the RoleAssignment to the same file as the resource being created and avoid the need for duplication.

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.