How to keep Environment-based secrets out of code? - visual-studio

(branch off my DefaultAzureCredential question)
Developing in C#, VS2022, I want to use Default Azure Credential (and machine Environment variables), and keep the secret from my App Registration out of my code. However, the only way I can find to test the code, or use the code in any other debugging environment, is to store it in the Debug setup, which then includes it in the code. Is there any other way to do this?

Related

Apparent Net7 dll Differences using Blazor Wasm with Shared Netstandard Libraries

Good Afternoon,
I apologize for the title if it is weird, as I don't really know how to describe this.
To describe my project:
Project has been fine for months
Blazor Wasm project, using Identity Server
Separate Identity grpc service for authenticating logins (hit by Server project piece of the mentioned wasm project)
Both grpc service and wasm use shared organizational nuget packages for identity objects (netstandard libraries)
Key Piece: There are protobuf.net metatype setups for the MSFT dlls that are serialized within Grpc service. E.g. as we cannot set the protomembers for these classes (ClaimsIdentity is one of them, at is the focus of this issue) The metatype setup is to expose the necessary properties to both client and service...
Recently, wasm was updated to net7
When deployed, the metatype setup for ClaimsIdentity blows up, stating that the field "Label" cannot be found. App doesn't run, fails within Program.cs...makes sense...so far...
Now, first thing I did was switch to the dev branch, pull latest, etc. Run locally, don't get the same issue; no issue at all actually, ran without any problems. Do "Go To Definition" and see the Label field within the ClaimsIdentity class (netstandard).
After updating VS, rebuilding, etc... I push out a pacifier release so people can test (removed the ClaimsIdentity line as the wasm piece doesn't need it, we're just reusing a helper method that had it in there). I then go back and try the Go To Definition stuff again, this time, I'm directed to the 7.0.0.0 dll of System.Security.Claims. The class is definitely different than the netstandard one (why I'm now sent to this definition, I dunno, I suspect caching of code/dll I dunno, whatever). Still, I cannot duplicate the issue when debugging.
At this point, after seeing that I'm getting different files on my own machine. I decided to use ILSpy and see if the deployed System.Security.Claims dll is the same....it is not. It is also System.Security.Claims v7.0.0.0, but only has a _label, private property.
Easy fix is just to remove the line throwing causing the issue, but, that is superficial. I'd like to know what I'm missing in why I'm seeing different contents between net 7 dlls. I'm thinking I'm overlooking something dumb, actually, I hope that I am.
Image: Left is Locally Built, Right is what gets deployed (both being Azure Devops and manual publish)

How do I Setup an Agent Requirement in TeamCity that detects if an Application is installed?

I have a build environment with multiple agents.
I would like to set up an Agent Requirement in my build that detects if certain software is installed. In some cases I can look in the env.Path for a particular string. But some software doesn't modify the Path.
I realize that after I install the software i could edit the BuildAgent.properties file to set a particular property, but I'd like it to be more automatic.
The specific instance is I have a build that uses MSDeploy to deploy websites, but it won't work if MSDeploy isn't installed. How can I specify in my build that I need an Agent that has MSDeploy installed?
You can build a simple agent plugin. Here are a few suggestions:
Extend AgentLifeCycleAdapter and implement agentInitialized method
Implement logic of detection the necessary application (for example based on some file existence) inside agentInitialized method
Use agent.getConfiguration().addConfigurationParameter() to report agent parameter to the server
If your detection logic can be implemented through file detection, you can use FileWatcher to monitor specific files and report parameters based on them even without restart of the agent
To my knowledge Agent Requirements work simply by validating either the existence of, or the value set in an Agent Parameter. As you say, this requires editing the <agent home>/conf/buildAgent.properties configuration file, either manually or in some automated way.
In terms of automation, you could take the approach of authoring a build configuration that acts as an agent bootstrapper; i.e. a build that runs on all agents (scheduled overnight / manually triggered) and maintains build agent parameters in the <agent home>/conf/buildAgent.properties file depending on certain conditions on the agent. Something like (pseudo):
if [ exists /path/to/MSDeploy ] then echo MSDeployExists to buildAgent.properties
This comes with a big disclaimer; I haven't tried this myself, and I believe that the agent will restart automatically based on changes to this file, so there may be issues with editing that file automatically. But it's a potential solution to maintaining your requirements in a centralised manner, and if it works then great. I use a similar approach to bootstrapping custom build scripts out to all agents to augment the already rich feature set in TeamCity.
I agree with the answer from SteveChapman. It is clear that you can test for environment variables (exits, contains, starts with, etc.). TeamCity is aware of versions of .NET installed on the agent (as well as Visual Studio, and VS SDKs). However, I can't find anything that would be equivalent to a "testpath" sort of capability.
The sure way to know is to add an agent parameter via the <agent home>/conf/buildAgent.properties configuration file.

What's the point of the Release vs Debug dropdown in Visual Studio if changes don't take hold unless you Publish?

I have web config transformations set up that work fine when I publish to something like Azure. But selecting between Release and Debug locally seems worthless if the web.config transformations don't actually get applied when running locally.
Is there any way to get these transformations to apply when I click "run"? If not, what's the point of having that dropdown? I'm genuinely curious, not asking rhetorically.
The idea for web.config transforms is that you have some settings that change between environments. For example, you might have a local development connection string, and you'll always use that when running/debugging locally. When you publish to your production server, though, you want to use your production DB. Debug vs. Release configurations at build time just change some settings in how your project is built (most commonly, how debug symbols are generated or what compiler optimizations are enabled), whereas web.config transforms are changing the content of what gets deployed (in web.config).
If you do want to apply the web.config transforms locally on F5, there are extensions that allow you to do so. Slow Cheetah is one such. However, in many cases, you probably don't need this as your web.config will stay mostly constant whenever you run locally.
Almost all IDEs have release and debug modes, in the debug mode, the code is compiled using debug flags and not so much optimization, i.e., some relation between the built program and the source code is kept, in this way you can run your code using a debugger, it is a tool that allows you to track and control the flow of execution of your application, for example the value stored in some variable in some situation in your code, this in order to expose semantic problems that your application may have, i.e., when your code is not actually doing what you expect it to be doing (most of the people does this using print statements everywhere at least once).
The release mode is aimed to produce an optimized version of your application, without debugging/profiling flags.
Notice that this have nothing to do with debug mode of web applications, where we set automated views to show more information when a run time error occurs, it just have to do with optimization or debugging of the actual program running underneath. So setting debug or release mode may not change whether a web application shows tracebacks or not, but it certainly changes the performance of the application running locally in your server.
Regards.

Managing connection strings in source controlled application that is continuously deployed to Azure websites

Here's the scenario: I have multiple developers on an asp.net mvc 4 project. Each developer has a local database. The source control system is TFS at http://tfs.visualstudio.com. We're using Azure websites to host the site. We have also configured Azure websites for continuous deployment.
The source control system could be git, mercurial, TFS, etc. Honestly, I don't think it matters.
My question is how to accomplish these three things:
Each developer has his/her own connection string(s) locally (without them being in source control)
Azure has its own connection string(s) (without it being in source control)
Source Control doesn't show any connection information
The ability for each developer to F5 and run/debug/test the app locally.
We accomplished #1 by adding our individual connection strings to our machine.config so that there's no conflict between developer workstation setups.
I originally removed the connectionstrings section from web.config. In the Azure website (using the management portal, under Configure), I configured the connection strings, and after watching a Scott Hanselman video was under the impression that these would be dynamagically merged into my web.config upon deployment, but that doesn't appear to happen. Whenever I go to any page that hits the db, I get an error saying can't find the connection string (or some other db error related to the connection)
If I put the Azure connection string directly in web.config, Things work on Azure, but then the connection details are in source control visible to everybody.
After reading some more posts from Scott and David Ebbo it seems that I could put a blank connection string in web.config (with the correct name) and then Azure will overwrite the values correctly. I would then have to have the developers put their connection strings in their web.debug.config and then install the Slow Cheetah plugin so that they could F5 and test locally. They would also have to not check in the web.debug.config into source control. (Not that easy with TFS) This seems like a seriously burdensome kludge, that's bound to fail somewhere along the line.
I have to believe that this isn't that rare of a problem. How do other teams accomplish this?
After looking around, it appears that what I was asking isn't actually supported without a bunch of command line hacks to the pre/post build process. What we ended up doing is forcing developers to all create their own local databases, use trusted authentication, and establish a SQL alias that was used by all developers in the web.config. That way, it works locally for everybody, it doesn't expose any user names/passwords within source control, and Azure can still overwrite it when automatically pulled from source control.
Slow Cheetah is actually a nice solution. It's an extension to web.config transformations. Those transformations let you keep one web.config file and then for each deployment scenario you specify which changes you want to it. For example, your Release configuration will probably remove the debug attribute.
This can also be used to change connection strings. The transformations are applied during the deployment of your project to Azure.
What I've done in the past to make this also work with local development machines is use a web.config with an externalized connections.config file. Each developer created a connection.machinename.config file that was copied to connection.config on build in the post-build step. Those files don't have to be checked in and they can never cause conflicts because each machine name is unique.
The release/staging/.. configurations used a web.config transformation to replace the connection string element with a specific connection string for that deployment (and that way remove the dependency on the external config file).
Slow Cheetah offers some nice helpers for checking the result of these transformations at design time.

Debug single role instance with Azure Compute emulator

I'm building an application which will be run on Azure. My Visual Studio solution contains multiple Azure role projects. When debugging locally, I use the Azure compute emulator.
To start debugging, I follow these steps:
I right-click on my Azure project and click Set as start up project.
I press F5 to start the debugger.
What happens now is that the emulator/vs2010 launches both my web roles and worker roles, even if I'm only interested in debugging a single worker role at the moment. Often when writing some background-processing code in my worker role, I'm interested to step through that code without starting the web role, launch Internet Explorer and so on as well.
Is there a convinient way to make the debugger only launch one of the role instances and not all of them?
I'm thinking of creating a separate project in my solution of type Console Application, where I load the same assemblies as in my worker role and execute the same code.
The emulator (similar to Azure itself) works just on the concept of a "Cloud Service". So when you launch w/ debug, its going to launch whatever is defined in your Cloud Service (.ccproj) project. This mimics Azure 100% which is why it occur, but I can definitely see where your scenario would be helpful.
Few options, based on your needs.
If you need to test azure-specifics (aka it has to run in the emulator)
Create a second solution file, create a new Cloud service in here, add your project. I like this option because the projects/roles themselves remain untouched.
What Stuart suggested before me, create a second Cloud Project, set as startup, run that.
Similar to above, create a second project, but don't worry about startup. You can right click on any project, go to Debug and select start w/ debugging and achieve what F5 does without binding F5 to this solution
If you dont need to test azure-specifics (ie you are just testing the role)
Right click on the role's project, Debug, Start with Debugging This way the whole solution remains intact and you are just testing the logic
I think you can do this by:
create a new Azure Cloud Project within your solution
add just the one worker role to that cloud project
set that cloud project as your startup project
This will single out just the worker you are interested in
An easier solution would be to open the ServiceConfiguration.cscfg file, and set the "Instances > Count" property to "0", for all the roles that you don't want running (this only works in the compute-emulator, and NOT on the azure cloud).
That way, you keep your solution intact and your configurations safe, while just omitting them from the compute-emulator during run-time.

Resources