<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Umut</title>
    <description>The latest articles on DEV Community by Umut (@learn4ops).</description>
    <link>https://dev.to/learn4ops</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2470463%2Ffcf24d3b-548d-4ecb-a34c-a9adec1c7739.jpeg</url>
      <title>DEV Community: Umut</title>
      <link>https://dev.to/learn4ops</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/learn4ops"/>
    <language>en</language>
    <item>
      <title>The perfect combination for Azure Key Vault integration with AKS (External Secret Operator + Reloader + Workload Identity)</title>
      <dc:creator>Umut</dc:creator>
      <pubDate>Mon, 17 Feb 2025 19:13:27 +0000</pubDate>
      <link>https://dev.to/learn4ops/the-perfect-combination-for-azure-key-vault-integration-with-aks-external-secret-operator--4fgi</link>
      <guid>https://dev.to/learn4ops/the-perfect-combination-for-azure-key-vault-integration-with-aks-external-secret-operator--4fgi</guid>
      <description>&lt;p&gt;Hello everyone !&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I will show a quick demonstration of how we can  use this integration with simple steps. I believe this is one of the most secure and easy to use method to read secrets from Azure key vault. In particular, if you're using IaC tools and creating SQL servers, app registrations and so on, you're passing secrets to the Key Vault during creation and reading them in kubernetes. There are several other methods and possibilities. But we won't compare them in this article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's get started&lt;/p&gt;

&lt;p&gt;Essentially, these are the requirements for this example,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Azure Kubernetes Service with Workload Identity enabled&lt;/li&gt;
&lt;li&gt;External Secret Operator&lt;/li&gt;
&lt;li&gt;Reloader&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What are these tools ? Here are the official for deep dive links.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/aks/workload-identity-deploy-cluster" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/azure/aks/workload-identity-deploy-cluster&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://external-secrets.io/latest/" rel="noopener noreferrer"&gt;https://external-secrets.io/latest/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/stakater/Reloader" rel="noopener noreferrer"&gt;https://github.com/stakater/Reloader&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The flow will be like this, &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcm9y7h7r4bn7vfmbe316.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcm9y7h7r4bn7vfmbe316.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;to make it more secure, &lt;strong&gt;private endpoint&lt;/strong&gt; and &lt;strong&gt;internal ci/cd agent&lt;/strong&gt; should be used. I will be acting as an agent in the article.&lt;/p&gt;

&lt;p&gt;All of this will be documented as code on this GitHub repo as well,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Learn4Ops/esowir" rel="noopener noreferrer"&gt;https://github.com/Learn4Ops/esowir&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone https://github.com/Learn4Ops/esowir&lt;/code&gt;&lt;br&gt;
&lt;code&gt;cd esowir/infrastracture&lt;/code&gt;&lt;br&gt;
&lt;code&gt;az login --use-device-code&lt;/code&gt;&lt;br&gt;
&lt;code&gt;terraform init&lt;/code&gt;&lt;br&gt;
&lt;code&gt;terraform apply --auto-approve -var "subscription_id=xxxxx" -var "tenant_id=xxxxx"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Subscription id and tenant id are required&lt;/p&gt;

&lt;p&gt;The key point is to manage the subject part for managed identity,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;subject             = "system:serviceaccount:testapp:external-secret-service-account"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And this managed Identity will need 'Get' secrets permission.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl4oso05very52urfe01p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl4oso05very52urfe01p.png" alt="Image description" width="171" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will create service account and use the namespace as above.&lt;/p&gt;

&lt;p&gt;Let's connect kubernetes and install required objects.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;az aks get-credentials --resource-group aks-resource-group --name aks-cluster --overwrite-existing&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We will work on these namespaces,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl create ns external-secrets&lt;/code&gt;&lt;br&gt;
&lt;code&gt;kubectl create ns testapp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Helm Charts,&lt;/p&gt;

&lt;p&gt;ESO,&lt;br&gt;
&lt;code&gt;helm repo add external-secrets https://charts.external-secrets.io&lt;/code&gt;&lt;br&gt;
&lt;code&gt;helm install external-secrets external-secrets/external-secrets -n external-secrets&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Reloader,&lt;br&gt;
&lt;code&gt;helm repo add stakater https://stakater.github.io/stakater-charts&lt;/code&gt;&lt;br&gt;
&lt;code&gt;helm install reloader stakater/reloader -n external-secrets&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Key vault secrets should exist (terraform already created), 'test-password' , 'test-username'&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feprltihyzw64b8sgitoi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feprltihyzw64b8sgitoi.png" alt="Image description" width="779" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okey, now everything is ready to test the flow, with the following command we will install each kubernetes object, so let's check it first.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a service account to use as the workload identity&lt;/li&gt;
&lt;li&gt;Create a CRD named SecretStore that will use the service account and connect to Azure Key Vault&lt;/li&gt;
&lt;li&gt;Create CRD named ExternalSecret that will create kubernetes secret using SecretStoreRef&lt;/li&gt;
&lt;li&gt;Create deployment which will use kubernetes secret&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;kubectl apply -f ../application&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Check service account, If you are following don't forget to change related fields&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg949nl3r81sshyyi31fi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg949nl3r81sshyyi31fi.png" alt="Image description" width="381" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl get sa -n testapp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can check SecretStore health, Detailed API guide: &lt;a href="https://external-secrets.io/latest/api/secretstore/" rel="noopener noreferrer"&gt;https://external-secrets.io/latest/api/secretstore/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl get secretstore -n testapp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F619jwspf347l3esfd9lw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F619jwspf347l3esfd9lw.png" alt="Image description" width="384" height="28"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also External Secret, Detailed API guide: &lt;a href="https://external-secrets.io/latest/api/externalsecret/" rel="noopener noreferrer"&gt;https://external-secrets.io/latest/api/externalsecret/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl get externalsecret -n testapp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4s1cld8tl25ppit9ivb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4s1cld8tl25ppit9ivb.png" alt="Image description" width="614" height="29"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks good, so secret should be created&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl get secret -n testapp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then I will check the secrets values from the pod,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl exec -it -n testapp testapp-deployment-65f7dc494c-xztjw -- sh&lt;/code&gt;&lt;br&gt;
&lt;code&gt;echo $TEST_USERNAME&lt;/code&gt;&lt;br&gt;
or&lt;br&gt;
&lt;code&gt;echo $TEST_PASSWORD&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Same as azure key vault values,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiz5lycu7fsg5ahxv81z7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiz5lycu7fsg5ahxv81z7.png" alt="Image description" width="148" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What about changing the secret? Reloader takes over here with the annotation adjustment,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fioxv8wulw6se90onnbbm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fioxv8wulw6se90onnbbm.png" alt="Image description" width="270" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the creation of new value,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt03dgrbuy23zgg0spl2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt03dgrbuy23zgg0spl2.png" alt="Image description" width="673" height="603"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then wait 30 seconds because the interval is set to this value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xubchkogarr3ub3hyk4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xubchkogarr3ub3hyk4.png" alt="Image description" width="152" height="47"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Amazing ! I don't need to worry about new secrets for rollout deployments.&lt;/p&gt;

&lt;p&gt;Let's clear the environment.&lt;br&gt;
&lt;code&gt;terraform destroy --auto-approve -var "subscription_id=xxxxx" -var "tenant_id=xxxxx"&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I mentioned earlier that to make it more secure, you can use Microsoft's internal network, Kubernetes should access KeyVault through a private endpoint, and creating the secret can be managed on the Azure side with an agent deployed in the container or virtual machine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's recap important advantages,&lt;br&gt;
&lt;strong&gt;-&amp;gt;&lt;/strong&gt; Workload identity is really great way to use Azure resources, in our case we didn't give any secret to use service account as identity and we filter related service account with namespace option.&lt;br&gt;
&lt;strong&gt;-&amp;gt;&lt;/strong&gt; External Secret Operator has a lot features, everything is documented on official site, not so complex to use and define configuration. &lt;br&gt;
&lt;strong&gt;-&amp;gt;&lt;/strong&gt; Reloader is very handy, if you have a lot of pods using secret and need to refresh this value, no worries, you just wait for new secret to restart pods automatically.&lt;/p&gt;

</description>
      <category>aks</category>
      <category>azure</category>
      <category>azurekeyvault</category>
      <category>workloadidentity</category>
    </item>
    <item>
      <title>Register Azure DevOps Agents with Service Principal Secret !</title>
      <dc:creator>Umut</dc:creator>
      <pubDate>Mon, 25 Nov 2024 20:23:20 +0000</pubDate>
      <link>https://dev.to/learn4ops/register-azure-devops-agents-with-service-principal-secret--1dmc</link>
      <guid>https://dev.to/learn4ops/register-azure-devops-agents-with-service-principal-secret--1dmc</guid>
      <description>&lt;p&gt;Here are the short instructions to add Azure DevOps agents using an app registration secret instead of your PAT!&lt;/p&gt;

&lt;p&gt;As a standard you can register your agent by following this &lt;a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/service-principal-agent-registration?view=azure-devops" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;However, when it comes to using the Service Principal (SP) option with the script, things get a little bit more complex.&lt;/p&gt;

&lt;p&gt;These other documentations ( &lt;a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/linux-agent?view=azure-devops" rel="noopener noreferrer"&gt;1&lt;/a&gt;, &lt;a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/agent-authentication-options?view=azure-devops#service-principal" rel="noopener noreferrer"&gt;2&lt;/a&gt; ) are very useful, but I just want to provide a clear example of how to use it.&lt;/p&gt;

&lt;p&gt;Thanks to these comments on GitHub and Developer Community, I figured out how to use the Service Principal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/microsoft/azure-pipelines-agent/issues/4641" rel="noopener noreferrer"&gt;https://github.com/microsoft/azure-pipelines-agent/issues/4641&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developercommunity.visualstudio.com/t/Self-hosted-agent-on-docker-setup-script/10650567?entry=problem&amp;amp;q=remote+testing+docker+compose" rel="noopener noreferrer"&gt;https://developercommunity.visualstudio.com/t/Self-hosted-agent-on-docker-setup-script/10650567?entry=problem&amp;amp;q=remote+testing+docker+compose&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Basically, it will look like this when using the script,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./config.sh --unattended \
  --agent "${AZP_AGENT_NAME:-$(hostname)}" \
  --url "${AZP_URL}" \
  --auth "SP" \
  --clientid "yourclientid") \
  --clientsecret "yourclientsecret") \
  --tenantid "yourtenantid") \
  --pool "${AZP_POOL:-Default}" \
  --work "${AZP_WORK:-_work}" \
  --replace \
  --acceptTeeEula &amp;amp; wait $!

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The auth parameter should be set to "SP", and you need to provide clientid, clientsecret, and tenantid.&lt;/p&gt;

&lt;p&gt;If you are using agent in &lt;a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/docker?view=azure-devops" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;, you'll also need to adjust the Dockerfile. Here are the parts that should be removed or modified,&lt;/p&gt;

&lt;p&gt;&lt;del&gt;if [ -z "${AZP_TOKEN_FILE}" ]; then&lt;br&gt;
  if [ -z "${AZP_TOKEN}" ]; then&lt;br&gt;
    echo 1&amp;gt;&amp;amp;2 "error: missing AZP_TOKEN environment variable"&lt;br&gt;
    exit 1&lt;br&gt;
  fi&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;del&gt;AZP_TOKEN_FILE="/azp/.token"&lt;br&gt;
  echo -n "${AZP_TOKEN}" &amp;gt; "${AZP_TOKEN_FILE}"&lt;br&gt;
fi&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;del&gt;unset AZP_TOKEN&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;del&gt;./config.sh remove --unattended --auth "PAT" --token $(cat "${AZP_TOKEN_FILE}") &amp;amp;&amp;amp; break&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;del&gt;export VSO_AGENT_IGNORE="AZP_TOKEN,AZP_TOKEN_FILE"&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;del&gt;AZP_AGENT_PACKAGES=$(curl -LsS \&lt;br&gt;
    -u user:$(cat "${AZP_TOKEN_FILE}") \&lt;br&gt;
    -H "Accept:application/json" \&lt;br&gt;
    "${AZP_URL}/_apis/distributedtask/packages/agent?platform=${TARGETARCH}&amp;amp;top=1")&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;del&gt;AZP_AGENT_PACKAGE_LATEST_URL=$(echo "${AZP_AGENT_PACKAGES}" | jq -r ".value[0].downloadUrl")&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;del&gt;./config.sh --unattended \&lt;br&gt;
  --agent "${AZP_AGENT_NAME:-$(hostname)}" \&lt;br&gt;
  --url "${AZP_URL}" \&lt;br&gt;
  --auth "PAT" \&lt;br&gt;
  --token $(cat "${AZP_TOKEN_FILE}") \&lt;br&gt;
  --pool "${AZP_POOL:-Default}" \&lt;br&gt;
  --work "${AZP_WORK:-_work}" \&lt;br&gt;
  --replace \&lt;br&gt;
  --acceptTeeEula &amp;amp; wait $!&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;Important Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pay attention to the VSO_AGENT_IGNORE variable, which helps prevent the client secret from being visible in Azure DevOps (and on the portal). This provides a more secure description of the agent in the portal.&lt;/li&gt;
&lt;li&gt;Be sure to remove the lines associated with the personal access token (PAT) and adjust the configuration for the Service Principal authentication.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>azuredevops</category>
      <category>cicd</category>
      <category>azure</category>
      <category>entraid</category>
    </item>
  </channel>
</rss>
