>> One of the factors in Cloud-native app states,
you should store your configuration and
settings outside of your application code.
In this episode, Andrew gives us
a rundown on how configuration options in
.NET Core allows for layers of
configurability and abstractions for your app.
Let's go have a conversation with Andrew.
[MUSIC]
>> Hey Andrew.
>> Hey Shayne.
>> How are you, man?
>> Pretty good.
>> All right. So configuration in ASP. NET Core.
>> Yeah.
>> It's come a long way.
>> Certainly.
>> So when I used to do configuration in my ASP.NET apps,
it was an XML file or many XML files, right?
>> Really just the one big XML file.
>> If I mess up that XML file, it wrecked my day.
>> Yeah.
>> So I know that you've been working with the team
and we've been making this better for Cloud-native apps.
>> Yes.
>> So I want to have a conversation and see what we've done,
what options we have, and see where we've come
from that big XML file and talk about security,
layering, and all of the work that you've done with the team.
>> Yeah.
>> Let's just go have the discussion.
>> We can go upstairs.
>> Yeah, it's good.
[MUSIC]
>> All right, Andrew. So by default, .NET Core manages
our settings and our configuration, kind in a, order of operations.
We've got a lot of options as to where we
can store our configurations in our settings.
Can you talk about how that works and what
overrules what when it comes to the decisions
the framework makes as to what wins?
>> Yeah, it's a layering system, basically.
Because you have different sources
of configuration in your app usually.
Sometimes you've got like a JSON file,
you might have environment variables,
you may have some configuration
that's actually just code in your app.
So we allow you to layer those things
and configure the layering the way you want.
So by default, we have some pretty sensible defaults.
So you've got a JSON file in your app by
default that has the settings. On top of that,
if you have any settings in your code,
those can override that.
>> Okay.
>> If you have environment variables
which are very common like,
for this instance of the app,
I really want to set this config this way.
That overrides all of it.
But even that default layering, it's completely configurable.
Configurable configuration I might say,
where you can just wired up in the order you want
and the particular settings can be overridden at different layers.
>> Okay. So given that, can I mix those options?
Can I have a JSON file and
an environment variable and in any file?
>> If you want to.
>> An XML?
If I really want to get crazy and I say,
"I want all of these different ones," and
I can just put those in there
and the framework just knows that I can do that,
the configuration middleware is what we're talking about here.
>> Yes.
>> What it says in there, right? So what about environments?
What about, I've got QA,
I've got staging, and got that.
So in the past,
if I go back to previous versions of ASP.NET,
I would have to do XML transforms to do that
and dealing with those big XML files.
In the Build, I believe we were using MSBuild
to do that and there was a craft to making that
happen and have to set that up for my QA in my dev and that.
What's the practice of doing that now
to separate my environment and making that work?
>> Yeah, in the past you were used to
transform the config as you built.
You'd end up with a different output for development,
for staging, for QA, etc.
What we've tried to do now is really separated out so that
that configuration can be adjusted at runtime
depending on where you're running.
So the environment that you talk about,
that's just one of the settings that we place
and know as this is the environment name.
Development by default,
you can set it's production and set staging.
The name is up to you and then you can make decisions
based on that including decisions about configuration.
So you can say, by default,
and we talked about the layering,
by default we're going to load this one JSON file
that defines the config for my app.
But if we're in development,
we're going to load another JSON file after that
and override any of the settings in there.
>> Okay.
>> Before, in production, we will load
a different JSON file and override settings.
So you can have different settings based on
the different environments and you can change
those and change environments
without redeploying your app and in design.
>> So is that a naming convention that we have?
>> Yeah. The name is development, staging, production.
That's just our defaults that we've chosen.
You can choose whatever you want.
>> So this allows me to take my files.
In our previous episode,
we talked with Abel about DevOps.
So now I can take those files and store them
separately in my configuration GitHub
repo outside of my code and be able to manage
that in my DevOps process and deploy that
with my code to the necessary environments.
>> Right.
>> This knows how to happen.
>> Yeah, and you can build your code artifacts once
and then deploy them to your different environments
with different configuration as you do it.
>> Okay, awesome.
Well, now that we've got a base of what's in the box,
and we've got an idea of how the middleware works and doing that.
What about taking some of the stuff and externalizing it,
not just in files but maybe pushing this
into my Cloud environment because when it comes to a Cloud-native,
I want to make sure that I'm not tied directly to my code.
We are now talking about files,
but what if I want to put
this configuration actually in my Cloud platform
and talk further into maybe some of
the security and things of that nature.
What's the story there?
Again, making some of those configurations.
What do we have available to us either in
a .NET ecosystem or maybe in Azure ecosystem?
>> Yeah. We talked about Files and environment variables.
These are all just providers that we provide out of the box.
It's a completely pluggable system.
You can plug in whatever system you want to store
your configuration but we also provide
a lot of really powerful options for you.
We've got files, we've got the environment variables.
That's really good.
The environment variables tend to be really useful for those,
I have some things in production in
my Azure App Service maybe you set those app settings,
they come out as environment variables and
they just appear in your app.
But when we talk about going to large Cloud-native applications,
we talk about wanting to centralize configuration so
as to be able to manage it across all your different services.
That's where we get into some of the Azure services like
Azure app configuration which allows you to do exactly that.
They have a system that plugs right into
the .NET Core configuration model.
It loads the config off of
a central configuration store
and you can just access it just like any other.
The best part is, your code
doesn't have to do with the difference.
So when you're running in development,
they could all be in a JSON file and
you can be testing against that JSON file.
Then when you deploy to production,
in the production environment,
it's pointed to this Azure app configuration service
and they're just loading and the code hasn't changed to do that.
>> We still handle that as far as
the layering is concerned too, right?
>> Right. So your development settings might be in
that JSON file and then they get overwritten
by the settings in Azure app configuration.
>> Now, if we're using something as far as
security may these settings to provide-
Do we have a built-in provider for some of
the Azure Key Vault to secure them,
and then I can then use that across other apps even?
Do we have a provider for that as well?
>> Yeah. So we have Azure Key Vault provider as well.
I think Azure App Configuration
and Azure Key Vault make a really good pair in
this model because app configuration can be
for your general configuration settings.
The things that aren't necessarily secrets
that need to be up hard securely managed.
Then, Azure Key Vault, which is the hardware
protected secure datastore in Azure,
can plug-in as well,
and again, we get the layering.
So you can have your JSON file, your App Configuration,
and your Key Vault secrets can
layer into that and mix in with that.
So you can store your database password,
or your credentials for some service in Key Vault.
But you can store all the rest of
the settings about your database,
or the rest of the configuration
but you need to access that service,
can be stored in the App Configuration store
and then the Key Vault stuff just merges in with that.
>> Okay. It's good you mentioned
connection strings because it brings up
a point about just conventions.
I know that, and this may or may not be true,
but when I'm building up these different files
in different environment variables,
I say like knowing my environment,
like I know it's a development environment,
are there naming conventions that we should be
aware of when we're abstracting this from our code,
like ASP.NET Core_ environment.
>> Right.
>> It's one pattern,
are there other patterns to be aware of
when we're pulling this out of our code,
that we need to worry about or be cognizant of,
when putting in these configurations and abstracting it,
other patterns that we should be aware of?
>> Most of the biggest pattern I think is
some consistency, is really valuable.
One of the things we still learned early on is,
when we started with .NET Core,
we had this really powerful flexible configuration system,
and we provide no defaults.
We didn't provide you with the Default JSON file,
we said you can do whatever you want,
and that was great, and then people said but what should we do?
So in later versions of .NET Core,
we've brought in some default settings,
some default names for setting.
So there's tons of things in .NET Core you can configure.
You can configure the server,
you can configure the authentication systems,
the logging, that kind of stuff.
It was all very decoupled originally,
and you didn't know how to plug them together,
but now, there's very consistent naming.
The names of these settings is well defined, it's understood.
So when you're building say
a component for use in a Cloud Native app,
that may be used in multiple different kinds of apps,
having some consistency there is really valuable,
being able to just define,
hey, however you're doing config,
these are the names of the settings.
You mentioned the ASP.NET Core_ environment,
that's a well defined name and we
document that and make that very clear.
>> Connection strings, I believe is connection strings_.
>> Right.
>> All right. We can check our docs and
we've got that well documented in ASP.NET for that.
So let's jump back into security real quick.
>> Yeah.
>> You mentioned, and we talked a little bit
about the Azure Key Vault implementations,
their capabilities we have.
Is it just built in?
Do we have a provider?
How do I get that into my app?
Can you talk a little bit about how do we take control
of those capabilities and insert that into our app?
>> Yeah. So we have a built-in provider that you can just enable.
You do run into this kind of catch 22
when you're dealing with something
like Key Vault because you've
got all your settings are stored in Key Vault.
Well, that's great, but how do you connect to Key Vault?
That is the setting itself.
One of the things that Azure does to make that
really easy is this Azure Managed Service Identity.
So this is the idea that you
can install it on your Virtual Machine,
your Kubernetes Service, wherever.
It's supported on all these various Azure compute services.
Wherever your service is running,
you can enable this managed service identity and
you can give that resource,
that container, that PPOD in Kubernetes,
or the VM, access to key Vault directly.
You can authenticate that, and you can say
you can only access these certain settings,
you can access these value, you can do these things.
When you do that,
you've freed up somewhat from having that,
well, where do I put the password for the Key Vault.
>> Sure.
>> Where do I configure the password for
the Key Vault if the passwords are in the Key Vault?
>> Okay.
>> With managed service identity,
you've got that kind of built-in identity
that allows you to just have
that trusted link between your runtime components,
your containers, and the Key Vault.
>> So do I have to use the Manage Servers Identity
or can I just take that password and then also put it into
something like my environment where it goes on my service,
or embedded into my container that I'm running?
You're right, we do get into this,
where do I hide the AIG a little bit with our IDs and passwords.
I would probably defer to my DevOps person,
or maybe I'll call Abel again and say,
''Hey, I've got all these passers.
How do I manage that and have that as a follow-up? ''
But it does get into the practices
and relationships between some of our services,
our DevOps practices, these passwords and configurations,
and how do we manage those things.
Are there some other things that we're
doing in the framework when it comes to
configurations and settings related to
Cloud native that we need to be aware of?
Are we doing something special in containers,
in some of the other managed
middle frameworks that you
can think of that we should be aware of?
>> Well, containers are another-
There are big space that we're looking at when we build
these Cloud-native apps and these Cloud-native frameworks.
We have for example built-in
configuration support for Docker secrets,
and for Kubernetes secrets.
Again, like we talk about everything being in the box,
Like we tried to put as much as we can in
the box so that you have all the tools you need,
but you also have the flexibility you want to do what you want,
and containers are right there.
There's something we support with a lot of our defaults.
>> The good thing is, I know just from using
the product that just because it's built into the box,
we're not constrained to that.
We can take that and you put it into other places
like the actual files in
the environment variables, put them into Key Vault.
So we have some flexibility, again,
looking to the docks to give that
prescriptive guidance on how we're doing things there, right?
>> Yeah, and I think one of the big things we've
done with.Net Core is everything is visible.
We don't hide things away in
these complex systems and complex configuration models,
where everything's in one giant file,
you don't know where to find it, how to
move it, how to figure that out.
But we have some defaults that
make some really nice prescriptive guidance to say,
''This is a way we think works really well.''
But it's transparent, you can do what you want,
you can adjust it how you want.
>> Great. Do you have any closing tips,
things you can point out,
point people to when it comes to using configuration,
when it comes to building these native apps,
or maybe lessons learned that you can point
the community to and give them some guidance on?
>> A lot of it is contained in our docs.
I think we have a really good amount of docs about just
describing all the ways that you can configure things,
and the way you can just set it up.
They have a lot of good docs on
the patterns you use to actually consume
the configuration in your code
because that's a whole another section here.
The configuration is really just the strings,
the key value pairs.
But how do you actually find that to some rich data objects
that you can use to actually pass into
various components and then use to build your app.
We have a lot of good docs on that as well.
>> Okay.
>> The thing we've learned most about configuration is
that flexibility is really good,
but it's also useful to be prescriptive in places, and to say,
''Yes you can do whatever you want,
but here's the pattern that we think works well.''
That's something that I think also holds true to people
building Cloud native components or individual services,
that in order for these things to work well together,
having some conventions, having
some default patterns helps out a lot there.
>> Awesome. Andrew, thanks for coming on the show.
That was configuration with Azure .NET Core and Cloud Native apps.
Be sure to check out the show notes and the docs related to this,
and we will see you next time.
Thanks for watching the Cloud Native Show.
Be sure to subscribe,
watch for a future episode,
and especially our streaming shows on Twitch,
where we build apps based on
the conversations we had right here. We'll see you next time.