<?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/"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
>
	<channel>
		<title>Visual Studio Geeks</title>
		<description>Great posts on DevOps, Azure, GitHub, Azure DevOps (VSTS) and Visual Studio</description>		
		<sy:updatePeriod>daily</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
		<link>https://www.visualstudiogeeks.com</link>
		<atom:link href="https://www.visualstudiogeeks.comrss.xml" rel="self" type="application/rss+xml" />
		<lastBuildDate>Sat, 17 Feb 2024 00:00:00 +0000</lastBuildDate>
		
		
            
			<item>
				<title>Exploring GitHub Advanced Security for Azure DevOps</title>
				
					<dc:creator>Utkarsh Shigihalli</dc:creator>
				    
				<description>&lt;p&gt;It has been a few months since GitHub Advanced Security (GHAS) has been made generally available for Azure DevOps. During this time, I’ve engaged with numerous customers eager to implement GHAS within their Azure subscriptions. In this post, I wanted to show you a quick way to set up GHAS within Azure DevOps and explore the features available.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2024-02-17-exploring-github-advanced-security-for-ado/ghas-features.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;enabling-advanced-security-in-azure-devops&quot;&gt;Enabling Advanced Security in Azure DevOps&lt;/h2&gt;
&lt;p&gt;This is easy, however, you need to be a member of the Project Collection Administrator group. You can verify that from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Organization Settings&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Permissions&lt;/code&gt; and then the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Members&lt;/code&gt; tab. You should see your name.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2024-02-17-exploring-github-advanced-security-for-ado/permissions.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once you have verified you are a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Project Collection Administrator&lt;/code&gt;, you are ready to enable GHAS.&lt;/p&gt;

&lt;p&gt;You can enable GHAS either individually per repo or across the organisation for all the repositories.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2024-02-17-exploring-github-advanced-security-for-ado/repo-setting.png&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If you want to enable it for all the repositories in your organization, you will need to go to organization settings and then the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Repositories&lt;/code&gt; section and enable it there.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For this post, I am enabling it only for a single repository. Once you click the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Advanced Security&lt;/code&gt; flag (1), you will be prompted to show the number of committers you will be billed against (more on billing below). This repository has only me committing to it, so it has correctly identified 1 active committer (2).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2024-02-17-exploring-github-advanced-security-for-ado/billing.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once you click &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Begin billing&lt;/code&gt; GHAS should be enabled.&lt;/p&gt;

&lt;p&gt;If your ADO instance does not have a linked and active subscription, you might get the below error.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2024-02-17-exploring-github-advanced-security-for-ado/billing-error.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You will need to select an active Azure subscription under the Billing tab under organization settings in ADO.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2024-02-17-exploring-github-advanced-security-for-ado/billing-success.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once you select a valid subscription, you will be able to enable GHAS for the repositories.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2024-02-17-exploring-github-advanced-security-for-ado/ghas-enabled.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;exploring-ghas-features&quot;&gt;Exploring GHAS features&lt;/h2&gt;
&lt;h3 id=&quot;block-secrets-on-push&quot;&gt;Block secrets on push&lt;/h3&gt;
&lt;p&gt;Once you enable GHAS, by default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Block secrets on push&lt;/code&gt; feature is enabled too. With this setting enabled, ADO will automatically check any incoming pushes for embedded secrets and reject them automatically. Not only works on CLI, but it works on the web interface too.&lt;/p&gt;

&lt;p&gt;For a simple test, below I am trying to commit a file with the GitHub API key, and it was rejected.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2024-02-17-exploring-github-advanced-security-for-ado/block-secrets-on-push.png&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Note that at the time of writing this GHAS supports secrets push protection only for certain service providers. Although secrets from the majority of service providers are supported, I was surprised to see GitLab personal access token is not supported yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Although not recommended, there is a way to push a secret that has been blocked. To push, you need to have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;skip-secret-scanning:true&lt;/code&gt; in your commit message.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2024-02-17-exploring-github-advanced-security-for-ado/skip-scanning.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This will allow the secret to be committed, however, it will be caught in the Secret scanning alert (more on that below).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2024-02-17-exploring-github-advanced-security-for-ado/alert.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The great thing about GHAS is that clicking on the alert will give you remediation steps too.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2024-02-17-exploring-github-advanced-security-for-ado/alert-remediation.png&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;dependency-scanning-and-code-scanning&quot;&gt;Dependency Scanning and Code Scanning&lt;/h3&gt;
&lt;p&gt;Dependency and Code scanning are additional features of GHAS. Dependency scanning will scan any vulnerabilities in your repo from your open-source dependencies. Code scanning will scan your source code (from supported languages) for vulnerabilities.&lt;/p&gt;

&lt;p&gt;Both these tasks are enabled through pipeline tasks. On any GHAS-enabled repo, you will be able to run the pipeline with these tasks and get the status of the repo.&lt;/p&gt;

&lt;p&gt;You can create a pipeline and add the tasks for dependency and code scanning.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2024-02-17-exploring-github-advanced-security-for-ado/pipeline-tasks.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;However, this post has already gotten super long than I intended it to be, I will probably do another post and explore both of those functionalities in detail.&lt;/p&gt;

&lt;h2 id=&quot;pricing&quot;&gt;Pricing&lt;/h2&gt;
&lt;p&gt;GHAS for Azure DevOps is a paid product and is available only for Azure DevOps Services. For Azure DevOps Service linked to an Azure Subscription, this will automatically be visible in your billing for subscription. At the time of writing this, it costs &lt;mark&gt;49$ per active committer per month&lt;/mark&gt;.&lt;/p&gt;

&lt;p&gt;That is it for this post. Thank you for reading. 🎉&lt;/p&gt;
</description>
				<pubDate>Sat, 17 Feb 2024 00:00:00 +0000</pubDate>
				<link>https://www.visualstudiogeeks.com/devops/github/exploring-github-advanced-security-for-ado</link>
				<guid isPermaLink="true">https://www.visualstudiogeeks.com/devops/github/exploring-github-advanced-security-for-ado</guid>
			</item>
		
            
			<item>
				<title>Use a single repository for multiple wikis in Azure DevOps</title>
				
					<dc:creator>Utkarsh Shigihalli</dc:creator>
				    
				<description>&lt;p&gt;This is a quick post to share how you can use a single Azure DevOps repository for multiple wikis in Azure DevOps. This approach will help you avoid creating multiple repositories for each wiki and manage them in a single repository.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h2 id=&quot;create-a-new-repo-for-wiki&quot;&gt;Create a new repo for wiki&lt;/h2&gt;
&lt;p&gt;Firs lets create a separate repository for the wiki.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-12-07-using-single-azdo-repo-for-multiple-wikis/create-repo.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Create a repository&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;I want to create two wiki for two teams in my project. So I have created subfolders for each team in the repository and have placed a sample markdown files in each folder. The idea is that each team will place their wiki content in their respective folder.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-12-07-using-single-azdo-repo-for-multiple-wikis/repo-folder-structure.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Folder structure&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;publish-code-as-a-new-wiki&quot;&gt;Publish code as a new wiki&lt;/h2&gt;
&lt;p&gt;Now lets create a new wiki in Azure DevOps. Go to the project settings and click on the Wiki tab. We will publish new code wiki.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-12-07-using-single-azdo-repo-for-multiple-wikis/publish-code-as-wiki.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Publish code as wiki&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Do the same for the second wiki.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-12-07-using-single-azdo-repo-for-multiple-wikis/publish-code-as-wiki-2.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Publish code as wiki&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;This will create two wikis in the project.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-12-07-using-single-azdo-repo-for-multiple-wikis/show-wikis.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;configure-the-wiki&quot;&gt;Configure the wiki&lt;/h2&gt;

&lt;p&gt;As you can see that was easy. However, at it stands now, both the wikis are open for edits from all the team members. We need to restrict the access to the wiki content based on the team. We will make use of branch policies to achieve this.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-12-07-using-single-azdo-repo-for-multiple-wikis/branch-policy.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Set the branch policy&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Now, when any time changes are made to the wiki under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;01-team-infra/*&lt;/code&gt; folder and a PR is created, Infra team will automatically be included as reviewers. Similarly, for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;02-team-app/*&lt;/code&gt; folder, App team will be included as reviewers.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-12-07-using-single-azdo-repo-for-multiple-wikis/pull-request.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Pull request showing automatic reviewers added&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;That is it for this post. You can now use a single Azure DevOps repository for multiple wikis in Azure DevOps. As mentioned above, this approach will help you avoid creating multiple repositories for each wiki and manage them in a single repository.&lt;/p&gt;

&lt;p&gt;Hope you enjoyed reading this.&lt;/p&gt;

</description>
				<pubDate>Thu, 07 Dec 2023 00:00:00 +0000</pubDate>
				<link>https://www.visualstudiogeeks.com/azure%20devops/using-single-azdo-repo-for-multiple-wikis</link>
				<guid isPermaLink="true">https://www.visualstudiogeeks.com/azure%20devops/using-single-azdo-repo-for-multiple-wikis</guid>
			</item>
		
            
			<item>
				<title>Creating KEDA Scalar in Azure Container Apps using Azure Portal</title>
				
					<dc:creator>Utkarsh Shigihalli</dc:creator>
				    
				<description>&lt;p&gt;In this post, I would like to show you how we added custom scaling with KEDA using the Azure Portal — Thanks to the KEDA scaler, we have a dynamic scaling pool, which automatically scales when there are more jobs in the queue and scales back down when demand reduces.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;We run our Azure DevOps Build agents inside a container. This has allowed us to package various tools like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubectl&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;helm&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;terraform&lt;/code&gt; are installed and available inside the agent image, which gives us control over versions of the tools we use — as we can execute our continuous integrations with consistent configuration. Also, adding any new tool is just adding installation instructions to the Dockerfile and publishing a new image.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Microsoft has detailed documentation on running Azure DevOps agent inside a container &lt;a href=&quot;https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/docker?view=azure-devops&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Further, we are running our agents as an Azure Container App, which has freed us from maintaining a dedicated AKS cluster and lets us dynamically scale the agents — a new agent per pipeline job with the help of custom scaling rules and &lt;a href=&quot;https://keda.sh/&quot;&gt;KEDA&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;creating-an-azure-container-app&quot;&gt;Creating an Azure Container App&lt;/h2&gt;
&lt;p&gt;Creating an Azure Container App can be done in a variety of ways — Terraform or any other IaC code, Azure CLI, or through Portal. We are using Terraform internally, but for the sake of this post, I am showing creating using the portal.&lt;/p&gt;

&lt;p&gt;So, search for the service and select Container App.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-11-22-creating-keda-scalar-in-aca-using-azure-portal/portal-search-aca.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The first step is the provide the name and select a region and Container Apps environment. I have decided to use the existing environment below.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-11-22-creating-keda-scalar-in-aca-using-azure-portal/portal-create-aca.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;configuring the container app&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The next tab in the wizard is about the container. Our team-specific image is in our internal Azure Container Registry and the wizard fills the drop-downs for easy selection.&lt;/p&gt;

&lt;p&gt;The only change I have made here is, changing the CPU and Memory values as needed for the image — Notice I am using Consumption Plan as we know this team does not need high-performance agents.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;As conveyed previously, this feature of allocating individual CPU and Memory configurations has great benefits over AKS. For example, we have a separate container app with a &lt;a href=&quot;https://learn.microsoft.com/en-us/azure/container-apps/workload-profiles-overview#profile-types&quot;&gt;dedicated workload profile&lt;/a&gt; for running CPU and Memory-intensive jobs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-11-22-creating-keda-scalar-in-aca-using-azure-portal/portal-create-aca-container.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;specify the container&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The rest of the wizard is left at defaults as I do not have any bindings or Ingress to configure.&lt;/p&gt;

&lt;p&gt;This should get your container app running.&lt;/p&gt;

&lt;h2 id=&quot;create-a-secret-to-store-azure-devops-pat&quot;&gt;Create a secret to store Azure DevOps PAT&lt;/h2&gt;
&lt;p&gt;The first step in the container app is to Add a secret and store our Azure DevOps PAT (Personal Access Token). PAT is needed for the Azure DevOps build agent to connect to our Azure DevOps service. Later in the post, we use this PAT to let KEDA authenticate to our Azure DevOps service to monitor the Agent Pool for new jobs.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-11-22-creating-keda-scalar-in-aca-using-azure-portal/add-pat-as-secret.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Add PAT as a secret&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;create-a-new-revision&quot;&gt;Create a new revision&lt;/h2&gt;
&lt;p&gt;The next step is to edit the container and define the few environment variables that are required for the container (for more on these specific environment variables refer to this &lt;a href=&quot;https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/docker?view=azure-devops#environment-variables&quot;&gt;documentation&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Notice, for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AZP_TOKEN&lt;/code&gt; the source is set as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Reference a secret&lt;/code&gt; as I want value for that to come from the secret defined in the previous step.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-11-22-creating-keda-scalar-in-aca-using-azure-portal/edit-container-add-secret.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Edit container environment variables&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;create-a-custom-scale-rule&quot;&gt;Create a custom Scale rule&lt;/h2&gt;
&lt;p&gt;The next and final step is to define the custom scale rule — which in our case is KEDA.&lt;/p&gt;

&lt;p&gt;So in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scale&lt;/code&gt; tab, click &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+Add&lt;/code&gt; and then enter the details below&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rule name:&lt;/code&gt; This is the name for the custom scale rule, can be anything.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Type&lt;/code&gt;: Custom&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Custom rule type&lt;/code&gt;: This is defined with the Scaler definition. I am using Azure Pipelines scaler, so this should match &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;type&lt;/code&gt; field of the Scaler definition.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Next, we need to add a few metadata values so that KEDA knows which agent pool should it monitor for new jobs. These will come from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;metadata&lt;/code&gt; keys of the scaler definition.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;peronalAccessTokenFromEnv&lt;/code&gt;: This lets KEDA authenticate with our Azure DevOps service to monitor the Agent Pool. The value is PAT we defined in the secret previously — which has been passed to the container as an environment variable, so we use that environment variable.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;organizationURLFromEnv&lt;/code&gt;: This is our Azure DevOps organization URL, again we set this as an environment variable in the previous section.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;poolID&lt;/code&gt;: This is the Azure DevOps pool ID which KEDA should monitor. Refer to the &lt;a href=&quot;https://keda.sh/docs/2.13/scalers/azure-pipelines/#how-to-determine-your-pool-id&quot;&gt;scaler docs&lt;/a&gt; on how to get this.&lt;/li&gt;
&lt;/ol&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-11-22-creating-keda-scalar-in-aca-using-azure-portal/add-scale-rule.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Add metadata for the scaler&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;That is it for the post. Hope you found it useful.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this post, I showed how we added custom scaling with KEDA using the Azure Portal. Thanks to the KEDA scaler, we have a dynamic scaling pool, which automatically scales when there are more jobs in the queue and scales back down when demand reduces.&lt;/p&gt;
</description>
				<pubDate>Wed, 22 Nov 2023 00:00:00 +0000</pubDate>
				<link>https://www.visualstudiogeeks.com/devops/creating-keda-scalar-in-aca-using-azure-portal</link>
				<guid isPermaLink="true">https://www.visualstudiogeeks.com/devops/creating-keda-scalar-in-aca-using-azure-portal</guid>
			</item>
		
            
			<item>
				<title>Installing Docker without Docker Desktop on WSL2</title>
				
					<dc:creator>Utkarsh Shigihalli</dc:creator>
				    
				<description>&lt;p&gt;I have been using Docker on WSL2 without Docker Desktop for a while now and recently I had to rebuild my Ubuntu distro. I had to go through installing the Docker Engine once again following a series of steps, so thought I would document it so that I can use it again as a reference.&lt;/p&gt;

&lt;p&gt;This post is just that and I hope others will find it useful too.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;

&lt;p&gt;Before installing Docker in WSL2, first make sure you are running WSL2. You can do that using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wsl --version&lt;/code&gt; in your PowerShell which should output as below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-10-04-installing-docker-without-docker-desktop-on-wsl2/wsl-version.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can also check you are running the Ubuntu version using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lsb_release -a&lt;/code&gt; command which should output as below&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-10-04-installing-docker-without-docker-desktop-on-wsl2/ubuntu-version.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;installing-docker&quot;&gt;Installing Docker&lt;/h2&gt;
&lt;p&gt;Now that you confirmed you have the prerequisites, let’s start by installing Docker. Docker documentation provides a convenient script for us to run, which just involves running the script below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-10-04-installing-docker-without-docker-desktop-on-wsl2/docker-install.png&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;However, you might get the error &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Updates for this repository will not be applied&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-10-04-installing-docker-without-docker-desktop-on-wsl2/docker-install-error.png&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A quick StackOverflow search suggested that this is caused due to the clock being out-of-sync between the Windows machine and the Ubuntu distro running in WSL2. To sync the clock, I had to run sudo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hwclock --hctosys&lt;/code&gt; and restart the WSL using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wsl --&lt;/code&gt;shutdown` and start WSL again.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The second attempt to run the command should be successful.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-10-04-installing-docker-without-docker-desktop-on-wsl2/docker-install-success.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;creating-docker-group-and-adding-the-current-user&quot;&gt;Creating &lt;em&gt;docker&lt;/em&gt; group and adding the current user&lt;/h2&gt;
&lt;p&gt;Due to the way the Unix socket works, we need to preface &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker&lt;/code&gt; command with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo&lt;/code&gt;. To avoid it, Docker recommends creating a group name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker&lt;/code&gt; and adding the current user to it. Docker daemon can then create a Unix socket accessible by members of the docker group.
So, first, create &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker&lt;/code&gt; group using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo groupadd docker&lt;/code&gt; then add yourself to that group using the command&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;usermod &lt;span class=&quot;nt&quot;&gt;-aG&lt;/span&gt; docker &lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Finally, run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;newgrp docker&lt;/code&gt; to activate the changes to the group.&lt;/p&gt;

&lt;h2 id=&quot;test-running-docker&quot;&gt;Test running Docker&lt;/h2&gt;
&lt;p&gt;You can now test the docker commands without &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo&lt;/code&gt;. Try running docker run hello-world and it should run correctly.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-10-04-installing-docker-without-docker-desktop-on-wsl2/docker-hello-world.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;ensuring-docker-daemon-starts-when-you-open-wsl&quot;&gt;Ensuring Docker daemon starts when you open WSL&lt;/h2&gt;
&lt;p&gt;Finally, to ensure you have the docker daemon start when you open WSL, you can run the below commands which will start the docker service as soon as you boot.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2023-10-04-installing-docker-without-docker-desktop-on-wsl2/docker-service-start.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That is it, you should be able to run all your docker commands without Docker desktop now.&lt;/p&gt;
</description>
				<pubDate>Wed, 04 Oct 2023 00:00:00 +0100</pubDate>
				<link>https://www.visualstudiogeeks.com/productivity/installing-docker-without-docker-desktop-on-wsl2</link>
				<guid isPermaLink="true">https://www.visualstudiogeeks.com/productivity/installing-docker-without-docker-desktop-on-wsl2</guid>
			</item>
		
            
			<item>
				<title>Trigger a Netlify build every day using GitHub Actions</title>
				
					<dc:creator>Utkarsh Shigihalli</dc:creator>
				    
				<description>&lt;p&gt;I host this blog on Netlify. Often, I end up writing few blog posts on the same day, but not necessarily want all of them published together. Jekyll allows to add future date to the posts, and those posts will not get published until the date set. This lets me write blog posts on the same day, but publish them later based on the date set for the post.&lt;/p&gt;

&lt;p&gt;However, this means that when you build the site (locally or on Netlify), posts with future dates will be skipped from the generated site. You will need to run build again on the blog post date to publish the blog posts. One way is to schedule a build on Netlify so that blog posts with future date can be included in the site. Curious how to do this?&lt;/p&gt;

&lt;!-- more --&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2022/feb/trigger-netlify-build-everyday-using-github-actions/jekyll-skip.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Jekyll skipping posts with future date&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;create-netlify-build-hook&quot;&gt;Create Netlify build hook&lt;/h2&gt;

&lt;p&gt;Netlify supports &lt;a href=&quot;https://docs.netlify.com/configure-builds/build-hooks/&quot;&gt;build hooks&lt;/a&gt;, which lets you trigger new builds and deploys by making a request to a URL.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2022/feb/trigger-netlify-build-everyday-using-github-actions/configure-builds-build-hooks.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Configure build hooks&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Go to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Site Settings&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Build Hooks&lt;/code&gt; section and click &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Add Build Hook&lt;/code&gt; button.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2022/feb/trigger-netlify-build-everyday-using-github-actions/add-build-hook.jpg&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Add build hook&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Give a name and select a branch to trigger the build and click &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Save&lt;/code&gt;. You will see the URL which you can use to trigger the build.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2022/feb/trigger-netlify-build-everyday-using-github-actions/build-hook.jpg&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;URL of the build hook&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;create-github-actions-workflow&quot;&gt;Create GitHub Actions workflow&lt;/h2&gt;

&lt;p&gt;Go to GitHub repo and create a actions yaml file under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.github\workflows&lt;/code&gt; folder. GitHub Actions supports scheduled jobs, which lets you run a job at a specific time. See the below example. I am using cron expression to run the build every day at 04:00 AM UTC timezone.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;nightly-netlify-build&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;schedule&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;cron&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;*&quot;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class=&quot;na&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;trigger netlify build&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;curl -X POST -d '{}' https://api.netlify.com/build_hooks/2eae8d5c79506d0213a38be0e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note, if you hover over the cron expression, GitHub nicely displays the tooltip explaining the cron expression.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2022/feb/trigger-netlify-build-everyday-using-github-actions/github-tooltip.jpg&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;GitHub shows cron expression detail&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Save the file and push the changes. That is it, you have created a GitHub Actions workflow which can trigger nightly build of the blog.
Go to Netlify and see the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Deploys&lt;/code&gt; tab. You will see the deploys triggered by the build hook.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2022/feb/trigger-netlify-build-everyday-using-github-actions/verify-netlify.jpg&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Deploys triggered by the build hook&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Isn’t that cool? If you liked the post, do share it in your social channels. Thanks for reading.&lt;/p&gt;
</description>
				<pubDate>Sun, 20 Feb 2022 00:00:00 +0000</pubDate>
				<link>https://www.visualstudiogeeks.com/github/netlify/trigger-netlify-build-everyday-using-github</link>
				<guid isPermaLink="true">https://www.visualstudiogeeks.com/github/netlify/trigger-netlify-build-everyday-using-github</guid>
			</item>
		
            
			<item>
				<title>Policy enforced deployments for your Kubernetes resources</title>
				
					<dc:creator>Utkarsh Shigihalli</dc:creator>
				    
				<description>&lt;p&gt;As your team starts to deploy resources to Kubernetes regularly, it becomes necessary for you as a cluster administrator to maintain  good standards and consistency of the Kubernetes resources. Be it, ensuring all the resources have set of labels, or ensuring you only pull images from your enterprise container registry. &lt;a href=&quot;https://github.com/open-policy-agent/gatekeeper&quot;&gt;Gatekeeper&lt;/a&gt; is a well known policy enforcement tool using &lt;a href=&quot;https://www.openpolicyagent.org&quot;&gt;Open Policy Agent (OPA)&lt;/a&gt; - which is a opensource, Cloud Native Computing Foundation (CNCF) project.&lt;/p&gt;

&lt;p&gt;But did you know you can validate policies on your Kubernetes manifests before you deploy them on to the cluster? In this post, we will see how we can govern our deployments using Conftest and OPA policy agent.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;However, Gatekeeper is installed on the cluster and thus ensures no policy is broken at deployment time. This means that any validation of policies happen only when you are trying to deploy resources to cluster. While this ensures that no resource violates the policy, you would like to know about these policies much earlier in your CI/CD pipeline. Doing policy validations much to the left of your deployment pipeline ensures your deployment going smooth when necessary.&lt;/p&gt;

&lt;p&gt;This is where &lt;a href=&quot;https://www.conftest.dev&quot;&gt;Conftest&lt;/a&gt; helps. Conftest relies on OPA and policies are written using &lt;a href=&quot;https://www.openpolicyagent.org/docs/latest/#rego&quot;&gt;Rego&lt;/a&gt;  - thus the policies you write for Gatekeeper will be compatible with Conftest. But more importantly &lt;strong&gt;with Conftest, you can validate your local manifests against OPA policies locally and ensure your resources are compliant before you deploy them&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;

&lt;p&gt;Installation is really easy if you are on Mac - For other platforms refer to the &lt;a href=&quot;https://www.conftest.dev/install/&quot;&gt;documentation&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-brew&quot;&gt;brew install conftest
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;folder-structure&quot;&gt;Folder structure&lt;/h2&gt;

&lt;p&gt;By default, Conftest expects you to maintain your policies under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;policy&lt;/code&gt; folder at the same location as your Kubernetes resources. If you prefer a different path, you will want to pass it using CLI or set environment variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CONFTEST_POLICY&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;📂 src
    📂 k8s
        📄 deployment.yml
        📄 service.yml
        📁 policy
            📄 replica.rego
            📄 labels.rego
    📂 app
        📄 main.ts
        📄 package.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;writing-policies&quot;&gt;Writing Policies&lt;/h2&gt;

&lt;p&gt;As mentioned previously, policies are written in &lt;a href=&quot;https://www.openpolicyagent.org/docs/latest/#rego&quot;&gt;Rego&lt;/a&gt;. I struggled to write policies initially and constantly went back to documentation. However, once you write couple of policies, you will get a hang of it. Take a look at the simple policy to &lt;em&gt;check every deployment has at least 2 replicas&lt;/em&gt;.&lt;/p&gt;

&lt;div class=&quot;language-rego highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;ow&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;deny_replicas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kind&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Deployment&quot;&lt;/span&gt;                          &lt;span class=&quot;c1&quot;&gt;# check if it is a Deployment&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replicas&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;                             &lt;span class=&quot;c1&quot;&gt;# And the replicas are &amp;lt; 2&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Deployments must have 2 or more replicas&quot;&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# show the error message and fail the test&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;input&lt;/code&gt; is the complete yaml document from our deployment yaml (see below) and we we are checking if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kind&lt;/code&gt; is equal to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Deployment&lt;/code&gt;. If its deployment, we move to next line in the constraint and check if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec.replicas&lt;/code&gt; is less that 2.&lt;/p&gt;

&lt;div class=&quot;language-yml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;apps/v1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Deployment&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mynodeapi-dep&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;dep-k8s-nodejs-api&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can write other policies similar to the one above to validate various aspects of Kubernetes resources. Let us see few examples.&lt;/p&gt;
&lt;h4 id=&quot;validate-resources-have-recommended-labels&quot;&gt;Validate resources have recommended labels&lt;/h4&gt;

&lt;p&gt;This policy validates our resources have the required labels and fail if any labels from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;required_deployment_labels&lt;/code&gt; object are not found.&lt;/p&gt;

&lt;div class=&quot;language-rego highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;ow&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;

&lt;span class=&quot;ow&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kubernetes&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;required_deployment_labels&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;app.kubernetes.io/name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;app.kubernetes.io/instance&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;app.kubernetes.io/version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;app.kubernetes.io/component&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;app.kubernetes.io/part-of&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;app.kubernetes.io/managed-by&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;violation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kind&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Deployment&quot;&lt;/span&gt;
	&lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;required_deployment_labels&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Must include Kubernetes recommended labels: https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/#labels&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;reference-container-images-only-from-our-enterprise-azure-container-registry&quot;&gt;Reference container images only from our enterprise Azure Container Registry&lt;/h4&gt;

&lt;div class=&quot;language-rego highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;ow&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;deny&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kind&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Deployment&quot;&lt;/span&gt;
    &lt;span class=&quot;ow&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;
    &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;myacr.azurecr.io&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# validate images start with endpoint for our container registry&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;image '%v' comes from untrusted registry&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

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

&lt;p&gt;As you can see rules can be very powerful.&lt;/p&gt;

&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;/h2&gt;

&lt;p&gt;The command to test resources using Conftest is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conftest test &amp;lt;PATH&amp;gt;&lt;/code&gt;. Since I would like to test all resources under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;k8s&lt;/code&gt; folder, I pass folder path as below.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;conftest &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt; ./k8s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Running this you will see the output as below (ignore other errors as I have other policies). The test failed because we have set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deny&lt;/code&gt; rule if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spect.replicas &amp;lt; 2&lt;/code&gt; and in our case our deployment yaml has &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;replicas: 1&lt;/code&gt; (see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec&lt;/code&gt; section in the deployment yaml above).&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2022/feb/policy-enabled-deployments-for-k8s/conftest-error.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Conftest failing due to policy violation&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;using-conftest-in-github-actions&quot;&gt;Using Conftest in GitHub Actions&lt;/h2&gt;

&lt;p&gt;Making Conftest work in your Continuous Integration (CI) process is simple. For demo purposes, I am using GitHub Actions in my repo &lt;a href=&quot;https://github.com/onlyutkarsh/k8s-nodejs-api&quot;&gt;here&lt;/a&gt;. If you run the tests, you will see the action fails with errors - &lt;a href=&quot;https://github.com/onlyutkarsh/k8s-nodejs-api/runs/5173696729?check_suite_focus=true#step:4:6&quot;&gt;see the output&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My action workflow looks like below.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;build&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;pull_request&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;workflow_dispatch&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class=&quot;na&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;actions/checkout@v2&lt;/span&gt;

      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;install conftest&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;wget https://github.com/open-policy-agent/conftest/releases/download/v0.30.0/conftest_0.30.0_Linux_x86_64.tar.gz&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;tar xzf conftest_0.30.0_Linux_x86_64.tar.gz&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;sudo mv conftest /usr/local/bin&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;rm -rf conftest_0.30.0_Linux_x86_64.tar.gz&lt;/span&gt;

      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;run conftest&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;conftest test $/k8s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;As you can see, Conftest lets you validate and govern your Kubernetes resources efficiently and can easily be integrated with your CI workflows. This lets your team standardise the common practices, go through PR review process before eventually deploying to the cluster. Once deployed to cluster, you can use Gatekeeper to validate as well to full proof your workloads.&lt;/p&gt;
</description>
				<pubDate>Sun, 13 Feb 2022 00:00:00 +0000</pubDate>
				<link>https://www.visualstudiogeeks.com/azure/kubernetes/devops/policy-enforcement-for-k8s</link>
				<guid isPermaLink="true">https://www.visualstudiogeeks.com/azure/kubernetes/devops/policy-enforcement-for-k8s</guid>
			</item>
		
            
			<item>
				<title>Keep your workflow actions up to date using GitHub Dependabot</title>
				
					<dc:creator>Utkarsh Shigihalli</dc:creator>
				    
				<description>&lt;p&gt;GitHub Actions is great in automating your workflows. However, as you start using various actions from GitHub Marketplace in your workflow, it will soon become necessary for you to keep the actions up-to-date. Actions might contain security fixes, bug fixes etc and manually keeping track of updates or updating them when a newer version is available is a lot of hassle. This is where we can use Depndabot, which can help by automatically raising PR’s whenever there is a newer version of action is available used in the workflow. In this post, we will see quick way to keep the actions up-to-date using GitHub Dependabot.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;blockquote&gt;
  &lt;p&gt;For this post, I am using my &lt;a href=&quot;https://github.com/onlyutkarsh/git-config-user-profiles&quot;&gt;Git Config User Profiles&lt;/a&gt; repository. I have workflow setup which builds and releases the VS Code extension to VS Marketplace.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;create-dependabotyml-file&quot;&gt;Create dependabot.yml file&lt;/h2&gt;

&lt;p&gt;To setup Dependabot scan, first got to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.github&lt;/code&gt; folder in your root and create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;depndabot.yml&lt;/code&gt; file. Then add the following content. This will ensure GitHub Dependabot raise a PR whenever there is a newer version of action is available&lt;/p&gt;

&lt;div class=&quot;language-yml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;updates&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;package-ecosystem&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;github-actions&quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# search for actions - there are other options available&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;directory&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/&quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# search in .github/workflows under root `/`&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;schedule&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;weekly&quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# check for action update every week&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;commit-the-file&quot;&gt;Commit the file&lt;/h2&gt;

&lt;p&gt;Commit the file created above and wait for few seconds. Based on your workflow, you will see a bunch of PR’s raised.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2022/jan/dependabot-to-update-actions/dependabot-alerts.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Dependabot Alerts as PR&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;If you look at the PR, you will be able to see the change and take a decision whether you want to upgrade the specific action or not. If you decide to accept the change, merge the PR and the changes on the workflow file will be made.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2022/jan/dependabot-to-update-actions/commit-detail.png&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Commit Details&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Isn’t it cool? This saves a lot of time, if you have a number of workflows and don’t want to keep checking the latest versions of actions. BTW, not only GitHub actions, you can use the same approach to update &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;npm&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker&lt;/code&gt; and many more using various &lt;a href=&quot;https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/about-dependabot-version-updates#supported-repositories-and-ecosystems&quot;&gt;package ecosystems&lt;/a&gt;. Do check it out!&lt;/p&gt;
</description>
				<pubDate>Fri, 28 Jan 2022 00:00:00 +0000</pubDate>
				<link>https://www.visualstudiogeeks.com/github/ensure-your-actions-are-up-to-date</link>
				<guid isPermaLink="true">https://www.visualstudiogeeks.com/github/ensure-your-actions-are-up-to-date</guid>
			</item>
		
            
			<item>
				<title>Setting up Azure Cosmos DB Emulator on Synology NAS</title>
				
					<dc:creator>Utkarsh Shigihalli</dc:creator>
				    
				<description>&lt;p&gt;Cosmos DB Emulator is great for developing against Azure Cosmos DB in your local environment. If you want to run the emulator on Mac/Linux though, the emulator is now in preview mode at the time of writing this and uses Docker to make it available.&lt;/p&gt;

&lt;p&gt;Recently I wanted to setup Cosmos DB Emulator on Mac, but I did not want to set it up such that I keep it running always on my Mac. Instead, I decided to use my Synology NAS to host the emulator directly on my NAS as it is built on Linux and also because it allows the emulator running and available for me all the time.&lt;/p&gt;

&lt;p&gt;In this post we will see how to set it up on Synology NAS.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;The goal is to run Cosmos DB emulator as a Docker container on Synology.&lt;/p&gt;

&lt;h2 id=&quot;enabling-ssh-on-synology&quot;&gt;Enabling SSH on Synology&lt;/h2&gt;

&lt;p&gt;Since Cosmos DB Emulator image is hosted on Microsoft Registry (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mcr.microsoft.com&lt;/code&gt;) which does not provide UI/discovery service, Synology’s Docker app, cannot pull images from Microsoft Registry. For this purpose we need to enable SSH on Synology so that we can SSH to Synology and run docker commands directly.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/jul/setting-up-cosmos-emulator-on-synology/ssh-on-synology.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you have firewall enabled on Synology, you must also &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Allow&lt;/code&gt; port &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;22&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/jul/setting-up-cosmos-emulator-on-synology/firewall-synology.jpg&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;pulling-the-docker-image&quot;&gt;Pulling the docker image&lt;/h2&gt;

&lt;p&gt;After enabling SSH on SYnology, you can SSH on to Synology and run the below command to pull the Docker image of Cosmos Emulator.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;docker pull mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You should see Cosmos DB Emulator image available in Syonology’s Docker app.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/jul/setting-up-cosmos-emulator-on-synology/image-downloaded.jpg&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;starting-the-container&quot;&gt;Starting the Container&lt;/h2&gt;

&lt;p&gt;You can now create a container using the docker image you just pulled. Before we start, as per the Microsoft documentation for the Emulator, we need to ensure we have setup few environment variables for the container. They are&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE = &amp;lt;&amp;lt;SYNOLOGY_IP_ADDRESS&amp;gt;&amp;gt;
AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE = true
AZURE_COSMOS_EMULATOR_PARTITION_COUNT = 10
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/jul/setting-up-cosmos-emulator-on-synology/env-variables.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Finally, you will need to ensure you have mapped these ports for the container. &lt;strong&gt;Ensure you have opened these below ports on the Synology’s Firewall as well&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/jul/setting-up-cosmos-emulator-on-synology/container-ports.jpg&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;For more information on creating container from docker image, see Synology’s &lt;a href=&quot;https://kb.synology.com/en-us/DSM/help/Docker/docker_container?version=7&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;install-the-certificate-on-your-machine&quot;&gt;Install the certificate on your machine&lt;/h2&gt;

&lt;p&gt;To avoid errors due to certificate, you need to download the self-signed certificate for the emulator and install it on your machine. To download the certificate for the emulator run below command&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-k&lt;/span&gt; https://&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SYNOLOGY_IP_ADDRESS&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&amp;gt;&amp;gt;:8081/_explorer/emulator.pem &amp;gt; emulatorcert.crt
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On my Mac, I had to &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/cosmos-db/linux-emulator?tabs=ssl-netstd21#consume-endpoint-ui?WT.mc_id=DT-MVP-5003386&quot;&gt;install it on Keychain Access App&lt;/a&gt; and set it as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Always Trust&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once done you should be able to browse the Cosmos Emulator UI using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://&amp;lt;&amp;lt;SYNOLOGY_IP_ADDRESS&amp;gt;&amp;gt;:8081/_explorer/index.html &lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/jul/setting-up-cosmos-emulator-on-synology/cosmos-ui.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That is it! Your Cosmos Emulator is now available to use all the time.&lt;/p&gt;

&lt;h2 id=&quot;reference&quot;&gt;Reference&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/cosmos-db/linux-emulator?tabs=ssl-netstd21?WT.mc_id=DT-MVP-5003386&quot;&gt;Microsoft documentation on Cosmos DB Emulator on Linux&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.wundertech.net/how-to-install-portainer-on-a-synology-nas/&quot;&gt;Enabling SSH on Synology&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
				<pubDate>Tue, 27 Jul 2021 00:00:00 +0100</pubDate>
				<link>https://www.visualstudiogeeks.com/azure/cosmos/setting-up-cosmos-db-emulator-on-synology</link>
				<guid isPermaLink="true">https://www.visualstudiogeeks.com/azure/cosmos/setting-up-cosmos-db-emulator-on-synology</guid>
			</item>
		
            
			<item>
				<title>How to publish Helm 3 charts to GitHub Container Registry using GitHub Actions</title>
				
					<dc:creator>Utkarsh Shigihalli</dc:creator>
				    
				<description>&lt;p&gt;I have already written how to publish Helm chart to ACR using &lt;a href=&quot;/devops/helm/deploying-helm-chart-with-azdo&quot;&gt;Azure DevOps&lt;/a&gt; and &lt;a href=&quot;/helm/devops/publish-helm-charts-to-acr-using-github-actions&quot;&gt;GitHub actions&lt;/a&gt;. But did you know that you can also publish Helm3 charts (or any OCI compliant package) to &lt;a href=&quot;https://github.blog/2020-09-01-introducing-github-container-registry/&quot;&gt;GitHub Container Registry(GCR)&lt;/a&gt;? In this post we will see how to do that. 
&lt;!-- more --&gt;&lt;/p&gt;

&lt;h2 id=&quot;enable-improved-container-support&quot;&gt;Enable improved container support&lt;/h2&gt;

&lt;p&gt;GitHub Container Registry is currently in public beta. So, the first step is to ensure that you have enabled the GitHub Container Registry for your account. If you have GitHub personal account, you can do that from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Feature Preview&lt;/code&gt; window.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/apr/publish-helm-3-charts-to-gcr/improved-container-support.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you have a Enterprise account, you can do that going to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Settings&lt;/code&gt; page.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/apr/publish-helm-3-charts-to-gcr/improved-container-support-ent.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;GitHub documentation has step-by-step guide of enabling &lt;strong&gt;improved container support&lt;/strong&gt; &lt;a href=&quot;https://docs.github.com/en/packages/guides/enabling-improved-container-support&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;publishing-helm-3-charts-using-github-actions&quot;&gt;Publishing Helm 3 charts using GitHub Actions&lt;/h2&gt;

&lt;p&gt;It really takes only couple of steps to publish a Helm chart to GCR using GitHub Actions. Like any other action, you start by creating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.github\workflow&lt;/code&gt; folder and create an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yml&lt;/code&gt; file in your repository.&lt;/p&gt;

&lt;p&gt;Excluding the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt; and trigger part, first step in the YAML is to define few necessary variables.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;HELM_EXPERIMENTAL_OCI&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#enable OCI support&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;HELM_VERSION_TO_INSTALL&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;3.5.0&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# version of HEL to install&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;GCR_IMAGE&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ghcr.io/${{ github.repository_owner }}/vote-app&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;First variable &lt;a href=&quot;https://helm.sh/docs/topics/registries/#enabling-oci-support&quot;&gt;enables the OCI support&lt;/a&gt; for the Helm commands we are going to run later in the YAML.&lt;/p&gt;

&lt;p&gt;Next variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HELM_VERSION_TO_INSTALL&lt;/code&gt; is used later in the workflow to install specific version of the Helm. For this workflow, we need &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3.5.0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Last variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GCR_IMAGE&lt;/code&gt; is constructing the chart name for the publication.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The GitHub Container Registry hosts containers at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ghcr.io/OWNER/IMAGE-NAME&lt;/code&gt;. I get the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OWNER&lt;/code&gt; of the repository using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;github.repository_owner&lt;/code&gt; from &lt;a href=&quot;https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;github&lt;/code&gt; context&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next steps are defining the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;job&lt;/code&gt; with steps to download the code (where we have Helm chart) and install the specific Helm tool on the runner/agent.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;publish gcr&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;prod&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;actions/checkout@v2&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;checkout repo&lt;/span&gt;
      
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;install helm&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Azure/setup-helm@v1&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;# Version of helm&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${{ env.HELM_VERSION_TO_INSTALL }}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# default is latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The above steps setup the agent machine with the required Helm tool.&lt;/p&gt;

&lt;p&gt;Next, we need to run few &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;helm&lt;/code&gt; commands to login to GCR (GitHub Container Registry) and finally publish the chart.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;We login to GCR using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${{ secrets.GITHUB_TOKEN }}&lt;/code&gt;&lt;/p&gt;

    &lt;blockquote&gt;
      &lt;p&gt;GitHub Container Registry only &lt;a href=&quot;https://github.blog/changelog/2021-03-24-packages-container-registry-now-supports-github_token/&quot;&gt;recently&lt;/a&gt; started supporting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GITHUB_TOKEN&lt;/code&gt;. Previously you had to create a separate PAT token with specific permissions to GCR.&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Next two steps in the workflow will be to save the chart and publish. We do that using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;helm chart save&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;help chart push&lt;/code&gt; commands as shown below.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;login to acr using helm&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;echo ${{ secrets.GITHUB_TOKEN }} | helm registry login ${{ env.GCR_IMAGE }} --username ${{ github.repository_owner }} --password-stdin&lt;/span&gt;

&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;save helm chart to local registry&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;helm chart save ${{ github.workspace }}/src/azure-vote-helm-chart/ ${{ env.GCR_IMAGE }}:${{ github.sha }}&lt;/span&gt;

&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;publish chart to acr&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;helm chart push ${{ env.GCR_IMAGE }}:${{ github.sha }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;That is it, if all worked successfully for you, you should see the chart in the GCR.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/apr/publish-helm-3-charts-to-gcr/published-chart.jpg&quot; /&gt;&lt;/p&gt;
</description>
				<pubDate>Sat, 10 Apr 2021 00:00:00 +0100</pubDate>
				<link>https://www.visualstudiogeeks.com/github/publish-helm-3-charts-to-gcr</link>
				<guid isPermaLink="true">https://www.visualstudiogeeks.com/github/publish-helm-3-charts-to-gcr</guid>
			</item>
		
            
			<item>
				<title>Publish Helm 3 charts to Azure Container Registry (ACR) using GitHub Actions</title>
				
					<dc:creator>Utkarsh Shigihalli</dc:creator>
				    
				<description>&lt;p&gt;In my &lt;a href=&quot;/devops/helm/deploying-helm-chart-with-azdo&quot;&gt;previous&lt;/a&gt; post, we briefly covered how to publish a Helm chart to ACR using Azure DevOps. In this post we will use GitHub actions to build and publish Helm chart to ACR using GitHub Actions. We will also take a sneak peak how GitHub environments work.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/apr/publish-helm-acr-github-actions/github-helm-acr.jpg&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;pre-requisites&quot;&gt;Pre-requisites&lt;/h2&gt;

&lt;p&gt;I am going to assume ACR instance is setup using repository scoped tokens. Since we already covered setting up of ACR this way in the &lt;a href=&quot;https://www.visualstudiogeeks.com/devops/helm/deploying-helm-chart-with-azdo#setting-up-the-acr-to-use-repository-scoped-tokens&quot;&gt;earlier post&lt;/a&gt;, I will not include the steps here.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-secrets-at-github&quot;&gt;Setting up secrets at GitHub&lt;/h2&gt;

&lt;p&gt;We would like store Azure Container Registry’s tokens as GitHub repository level secrets. To do that, click on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Settings&lt;/code&gt; on the repository page and head to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Secrets&lt;/code&gt; tab. Finally click on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;New repository secret&lt;/code&gt; and add the token name and the password. I have stored token name as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ACR_PUSH_USER&lt;/code&gt; and token password as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ACR_PUSH_TOKEN&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/apr/publish-helm-acr-github-actions/add-secret.jpg&quot; /&gt;
&lt;figcaption class=&quot;figure-caption&quot;&gt;Add repository secrets&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;creating-the-workflow-in-github-actions&quot;&gt;Creating the workflow in GitHub Actions&lt;/h2&gt;

&lt;h3 id=&quot;publish-chart-to-acr&quot;&gt;Publish chart to ACR&lt;/h3&gt;

&lt;p&gt;The first step is to create an yaml file under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.github\workflows&lt;/code&gt; folder and setup a basic structure. The first things (see the yaml below) are defining name for the action, currently set to trigger via manual trigger using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;workflow_dispatch&lt;/code&gt; and define few environment variables which we are going to use later in the action.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ci&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; 
  &lt;span class=&quot;na&quot;&gt;workflow_dispatch&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;HELM_EXPERIMENTAL_OCI&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;HELM_VERSION_TO_INSTALL&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;3.5.0&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;ACR_NAME&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;acrdemoutkarsh&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;ACR_REPO_NAME&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;helmdemo/vote-app&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The first environment variable conveys to ACR that we are going to publish a &lt;a href=&quot;https://helm.sh/docs/topics/registries/&quot;&gt;OCI package&lt;/a&gt;. Next couple of variables just define version of Helm we need on the runner, our ACR name to which we are going to publish this chart and finally to the repository we are publishing this chart to (used in below sections).&lt;/p&gt;

&lt;h3 id=&quot;installing-helm-3-on-the-agent&quot;&gt;Installing Helm 3 on the agent&lt;/h3&gt;

&lt;p&gt;Now that we have all the variables defined, we need add jobs and steps to build our workflow to publish charts to ACR. We then need to install Helm tool on the agent before we can run the Helm commands. We do that using yaml below.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;publish acr&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;prod&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;actions/checkout@v2&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;checkout repo&lt;/span&gt;
      
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;install helm&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Azure/setup-helm@v1&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${{ env.HELM_VERSION_TO_INSTALL }}# default is latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;As you can see, we have one job named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build&lt;/code&gt; (which will be displayed as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;publish acr&lt;/code&gt; - see screenshot below) which runs on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ubuntu-latest&lt;/code&gt; agent. We also are targeting our deployment to an environment &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prod&lt;/code&gt;. &lt;a href=&quot;https://docs.github.com/en/actions/reference/environments&quot;&gt;Environments&lt;/a&gt; in GitHub are cool because you can have approvers, additional protection rules for environments and environment specific secrets. In the screenshot below, notice how the flow is waiting for review.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/apr/publish-helm-acr-github-actions/environment-approvers.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Next, we checkout the repository and using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setup-helm&lt;/code&gt; task from Azure repo we install the specific version (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3.5.0&lt;/code&gt;) of Helm.&lt;/p&gt;

&lt;h3 id=&quot;login-to-the-acr-using-helm&quot;&gt;Login to the ACR using Helm&lt;/h3&gt;

&lt;p&gt;Next, we need to login to ACR registry using Helm tool.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;login to acr using helm&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;echo $ | helm registry login $.azurecr.io --username $ --password-stdin &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;save-and-push-the-chart-to-acr&quot;&gt;Save and push the chart to ACR&lt;/h3&gt;

&lt;p&gt;Next we need to save the chart directory to local cache and publish it to ACR.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;save helm chart to local registry&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;helm chart save $/src/azure-vote-helm-chart/ $.azurecr.io/$:latest&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;  &lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;publish chart to acr&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;helm chart push $.azurecr.io/$:latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Run the workflow, and you will see output as below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/apr/publish-helm-acr-github-actions/run.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Go to ACR and you will see char correctly published to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;helmdemo/vote-app&lt;/code&gt; repository as declared in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;env&lt;/code&gt; section above.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.visualstudiogeeks.com/images/screenshots/utkarsh/2021/apr/publish-helm-acr-github-actions/acr.jpg&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In this post, you saw how easily we can deploy a OCI package (helm3 chart) to ACR using GitHub actions. We also saw how GitHub environments help you approve changes to the environment. Hope you enjoyed reading this post.&lt;/p&gt;

</description>
				<pubDate>Thu, 01 Apr 2021 01:00:00 +0100</pubDate>
				<link>https://www.visualstudiogeeks.com/helm/devops/publish-helm-charts-to-acr-using-github-actions</link>
				<guid isPermaLink="true">https://www.visualstudiogeeks.com/helm/devops/publish-helm-charts-to-acr-using-github-actions</guid>
			</item>
		
	</channel>
</rss>