Hi, We are running into an issue with setting com...
# box-products
d
Hi, We are running into an issue with setting commandbox server name within server.json which I believe started when we upgraded from CommandBox 5.2.0 to 5.4.2… and which persists into current 5.6.0 version. Within our server.json we have (amongst other settings) the following to set the server name:
Copy code
{
  "name": "${INSTANCENAME:UndefinedInEnvironment}"
}
When we were running CB <= 5.2.0, this would correctly set the name of the server to the passed in environment variable… but following on from upgrading to 5.4.2, the servername is always set to
www
- or rather I believe set to the name of the folder the server is started in… Within the detailed output for warmup-server.sh (in this instance running CB 5.5.2) we see the following:
Copy code
Starting up container in test mode
Set verboseErrors = true
INFO: Configuration set to non-root user: CBServerUser
Set verboseErrors = true
INFO: CF Engine defined as lucee@5.3.9+133
INFO: Convention .cfconfig.json found at /var/www/.cfconfig.json
INFO: Server Home Directory set to: /usr/local/lib/serverHome
 √ | Starting Server
   |------------------------------
   | start server in - /var/www/
   | server name - www
   | server config file - /var/www//server.json
   | WAR/zip archive already installed.
..and when the server starts - either locally or on AWS, the server name always shows up as www previously, within the warmup running within the dev ops build script, where the
INSTANCENAME
environment variable was not set, we would see
UndefinedInEnvironment
shown as the server name, and then when running within local / AWS environments where the environment variable was set, the server name would be set to the environment variable. This is particularly an issue when viewing servers within Fusion Reactor Cloud dashboard… as we have multiple servers for different applications and environments appear in the dashboard as www - and not the specific app / environment name specified. All other dynamically set parameters within the server.json - such as the fusionreator settings for cloudgroup, defaultApplicationName etc. which are set from environment variables, appear to be set correctly (so we can for instance see in FR when we dig into the details what app / environment is being run, but on all the menus, all instances appear as www. Can anyone advise why this behaviour seems to have changed… and if there is something we can do to ensure that the server name is set correctly as it was previously?
b
Since you're doing this in Docker, there's an additional layer of possibilties
What base docker image are you extending and do you have a warmup in place?
Chances are this is a simple case of the server not having a name set when it warms up the first time, and therefore getting "locked" in forever
The Ortus Docker containers run in "single server mode" and that is actually probably more related to your behavior than anything.
A CommandBox instance in single serve mode will never define another server, but will just re-use any existing server definition.
There's still a lot of questions, but a good chance your fix is to have the server name present when actually warming up the server for very first time (which also means not using any sort of pre-warmed container)
d
In this particular example base is:
Copy code
FROM ortussolutions/commandbox:3.5.4
and we are running:
Copy code
RUN ${BUILD_DIR}/util/warmup-server.sh
looking at it, we are running on our base cb image… and then again on specific app… which is probably not ideal
b
It really depends when the very first warmup that defines the server happens
Whatever the name is then, will be the name forever because the server will never be redefined
d
so… are you saying… if we use warmup, then server.json will be ignored for subsequent executions?
b
We added single server mode to fix related issues where people switching around their server names and such would wind up with having several servers defined with different names and different settings which led to all sorts of issues
then server.json will be ignored
Not ignored, I mean the rest of your settings will be used. But the name itself is locked in the way it works now
d
was that something which was changed between 5.2.0 and 5.4.2?
b
You can't change the name on a server without basically creating a new serer
Internally, the unique ID of a server is a hash of the name and web root. So changing either of those would create a new server
d
Was this a change in behaviour?
b
was that something which was changed between 5.2.0 and 5.4.2?
Maybe, you'd need to go read the release notes 🙂
Lol, everything is a change in behavior. Even bug fixes
d
yeah
b
Sometimes one man's fix is another man's bug
d
solutions…
Is this something which can be overridden in what is passed in to FR?
b
FWIW, it's probably possible to enhance CommandBox's single server mode a bit to absorb the last server name used for scenarios like this, that's just not how it works.
d
That’s the only reason we care about it at all
b
I was checking, but got distracted talking here 😉
d
lol
sorry
b
Darn, looks like it's hard coded to use the server name from CommandBox. It must be the ONE thing I didn't add a setting for
Yes, you don't need to send screenshots... I understand the issue, lol
d
lol
b
We've dealt with the same thing
We just do our warmups at the right time now
Which is why I suggest you do the same
meaning, if the server.json and env vars are defined the VERY FIRST time the server is ever started, it will lock in that name
But if you're warming up in a base image, that's probably impossible
I'm not a fan of base image warmups for several reasons, including this one
Let me just add in a setting for this though in FR-- it's bitten us too. Also I need to release a few version of FR that defaults to FR 9.x too
Give me like 60 seconds...
d
😄
b
ok, testing locally...
d
We definitely need to look at when and where we are doing warmups… trying to follow advice read in the past in order to mitigate against longgggggg startup times within hosted environments… not that it’s completely successful… but it does help… But then we seem to cause issues down the line… Seems we either need to create finalised builds where nothing is set from environment… all at build phase… or have it all dynamic (and slow, and massive images with multiple copies of various apps etc…
we seem to be having a combination of the worst aspects of both atm eye roll
b
Yes, the more dynamic you want, the larger the image normally is
Because all the env var stuff and JSON files require CommandBox to be in the mix
The smallest images you can create which are ready to go and can serve requests in single digit seconds are rather inflexible because all the config is fully loaded into the engine's XML files and ready to go without any additional start up-time hoops
d
hmm I’m somewhat reluctant to have things like db connection details etc. within the build… just… does not seem right…
b
It would be nice if Lucee itself had better support for env vars right in the XML configs
Then you could use CFConfig to create them and load up the final env vars which you would provide at run time
d
yeah, that would be nice… didn’t they say they were going to add that at some point?
b
no clue...
Ok, sorry that took a little longer-- my wife came in to talk to me
Update your system modules and try again
• you'll get FR 9.x by default now (just released yesterday( • You can set
fusionreactor.serverName
in your
server.json
to override the server name in FR
@danlance
d
sweet, I’ll update the build config and give that a whirl…
d
@bdw429s just tried it with my setup and works a treat - makes FR Cloud with AWS fargate containers much easier to identify. Thanks for adding that one 👍
d
@bdw429s can confirm, tested this on a local build, and the FR instance is now showing with the specific name 🙂 Thanks for sorting 😄
@bdw429s - could I suggest that it may be worth adding a note to documentation page https://commandbox.ortusbooks.com/embedded-server/server.json regarding name being unchangeable after first launch etc. (or something to that effect)?
b
Well, that caveat only really applies to single server mode. There are honestly tons of little caveats everywhere when it comes to changing server name and web root, lol
d
Lol ok...
☝️ Feel free to add any notes there via a pull, but I'd also rather find a way to make single server mode always use the last server name you tried to pass.
The logic for single sever mode is pretty straight forward.
Basically anywhere in CommandBox that tries to "look up" a server based on name, web root, etc just does this
Copy code
if( ConfigService.getSetting( 'server.singleServerMode', false ) && getServers().count() ){
	return getFirstServer();
}
So as soon as you flip that switch on, it just blindly grabs the first (and only) server that exists and hands it back with whatever data is in it
So any name you pass is just ignored (unless there are NO servers defined, in which case it creates it), but it's prob not too much code to try and change it to also update that server it pulls back to have the data you asked for.
d
Yeah... Would make sense... Not sure how much benefit this would be outside of the context of passing in to FR... Which is already solved...
Would certainly be less confusing...
Application name != Server name... Server name is shown in the sidebar and server listing. Application name is shown in applications Normally I am looking at server rather than app, as that shows more real-time granular info, as well as resource usage... And with the UI in FR, having multiple apps all showing as www... Not great, especially as the ordering in the menu is not consistent!
Ideally I would also like the aws EC2 instance I'd showing in the server name as well... But to do that I need to create a script which runs on container startup and gets the id for the current instance... Which is on the to-do list now that FR cb integration is allowing server name to be set again...
b
Your app name comes from ColdFusion itself
You can also set that in the server.json if you want to override it
Is the AWS EC2 instance name available as an env var?
d
Yes... Already doing... All working fine.... Just responding to... Hang on... I could have sworn I was responding to someone in this thread .. WTF??? has someone deleted a post?
b
¯\_(ツ)_/¯
d
Someone posted about how it's possible to set Application name... Which I was responding to...
b
Ahh, that makes more sense, lol
Yep, that's a different thing which is why I hadn't talked about it, lol
d
Yup
b
FWIW, you may already know this but it appears you can get your instance name set into an env var like so
Copy code
AWS_INSTANCE_ID=`curl -s <http://169.254.169.254/latest/meta-data/instance-id>`
Then you could use
%{AWS_INSTANCE_ID}
in your
server.json
System setting expansions in CommandBox are also extendable, which means someone could easily write a module that allows you to do something like
Copy code
${aws-meta.INSTANCE_ID}
that does a HTTP behind the scenes to get the data.
I made those extendable originally with the idea of building namespaces to access custom secret stores too
d
Yeah.... I had mixed results trying this a while back when using elastic beanstalk multicontainer docker image... Not tried yet in new AL2 docker images to see if it now works...
As in, I asked aws support how to do it, followed their instructions, didn't work, asked why, and eventually they said it wouldn't work in that image... And then I had more important things to look at and have not revisited!
b
wow...
d
The curl method that is... Not the system setting expansion... That looks interesting... Although I presume would still need a way of getting the host instance I'd etc. first...
b
Not sure exactly what your question is, but in order to use a
${foo}
place holder in a CommandBox JSON file, it would first need to be something CommandBox knew how to find.
The
${}
construct (called system settings) is much more than env vars. It's • local CommandBox env vars set in the box CLI • Java system properties in the CLI's Java process • OS-level env vars set in the process that is running the CLI/Java • a series of internal namespaces defined by CommandBox such as
${serverinfo.serverHomeDirectory}
,
${boxjson.name}
or
${@localJSONKey}
• Any custom namespaces you want to define in a custom module you (or someone else) has written that defines a pattern of
${mynamespace.mykey}
and implements the lookup for those values
d
Yeah - not a question... Just a stream of consciousness... Issue we had on docker multicontainer image was I believe network configuration related - and not something which was easily fixable due to elements of the docker configuration being somewhat locked down on that image. So I need to check if the http request method works first prior to building anything which relies on that...
b
So above, I was suggesting two different approaches. 1. Just running a bash line somewhere to set a proper OS level env var, which would get pulled in via bullet #3 above 2. Or writing a custom CommandBox module that adds a system setting namespace for looking up AWS specific instance information which would be bullet #5 (and would remove the need for any curl stuff)
I'd love to see some people work on stuff like that, but I don't tend to use AWS myself, so I've just never had the need.
d
Yeah... I get it... But option 2 would still need a way of getting the info 😉 http request probably being the simplest... If it works!
b
The other thing I'd really like to see is
Copy code
${custom-aws-secret-namespace.name-of-secret}
so people can use AWS's custom secret store directly in their JSON files via system settings. It would be trivial to write, I just don't need it myself, lol
And yes, the HTTP requests would need to work indeed for any of this to be of use! I assume it was related to networking somehow in the image
d
Both of those, especially the second, would be of interest. Maybe something I can look at if we get some downtime...
b
I'll happily help guide if you are interested in helping write it
You can basically grab that example I linked to in the docs and flesh it out
d
Yeah... Pretty certain it was that the build locked down config of the network resolution... Probably solvable but didn't look further at the time...
Ok... No guarantees... But I'm interested in principle...
well… good news, the http method for determining AWS instance-id, does work when run within the docker container within the aws instance under AL2…
So I can try to take a look at modularising this…
Hi @bdw429s I’m trying to create a CB module for getting the AWS instance ID via HTTP. are you able to just give me a bit of guidance / clarification regarding these lines with the example you linked:
Copy code
interceptData.resolved=true;
    return true;
I’m just trying to ensure that there’s no risk of this being called repeatedly… and also ensure that if it does not retrieve the instancID (probably as it’s not running on aws) that it does not prevent loading - ideally logging warning to console output. In the event that we catch an exception with the http call… how should the above 2 values be set?
b
@danlance Good questions • your interceptor will fire every time any system setting is resolved anywhere in CommandBox for any reason (well, unless another core interceptor has already resolved the value, breaking the chain of execution) • It's up to your code to recognize the prefix it cares about and only attempt the HTTP call when it knows the system setting being expanded is one it can provide • If the values never change, I would highly recommend caching the data • If there is an endpoint to get all the data available in one go, you could just cache the whole lot of it. (your interceptor is a singleton, so you can stick whatever you like in the variable scope and it will live for as long as the CommandBox CLI is running. • I would use a timeout on the http and a small one at that. If the CFHTTP errors, I would log it with the
log
logger available in your interceptor
Copy code
log.error( 'error getting system setting #name#', e )
which will go in CommandBox logs visible with
Copy code
system-log | tail
In the event of an error, you should return the default value which was provided. The default value should be provided any time you can't find whatever was asked for. You could choose to throw an exception if you are very sure there will not be a default value and it is fatal if nothing is found, but that's not really how system settings works. Default values are provided like so
Copy code
${namespace.key:default}
d
going backwards… default value - am I correct in thinking that is empty string if not specified?
b
Yes, there will always be a default value of an empty string if the user didn't specify one
which is basically how env vars work
d
👍
b
But you don't need to worry about what the default value is-- it's passed into your interceptor I believe
d
Am I correct in my understanding… that the interceptor runs before onServerStart? I was trying to define vars in onServerStart… and getting errors when referencing said vars that they do not exist… but then it struck me that as this setting config etc. it would fire before onserverstart?
b
I have no idea what you mean, lol. I'd have to see what you're looking at
Forget servers thoguh
system settings have nothing directly to do with servers at all
ANY TIME CommandBox needs to resolve a system settings, which could literally just be this
Copy code
env show aws.foobar
or this
Copy code
echo ${aws.foobar}
it will fire the system setting expansion interception point, which allows any interceptor (including the core one) to resolve the value
d
lol - I was trying to nick some stuff from your CB FR module… Which has logging functions and stuff like that… but everything in there is intialised in the onServerStart event… and erroring
b
Forget the FR module, there's nothing in there you need
d
ok
does log() also log to stdout?
b
All you need is • a moduleconfig.cfc that declares the `onSystemSettingExpansion`interceptor • an interceptor file that contains just that method in the docs, but with your logic instead
When the module loads, it will register it's interceptor with the CLI which will just sit there and help resolve any system settings that need expanded for any purpose
You shouldn't be writing anything to the console from this module unless it's just for development debugging, in which case just use
Copy code
systemOutput( 'I was called...', true )
That's why I said any error logging needs to go through the logbox logger already available in your interceptor which points to a log file appender
d
already available in the interceptor?
b
Yes, just like ColdBox 🙂
interecptors auto-extend the framework super type and have all sorts of methods and variables available to them
d
uhhh… ok… not actually ever used that 😳
is there a quick ref guide to that?
to what’s available?
b
There's these docs, but honestly it's way more information than you need, lol https://coldbox.ortusbooks.com/the-basics/interceptors
If you wanted, you could actually just slap the ``onSystemSettingExpansion` method directly in your
ModuleConfig.cfc
, but then you don't get all the fun framework super type stuff
What would probably help you better is just seeing an example of one of the core interceptors
d
ah ok - that’s how id done it from the example… stuck it in the moduleconfig
b
Internally CommandBox uses lots of modules internally just for organization. Here is the moduleconfig for the server module https://github.com/Ortus-Solutions/commandbox/blob/development/src/cfml/system/modules_app/server-commands/ModuleConfig.cfc#L13
It registers the
ServerSystemSettingExpansions
interceptor
d
ok… so moduleconfig just has the configur() method registering interceptos…
b
Note, there's two different namespaces that intereptor is looking for (
serverjson.
and
serverinfo.
)
d
IS the interceptor a singleton?
b
yeah, I said that above
d
sorry… missed that
b
So as far as where you put the method, you can pick your approach. The separate CFC is the more formal approach but has a bit more boilerplate
Slamming the method in the moduleconfig (because every
ModuleConfig.cfc
is also registered as an interceptor) is quick and dirty, but the method doesn't have access to the useful interceptor base class variables like logbox. Doesn't mean you can't get it-- it's just a bit more boilerplate again.
d
ok… if I go down the separate interceptor route… to acess logbox… is it there by default, or do I need set a property for injection?
b
FWIW, I also have these interceptor docs in CommandBox, but they don't go nearly as deep. https://commandbox.ortusbooks.com/developing-for-commandbox/interceptors
is it there by default,
Yeah, there's a ton of stuff just already there. Interceptors are like COldBox handlers in that they use Wirebox's virtual inheritance to extend a special base class at run time
This gives them methods and variables you can just use without any boilerplate
d
so logbox.log() to use?
b
almost, I showed you the code above 🙂
Just paste it in, lol
Copy code
log.error( 'message' );
Which is just standard logbox stuff
d
ah ok
b
oh dang, I lied-- moduleconfig also has a log object mixed in. I probably added that in CommandBox because I was annoyed that ColdBox didn't do it 😆 https://github.com/Ortus-Solutions/commandbox/blob/development/src/cfml/system/services/ModuleService.cfc#L696
☝️ That code there is all the stuff that gets "mixed in" to every moduleconfig.cfc
And just for completeness, here is the base interceptor class as well, so any methods or variables in here are available to all interecptors https://github.com/Ortus-Solutions/commandbox/blob/development/src/cfml/system/Interceptor.cfc#L16
d
Thanks Brad… I have a working POC for getting the instance ID up within an existing app on AWS… Need to do some tidy up, separate it from the app into a standalone package, possibly make it more multifunctional… and see how much more complicated it is to get this to work with IMDSv2 (current approach requires IMDSv2 which is supposed to be avoided when possible…) That’s a task for tomorrow though…
Hi @bdw429s I’ve created a very basic module - which works for IMDS v1 This I originally had copied in locally to
/usr/local/lib/CommandBox/cfml/modules/
in docker build process… which works fine. I’ve attempted to turn into a package using box init command, which created a box.json file. I then commited the module folder to github public repo, and am attempting to install as I do with other packages within Dockerfile, but from git endpoint:
RUN box install git+<https://github.com/Gencia/commandbox-awsimds.git>
This appears to work - as in I see the following within the docker build output:
Copy code
#9 [5/7] RUN box install git+<https://github.com/Gencia/commandbox-awsimds.git>
#9 11.24  √ | Installing package [git+<https://github.com/Gencia/commandbox-awsimds.git>]
#9 DONE 11.8s
However, when I start the container, I cannot see the module within the modules folder, and also no log entry in the logbox log (which I would expect when running in local environment) I’m sure theres some basic step I’ve missed here.. but struggling to see why it’s not working… Are you able to shed any light on this?
b
@danlance Your module looks pretty good, you just have the wrong type in your
box.json
https://github.com/Gencia/commandbox-awsimds/blob/master/box.json#L56
You want
commandbox-modules
which would have been obvious if you just tested with the
install --verbose
command
The package installed all right, but not where you think it did! It just installed into whatever the current working directory was at the time, not the system folder!
See the guide here which covers the package type you needed to use https://commandbox.ortusbooks.com/developing-for-commandbox/modules#share-the-love
Also, I recommend testing with the
link
command which creates a nice symlink for you to the commandbox system folder so you don't need to go copying stuff around and having more than one copy of the code https://commandbox.ortusbooks.com/developing-for-commandbox/modules/linking-modules
Just • create the repo • create the package all up front, and link it into the CommandBox core while you develop.
And finally, all you need to do to get this on forgebox is run
Copy code
publish
from the root of the package and then the installation just becomes
Copy code
install commandbox-awsimds
One side note-- I mentioned this the other day, but does AWS have an endpoint that returns all the data available as a struct instead of just getting one setting at a time? https://github.com/Gencia/commandbox-awsimds/blob/master/interceptors/awsimdsExpansion.cfc#L12
If it's the same amount of HTTP overhead to get all the settings and you are going to access more than one, it may be easier to just cache all of them if you can on the first call.
d
I was going to say no… but I think there may be… returns JSON… let me just recheck
does not have everything which is available through IDMS - but probably most of the useful stuff that anyone would require
For my own purposes… I’m not planning on getting anything other than instanceid - but I can see how that this would be better practice for a more general use case
also… with the symlinking - slightly more complex as local environment is entirely docker based…
b
Yeah, you brought that upon yourself when you decide to take on the complexities of Docker for local dev 😉
I love Docker, but not for local dev! 😆
I'm not a fan of layer upon layer of abstraction around my file system, networking, processes, logs, and settings when all I need is a nice, simple
Copy code
server start
d
Yeah… does make it easy to get dev environments up remotely for external contractors etc. in a consistent manner which is mostly independent of the system being used… and be much more confident that something that works locally will work within hosted environments subject to consistent configuration…. But yeah, does come with it’s downsides, and probably much less benefit when using Commandbox
b
Everything you said above also applies to CommandBox 🙂
make it easy to get dev environments up remotely for external contractors etc. in a consistent manner which is mostly independent of the system being used… and be much more confident that something that works locally will work within hosted environments subject to consistent configuration….
☝️ ☝️ ☝️ ☝️ ☝️ ☝️
Copy code
git clone ...
box install
box server start
I do like docker compose for a few projects where there are hard dependencies on several specific services like elastic search, redis, or SQL which must be run locally as well.
But luckily in most of my cases, all I really need is the CF engine spun up
d
Yeah - was going to say… when working with SOA with multiple dependencies… docker works well… but for basic, probably adds more overhead than is worthwhile… However… it’s one of those… is it more work to change what is working and something for which we have a consistent approach between dev / test / prod environments… or come up with something new (and simpler) for the cases where that approach would be more suitable… ..and still, there would be more difference between the local and prod environments with that approach - one using docker / nginx / multiple services, and one where you are just using commandbox… I suppose I’ve been burnt too many times over the years with issues caused by environmental differences… that an approach where I can run identical images in multiple environments, and be pretty confident that in the vast majority of cases, if it works locally, it will also work remotely… is more appealing to me than maybe is warranted… And for stuff where your stack is made from multiple dependant web services, and relies on nginx etc. for URL rewriting, S3 proxying and client cert based authentication… then the docker exclusive approach has some additional benefits
b
there would be more difference between the local and prod environments with that approach
I actually think it's far fewer differences than people realize. The JVM itself already provides a abstraction layer, and CommandBox is capable of dialing in the exact version of your CF engine, and even your JDK version. If I were to draw a Venn diagram of all the configuration things that could make a difference between dev and prod, there would be a huge circle of things and then an ever-so-slightly-smaller circle inside labeled "stuff CommandBox lets you control" 🙂 Heck, CommandBox even lets you force the case sensitivity (or lack thereof) for static files in the web server so you can be on Windows and pretend it's Linux or vice versa!
relies on nginx etc. for URL rewriting, S3 proxying and client cert based authentication
CommandBox already does • URL rewriting • client cert auth (new in the latest version!) I'm not sure what you mean by S3 proxying, but I'm curious, since Undertow's built in HTTP proxy can probably do it too!
Our Ortus sites and most of our client sites deploy on Docker/CommandBox in production, so it's actually a very short trip to get to a local dev environment running CommandBox because it's literally all the same JSON files we use in prod for
server.json
,
box.json
, and
.cfconfig.json
but just without the complexities of Docker wrapping it.
d
As in CMS uploads files to S3 via lucee mapping, but for direct links referencing those files, (images etc.) they are proxied directly to s3 https endpoint without having to go through lucee… but whilst still appearing to be hosted on the same website
b
Yeah, you could do that with CommandBox 🙂
Here's a similar example in our Server Rules examples page
Copy code
path-prefix('/reports') -> reverse-proxy({'<http://reports1.mydomain.com>','<http://reports2.mydomain.com>'})
d
ah cool
b
Simple round robin load balanced reverse proxying to back end servers
The list of stuff you can't do with our web server has gotten very small, especially since we conquered client cert auth
CommandBox's web server is also more secure than default for CF apps than any other web server, so I almost hate to ruin it by sticking something in front of it to proxy 🤣
Ironically-- I'm writing up instructions right now for a huge enterprise company to replace a bunch of their Nginx+/Lucee/Tomcat installations with straight CommandBox. Fun stuff
Anyway-- I don't know how I got us off talking about CommandBox servers, lol. Carry on 🙂
d
not everything which commandbox is not capable of… has been available for ever… like the client cert stuff… that’s a more recent addition The main and most complex app we are working with, was initially migrated from windows / CF9 to docker / nginx / lucee… and then from there commandbox was introduced, mainly for config, effectively by substituting cg docker image in there instead of the official lucee docker image… then as time has progressed we have used more of CB functionality - but still probably only really scratch the surface of what it is capable of. I think maybe if we were starting again… and had appropriate budget… then we would look at a no nginx / CB only route… and see if docker local was still the best approach
but yeah… getting diverted… strange how that happens 😉
FYI @bdw429s… Module published as is… although I did put a little bit of documentation together and notes as to potential future improvements… https://www.forgebox.io/view/commandbox-awsimds Got to say… I really like how you’ve set this up… the whole process for creating a simple package for extending CommandBox, for custom namespace expansion, and for publishing… so much more straightforward and well documented than the majority of systems I’ve worked with and tried to extend in my ~22 years a professional developer!!!
b
Sweet, thx!