<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Alex Kucksdorf</title>
    <description>The latest articles on Forem by Alex Kucksdorf (@alexkuck).</description>
    <link>https://forem.com/alexkuck</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F138885%2F5256b443-a704-4e9a-91b1-c51f3f914544.jpg</url>
      <title>Forem: Alex Kucksdorf</title>
      <link>https://forem.com/alexkuck</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/alexkuck"/>
    <language>en</language>
    <item>
      <title>Managing CircleCI secrets via Terraform</title>
      <dc:creator>Alex Kucksdorf</dc:creator>
      <pubDate>Fri, 06 Jan 2023 22:37:57 +0000</pubDate>
      <link>https://forem.com/alexkuck/managing-circleci-secrets-via-terraform-3ijc</link>
      <guid>https://forem.com/alexkuck/managing-circleci-secrets-via-terraform-3ijc</guid>
      <description>&lt;p&gt;&lt;em&gt;If you are just interested in the examples, jump straight ahead or have a look at the &lt;a href="https://github.com/alex-kuck/circleci-env-via-terraform" rel="noopener noreferrer"&gt;example code&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It sucks, if your CI provider has a security breach. What sucks even more is, if you are the lucky one in charge who has to go, rotate all possibly compromised secrets and update those in your build pipeline environment variables 🤦‍♂️.&lt;/p&gt;

&lt;p&gt;Sadly, this is not some dystopian fantasy, but was just &lt;a href="https://circleci.com/blog/january-4-2023-security-alert/" rel="noopener noreferrer"&gt;announced this week (2023-01-04)&lt;/a&gt; by CircleCI. This is no news you want to receive on your first day back to work after the holidays - lucky me 🤪. But, to be fair, I guess you don't want those news on any other day either 🤷‍♂️...&lt;/p&gt;

&lt;p&gt;Jokes aside, when one of your clients - and their 10s or more repositories - is affected by this, it can get hairy pretty quickly. Worst case, you have to click your way through the UI and collect all secrets stored in &lt;a href="https://circleci.com/docs/contexts/" rel="noopener noreferrer"&gt;contexts&lt;/a&gt; or, even better, in &lt;a href="https://circleci.com/docs/set-environment-variable/#set-an-environment-variable-in-a-project" rel="noopener noreferrer"&gt;project/repository-specific&lt;/a&gt; settings. In the meantime, CircleCI has published a repository to help those unlucky ones: &lt;a href="https://github.com/CircleCI-Public/CircleCI-Env-Inspector" rel="noopener noreferrer"&gt;CircleCI-Public/CircleCI-Env-Inspector&lt;/a&gt;. Using this, you can get at least a high-level overview of all used secrets in your organization, e.g. name, location and anonymized value.&lt;/p&gt;

&lt;p&gt;The best case on the other hand would be, if you could just rotate most - if not all - of your secrets with the click of a button and be done with it. Lucky for us, this is indeed achievable via Terraform and this neat plugin: &lt;a href="https://registry.terraform.io/providers/mrolla/circleci/latest/docs" rel="noopener noreferrer"&gt;mrolla/circleci&lt;/a&gt;. Chances are, a good chunk of your secrets are already managed alongside your infrastructure via Terraform. Using the plugin, you can update your secrets in CircleCI automatically whenever they are changed in Terraform. (Although this is not achievable for all secrets and passwords, many resources support this directly via Terraform, e.g. &lt;a href="https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/service_principal_password#rotate_when_changed" rel="noopener noreferrer"&gt;Azure Service Principal Passwords&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Set CircleCI Secrets via Terraform
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Configure the plugin&lt;/span&gt;
&lt;span class="k"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;circleci&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"mrolla/circleci"&lt;/span&gt; &lt;span class="c1"&gt;# c.f. https://registry.terraform.io/providers/mrolla/circleci/latest/docs&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;=0.6.1"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;# possibly some more&lt;/span&gt;

  &lt;span class="nx"&gt;required_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 1.2.5, &amp;lt; 3.0.0"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"circleci"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;vcs_type&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"github"&lt;/span&gt;
  &lt;span class="nx"&gt;organization&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-org"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Create a CircleCI Context&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"circleci_context"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-terraform-variables"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# Populate context with ENV variables&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"circleci_context_environment_variable"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;FOO&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;some-value-from-resource-foo&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;# e.g. secret from Key Vault&lt;/span&gt;
    &lt;span class="nx"&gt;BAR&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;some-value-from-resource-bar&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;variable&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
  &lt;span class="nx"&gt;context_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;circleci_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# OR set project-specific ENV variable instead&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"circleci_environment_variable"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;FOO&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;some-value-from-resource-foo&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;BAR&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;some-value-from-resource-bar&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;name&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
  &lt;span class="nx"&gt;project&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-repo"&lt;/span&gt;
  &lt;span class="nx"&gt;organization&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-org"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hopefully 🤞, you are &lt;strong&gt;not&lt;/strong&gt; affected by those news and are just reading this out of curiosity (thanks!). If not, maybe this plugin can save you some sweat and tears - at least in the future! 🍀&lt;/p&gt;

&lt;p&gt;You can find a more detailed example &lt;a href="https://github.com/alex-kuck/circleci-env-via-terraform" rel="noopener noreferrer"&gt;here on GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>development</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Living with Multiple Git-Personalities without Going Crazy</title>
      <dc:creator>Alex Kucksdorf</dc:creator>
      <pubDate>Sun, 06 Oct 2019 19:48:59 +0000</pubDate>
      <link>https://forem.com/alexkuck/living-with-multiple-git-personalities-without-going-crazy-3kbi</link>
      <guid>https://forem.com/alexkuck/living-with-multiple-git-personalities-without-going-crazy-3kbi</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Change your &lt;code&gt;git&lt;/code&gt; config based on the location where you clone your repository - jump there
&lt;/li&gt;
&lt;li&gt;Easily switch between different &lt;code&gt;git&lt;/code&gt; accounts via &lt;code&gt;SSH&lt;/code&gt;-key during clone - jump there
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;So... You know you have a problem. &lt;br&gt;
You have known for quite some time. &lt;br&gt;
Up until now you haven't been able to put your finger on it, but something was always bothering you. You have known there had to be others out there, facing the same issues. Although some of them must have come up with a solution by now, you didn't stumble across it yet. &lt;/p&gt;

&lt;p&gt;But fear no more. Your search is over. You have finally come to the right place.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Forgive my exaggeration, but I hope you get my point. This is a feeling every one of us developers has once in a while. We continue to learn throughout our careers and often are fortunate enough to work together with other awesome developers from whose experiences we should always try to learn. This is why decided to start sharing those lessons and tricks as I come to learn them.&lt;/p&gt;

&lt;p&gt;I dare say everybody of us found themselves banging their head against a wall in the past, struggling with some kind of issue or annoyance that turned out to be easily solvable - once you have the right trick up your sleeve.&lt;/p&gt;

&lt;p&gt;One of those annoyances for me was handling &lt;code&gt;git&lt;/code&gt; in different contexts. I use it for private projects as well as for work related projects. Additionally, since I work at a consulting company, I also work for varying clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conditional Git Config
&lt;/h2&gt;

&lt;p&gt;Although this is no must, I prefer slightly different appearances in all these contexts. I want my private projects to be associated with my private email address and work projects with my company address respectively. Some of the clients also provide their external developers with dedicated email addresses that I prefer to use in those cases.&lt;/p&gt;

&lt;p&gt;Additionally, I find my name relatively long to type and just go with Alex. However, in a professional context I prefer to use my full name.&lt;/p&gt;

&lt;p&gt;I know those settings can be adjusted for every repository I work on, but I prefer this to be automated. You might call it lazy, but I try to avoid it since I tend to forget doing it in time and get thrown out of my flow down the road. &lt;/p&gt;

&lt;p&gt;This is where the &lt;code&gt;.gitconfig&lt;/code&gt; comes into play. By default, &lt;code&gt;git&lt;/code&gt; will store your global settings in this file within your home directory. My default private config looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ~/.gitconfig
[user]
    name = Alex Kucksdorf
    email = &amp;lt;my_private_mail&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The real game changer there for me was learning about &lt;a href="https://git-scm.com/docs/git-config#_conditional_includes"&gt;conditional includes&lt;/a&gt;. This enables me to do something like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ~/.gitconfig
[user]
    name = Alex Kucksdorf
    email = &amp;lt;my_private_mail&amp;gt;

[includeIf "gitdir:~/dev/work/"]
    path = .gitconfig-work
[includeIf "gitdir:~/dev/work/&amp;lt;client&amp;gt;/"]
    path = .gitconfig-&amp;lt;client&amp;gt;
...
# ~/.gitconfig-work
[user]
    name = Alexander Kucksdorf
    email = &amp;lt;my_work_mail&amp;gt;
...
# ~/.gitconfig-&amp;lt;client&amp;gt;
[user]
    name = Alexander Kucksdorf@it-economics
    email = &amp;lt;my_&amp;lt;client&amp;gt;_mail&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way I only need to think about the folder where I clone the &lt;code&gt;repository&lt;/code&gt; and my &lt;code&gt;git&lt;/code&gt; config is automatically good to go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manage Accounts via SSH
&lt;/h2&gt;

&lt;p&gt;Resulting from this, I have already been in the situation where I had multiple &lt;code&gt;Github&lt;/code&gt; accounts because of client requests. Due to the requirement of using 2FA as well, I very much prefer to use &lt;code&gt;SSH&lt;/code&gt; instead of &lt;code&gt;username/password&lt;/code&gt; authentication. However, this means that I have to use different private keys, depending on which account I want the commit to be published with. An easy solution is to define a configuration at &lt;code&gt;~/.ssh/config&lt;/code&gt; like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ~/.ssh/config
Host github.com-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa_work

Host github.com-private
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa

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

&lt;/div&gt;



&lt;p&gt;After you have set up your &lt;code&gt;SSH&lt;/code&gt; like this, all you need to is clone your repositories like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone git@github.com-work:&amp;lt;organization&amp;gt;/&amp;lt;repo&amp;gt;.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and it will automatically use the private key associated with your work account. The same can be achieved by changing your remote &lt;code&gt;URL&lt;/code&gt;s on already cloned repositories respectively.&lt;/p&gt;

</description>
      <category>git</category>
      <category>productivity</category>
      <category>automation</category>
      <category>tips</category>
    </item>
  </channel>
</rss>
