<?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: Mark van Holsteijn</title>
    <description>The latest articles on Forem by Mark van Holsteijn (@mvanholsteijn).</description>
    <link>https://forem.com/mvanholsteijn</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%2F1135884%2F7aa2f469-aa67-4ef2-a621-f6865868c179.png</url>
      <title>Forem: Mark van Holsteijn</title>
      <link>https://forem.com/mvanholsteijn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mvanholsteijn"/>
    <language>en</language>
    <item>
      <title>How to overcome Docker Hub rate limiting using AWS ECR and AWS CloudFormation</title>
      <dc:creator>Mark van Holsteijn</dc:creator>
      <pubDate>Sun, 08 Oct 2023 22:00:00 +0000</pubDate>
      <link>https://forem.com/mvanholsteijn/how-to-overcome-docker-hub-rate-limiting-using-aws-ecr-and-aws-cloudformation-3hce</link>
      <guid>https://forem.com/mvanholsteijn/how-to-overcome-docker-hub-rate-limiting-using-aws-ecr-and-aws-cloudformation-3hce</guid>
      <description>&lt;p&gt;In this blog post, you will see how AWS ECR and AWS CloudFormation overcome the rate limiting imposed by &lt;a href="https://hub.docker.com/"&gt;Docker Hub&lt;/a&gt; and provide full control over your base images.&lt;/p&gt;

&lt;p&gt;The popular registry &lt;a href="https://hub.docker.com"&gt;Docker Hub&lt;/a&gt; is home to thousands of useful container images, used by many software delivery processes. Unfortunately, the registry enforces a rate limit for anonymous and free-tier users. Whenever you try to pull an image from an AWS CodeBuild project, you immediately run it this problem. AWS offers many Docker Hub images directly from their public AWS ECR registry &lt;a href="https://public.ecr.aws"&gt;https://public.ecr.aws&lt;/a&gt;, but not all of them. So, when you want to use a public image not on offer, you are stuck.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overcome Docker Hub rate limiting
&lt;/h2&gt;

&lt;p&gt;Our &lt;a href="https://github.com/binxio/cfn-container-image-provider"&gt;Custom CloudFormation Container Image Provider&lt;/a&gt; offers an effective workaround by allowing you to clone public images into a private &lt;a href="https://aws.amazon.com/ecr"&gt;Amazon Elastic Container Registry&lt;/a&gt; repository. By leveraging the custom provider you use CloudFormation to avoid the rate limit imposed by Docker Hub. Once the image is copied, you can pull the image as often as you want from your own ECR repository. This ensures a smooth and uninterrupted development process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full control over updating base images
&lt;/h2&gt;

&lt;p&gt;Another advantage of using the Custom CloudFormation Container Image Provider is that you gain complete control over the base images. You can enable &lt;a href="https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html"&gt;container image scanning&lt;/a&gt; and see which vulnerabilities live inside the public image. By using a &lt;a href="https://aws.amazon.com/cloudformation/"&gt;CloudFormation&lt;/a&gt; template you specify the exact image version you want.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/binxio/cru"&gt;container reference update utility – cru&lt;/a&gt; can be used to updates image references in the CloudFormation template and trigger the provisioning of the latest version to your ECR repository.&lt;/p&gt;

&lt;p&gt;This effectively gives you a well defined process for provisioning container images.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example usage
&lt;/h2&gt;

&lt;p&gt;To demonstrate the usage of the Custom CloudFormation Container Image Provider, let’s consider the following CloudFormation template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Resources:
  Repository:
    Type: AWS::ECR::Repository
    Properties:
      RepositoryName: python

  Python37:
    Type: 'Custom::ContainerImage'
    Properties:
      ImageReference: docker.io/library/python:3.7
      RepositoryArn: !GetAtt Repository.Arn
      ServiceToken: !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:cfn-container-image-provider'

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

&lt;/div&gt;



&lt;p&gt;In this example, we clone the current repository from the public image ‘python:3.7’ into our ‘python’ repository in ECR. The ‘Repository’ resource creates the ECR repository, and the ‘Python37’ resource uses the custom resource ‘Custom::ContainerImage’ to clone the image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating the image reference
&lt;/h2&gt;

&lt;p&gt;To pin the image to a specific version, you can use the &lt;a href="https://github.com/binxio/cru"&gt;container reference update utility – cru&lt;/a&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cru update \
        --resolve-digest --all \
        --matching-tag \
        demo.yaml

023/10/07 16:20:56 INFO: 1 image references found
2023/10/07 16:20:57 resolving repository docker.io/library/python Tag 3.7 to Digest sha256:eedf63967cdb57d8214db38ce21f105003ed4e4d0358f02bedc057341bcf92a0
2023/10/07 16:20:57 INFO: updated a total of 1 files
2023/10/07 16:20:57 INFO: no commit message, skipping commit and push

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

&lt;/div&gt;



&lt;p&gt;Now the container image reference will have the associated digest of the image, so you know exactly which image is used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Python37:
    Type: 'Custom::ContainerImage'
    Properties:
      ImageReference: 'docker.io/library/python:3.7@sha256:eedf63967cdb57d8214db38ce21f105003ed4e4d0358f02bedc057341bcf92a0'

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installing the provider
&lt;/h2&gt;

&lt;p&gt;To install this custom resource provider, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;read -p 'VPC id:' VPC_ID
read -p 'private subnet ids (comma separated):' PRIVATE_SUBNET_IDS
read -p 'security group ids (comma separated):' SECURITY_GROUP_IDS

aws cloudformation create-stack \
       --capabilities CAPABILITY_IAM \
       --stack-name cfn-container-image-provider \
       --template-url s3://binxio-public-eu-central-1/lambdas/cfn-container-image-provider-0.2.4.yaml \
       --parameter-overrides \
          ParameterKey=AppVPC,ParameterValue=$VPC_ID \
          ParameterKey=Subnets,ParameterValue=$PRIVATE_SUBNET_IDS \
          ParameterKey=SecurityGroupIds,ParameterValue=$SECURITY_GROUP_IDS

aws cloudformation wait stack-create-complete \
       --stack-name cfn-container-image-provider

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

&lt;/div&gt;



&lt;p&gt;or use &lt;a href="https://console.aws.amazon.com/cloudformation/home?region=eu-central-1#/stacks/new?stackName=cfn-container-image-provider&amp;amp;templateURL=https://binxio-public-eu-central-1.s3.amazonaws.com/lambdas/cfn-container-image-provider-0.2.4.yaml"&gt;launch stack&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The provider is installed on the private subnets in your VPC, to ensure that your NAT gateway IP addresses are used to pull images from docker hub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The Custom CloudFormation Container Image Provider addresses two important challenges that developers and organisations face when working with container images. By cloning public images into your ECR repository, you can overcome the rate limit imposed by Docker Hub, and ensure uninterrupted access to the images you need. Additionally, you gain full control over which images are used in your organisation.&lt;/p&gt;




&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@zmefc?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Zé Maria&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/bYJ3OpyXfuw?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://xebia.com/blog/how-to-overcome-docker-hub-rate-limiting-using-aws-ecr-and-cloudformation/"&gt;How to overcome Docker Hub rate limiting using AWS ECR and AWS CloudFormation&lt;/a&gt; appeared first on &lt;a href="https://xebia.com"&gt;Xebia&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Seamlessly connect Gitlab CI/CD with AWS: Gitlab AWS credential helper</title>
      <dc:creator>Mark van Holsteijn</dc:creator>
      <pubDate>Sun, 01 Oct 2023 22:08:00 +0000</pubDate>
      <link>https://forem.com/mvanholsteijn/seamlessly-connect-gitlab-cicd-with-aws-gitlab-aws-credential-helper-21k2</link>
      <guid>https://forem.com/mvanholsteijn/seamlessly-connect-gitlab-cicd-with-aws-gitlab-aws-credential-helper-21k2</guid>
      <description>&lt;p&gt;In this blog we will show you how our Gitlab AWS credential helper will make it very easy to connect to an AWS account using the gitlab pipeline &lt;a href="https://docs.gitlab.com/ee/ci/secrets/id_token_authentication.html"&gt;id token&lt;/a&gt; as your identity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Since June 2022, Gitlab provides JWT identity tokens for each project pipeline, which can be exchanged for AWS access credentials using the &lt;a href="https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html"&gt;assume-role-with-web-identity&lt;/a&gt; API call. This is great, because it allows you to configure the AWS permissions for each individual pipeline. However the problem is that exchanging the token for credentials requires quite a bit of shell programming. Something along the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ROLE_ARN=$1
WEB_IDENTITY_TOKEN=$2
ROLE_SESSION_NAME=gitlab-${CI_PROJECT_PATH_SLUG}-${CI_PIPELINE_ID}

CREDENTIALS=($(aws sts assume-role-with-web-identity \
        --role-arn ${ROLE_ARN} \
        --role-session-name ${ROLE_SESSION_NAME} \
        --web-identity-token "${WEB_IDENTITY_TOKEN}" \
        --duration-seconds 3600 \
        --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' \
        --output text))

aws configure set aws_access_key_id "${CREDENTIALS[0]}"
aws configure set aws_secret_access_key "${CREDENTIALS[1]}"
aws configure set aws_session_token "${CREDENTIALS[2]}"

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

&lt;/div&gt;



&lt;p&gt;As you can see that is quite a complex shell script. This will not look pretty in your &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;, and you will would probably add this as a separate script to your project. For a single project this is ok-ish, but to apply that to all your projects, is not going to scale well: As this script is not suitable for all situations, you probably end up with some variants as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gitlab AWS credential helper to the rescue
&lt;/h3&gt;

&lt;p&gt;This is where the gitlab aws credential helper comes in! The utility is flexible and very easy to use in all sorts of situations. It is simple to configure, as it only needs the AWS account number and Gitlab id token. The Gitlab project path slug and pipeline id will be used to determine the IAM role- and session name. The general configuration of the CI/CD pipeline consists of the following five steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the Gitlab ID token&lt;/li&gt;
&lt;li&gt;Set the AWS variables&lt;/li&gt;
&lt;li&gt;Configure the credential helper&lt;/li&gt;
&lt;li&gt;
Create the IAM role for the pipeline &lt;/li&gt;
&lt;li&gt;Install the credential helper&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s us take you through these five steps in the following paragraphs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add Gitlab ID token
&lt;/h3&gt;

&lt;p&gt;To obtain an Gitlab ID token in your pipeline jobs, add the following definition to your pipeline definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;default:
  id_tokens:
    GITLAB_AWS_IDENTITY_TOKEN:
      aud: https://gitlab.com

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

&lt;/div&gt;



&lt;p&gt;This will cause each job to have an environment variable name &lt;code&gt;GITLAB_AWS_IDENTITY_TOKEN&lt;/code&gt; with the JWT identity token signed by Gitlab as a value. The credential helper expects the token in this variable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set AWS variables
&lt;/h3&gt;

&lt;p&gt;To know which AWS account to connect to, add the environment variable &lt;code&gt;GITLAB_AWS_ACCOUNT_ID&lt;/code&gt; with your AWS account id:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variables:
  GITLAB_AWS_ACCOUNT_ID: '1234567898012'

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

&lt;/div&gt;



&lt;p&gt;If you have many gitlab projects, you can also set this variable as a CI/CD variable &lt;a href="https://docs.gitlab.com/ee/ci/variables/#for-a-group"&gt;on the group level&lt;/a&gt;. We recommend to add the following variables as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variables:
  - AWS_CONFIG_FILE: ${CI_PROJECT_DIR}/.aws/config
  - AWS_SHARED_CREDENTIALS_FILE: ${CI_PROJECT_DIR}/.aws/credentials
  - AWS_PROFILE: default

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

&lt;/div&gt;



&lt;p&gt;These will make sure the credential configurations are kept in scope of the pipeline build and that the obtained credentials are actually used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the credential helper
&lt;/h3&gt;

&lt;p&gt;Now you are ready to use the credential helper, in one of three different ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;as credential process&lt;/li&gt;
&lt;li&gt;stored as shared credentials&lt;/li&gt;
&lt;li&gt;as environment variables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s look at each of these options.&lt;/p&gt;

&lt;h4&gt;
  
  
  As credential process
&lt;/h4&gt;

&lt;p&gt;The most elegant use, is to configure the credential helper as &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html"&gt;AWS credential process&lt;/a&gt;, like shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;before_script:
  - &amp;gt;
    aws config --profile default 
    set credential_process 
    "gitlab-aws-credential-helper process"

script:
  - aws --profile default sts get-caller-identity

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

&lt;/div&gt;



&lt;p&gt;The AWS SDK will call the credential helper whenever it requires to access to AWS!&lt;/p&gt;

&lt;h4&gt;
  
  
  Stored as shared credentials
&lt;/h4&gt;

&lt;p&gt;Alternatively, the helper can store the AWS credentials directly in the AWS shared credentials file. You can do this as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;before_script:
  - &amp;gt;
    gitlab-aws-credential-helper aws-profile 

script:
  - aws --profile default sts get-caller-identity

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

&lt;/div&gt;



&lt;p&gt;This will store the credentials in shared credentials file, normally ~/.aws/credentials.&lt;/p&gt;

&lt;h4&gt;
  
  
  Get as environment variables
&lt;/h4&gt;

&lt;p&gt;Finally, you can use the helper to export the environment variables AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY&lt;br&gt;&lt;br&gt;
 and AWS_SESSION_TOKEN, as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script:
  - eval $(gitlab-aws-credential-helper env --export)
  - aws sts get-caller-identity

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

&lt;/div&gt;



&lt;p&gt;Alternatively, you can directly execute the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script:
  - gitlab-aws-credential-helper env -- aws sts get-caller-identity

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create the pipeline IAM role
&lt;/h3&gt;

&lt;p&gt;Once the pipeline is prepared, you need to add the IAM role for the CI/CD pipeline. The name of the role should be equal to the name of the gitlab project path slug as defined by the variable CI_PROJECT_PATH_SLUG, prefixed with &lt;code&gt;gitlab-&lt;/code&gt;. The following CloudFormation template shows an example IAM role definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWSTemplateFormatVersion: '2010-09-09'
Description: Role for gitlab pipeline with limited AWS access
Parameters:
  RepositoryPath:
    Description: the gitlab repository path
    Type: String
  RepositoryPathSlug:
    Description: the gitlab repository path slug
    Type: String
Resources:
  GitlabPipeline:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub 'gitlab-${RepositoryPathSlug}'
      MaxSessionDuration: 3600
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRoleWithWebIdentity
            Principal:
              Federated: !Sub 'arn:aws:iam::${AWS::AccountId}:oidc-provider/gitlab.com'
            Effect: Allow
            Condition:
              ForAnyValue:StringLike:
                "gitlab.com:sub":
                  - !Sub "project_path:${RepositoryPath}:ref_type:branch:ref:*"
      Policies:
        - PolicyName: MetaInformationAccess
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - sts:GetCallerIdentity
                Resource:
                  - '*'

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

&lt;/div&gt;



&lt;p&gt;The template assumes you have already created the OIDC provider for gitlab.com in your account. If not, checkout &lt;a href="https://xebia.com/blog/how-to-update-the-thumbprint-for-an-openid-connect-identity-provider-in-cloudformation/"&gt;this blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To create the role you need, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CI_PROJECT_PATH=mvanholsteijn/aws-credential-helper-demo
CI_PROJECT_PATH_SLUG=mvanholsteijn-aws-credential-helper
aws cloudformation deploy \
  --stack-name gitlab-$CI_PROJECT_PATH_SLUG \
  --template-file gitlab-pipeline-limited-access.yaml \
  --capabilities CAPABILITY_NAMED_IAM \
   --parameter-overrides \
     "RepositoryPath=$CI_PROJECT_PATH" \
     "RepositoryPathSlug=$CI_PROJECT_PATH_SLUG"

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

&lt;/div&gt;



&lt;p&gt;This all you need for one pipeline. The following two paragraphs will explain how to install the credential helper and show you how to override defaults.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install the credential helper
&lt;/h3&gt;

&lt;p&gt;Of course, your job will need to have the &lt;a href="https://github.com/binxio/gitlab-aws-credential-helper"&gt;gitlab-aws-credential-helper&lt;/a&gt; installed. We recommend to add it to the image that runs your job using a multi-stage docker build file, as show below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM ghcr.io/binxio/gitlab-aws-credential-helper:0.3.2 as gitlab-aws-credential-helper

FROM &amp;lt;yourimage&amp;gt;

COPY --from=gitlab-aws-credential-helper /usr/local/bin/gitlab-aws-credential-helper /usr/local/bin

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

&lt;/div&gt;



&lt;p&gt;If you do not manage your own runner image, you can add the following command to the before_script section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME=gitlab-aws-credential-helper
RELEASE=0.3.2
URL=https://github.com/binxio/$NAME/releases/download/${RELEASE}/${NAME}_${RELEASE}_linux_amd64.tar.gz
CHECKSUM=b8c84f1ca5622f4b0f529eca74e7689ea20418eab31a96666366ae1e1531b41f
ARCHIVE="$(basename $URL)"

cd /tmp &amp;amp;&amp;amp; \
    curl -L -O -sS $URL &amp;amp;&amp;amp; \
    (echo "$CHECKSUM $ARCHIVE" | sha256sum -c -) &amp;amp;&amp;amp; \
    tar -C /usr/local/bin/ -xzf $ARCHIVE &amp;amp;&amp;amp; \
    rm -f $ARCHIVE

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Overriding defaults
&lt;/h3&gt;

&lt;p&gt;The credential helper uses sensible defaults to make it as easy as possible. Of course, you can override all options via environment variables or via the command line. The following example shows how to create different profiles for a named role in different accounts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;before_script:
  -&amp;gt;
    gitlab-aws-credential-helper
    aws-profile --name development
    --aws-account 111111111111 
    --role Deployer
  -&amp;gt;
    gitlab-aws-credential-helper
    aws-profile --name test
    --aws-account 222222222222 
    --role Deployer
  -&amp;gt;
    gitlab-aws-credential-helper
    aws-profile --name production
    --aws-account 333333333333 
    --role Deployer

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

&lt;/div&gt;



&lt;p&gt;Use the &lt;code&gt;--help&lt;/code&gt; flag to get an overview of all possible options for each of the command usages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With the Gitlab AWS credential helper, it becomes really easy to provide each Gitlab CI/CD pipeline with the least amount of privileges required to perform their task on AWS. Just configure the AWS account number and add the credential helper to the runner and create an IAM role for each gitlab project.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://xebia.com/blog/seamlessly-connect-gitlab-cicd-with-aws-gitlab-aws-credential-helper/"&gt;Seamlessly connect Gitlab CI/CD with AWS: Gitlab AWS credential helper&lt;/a&gt; appeared first on &lt;a href="https://xebia.com"&gt;Xebia&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cicd</category>
      <category>gitlab</category>
    </item>
    <item>
      <title>How to create and deploy a golang AWS CloudFormation custom provider in less than 5 minutes</title>
      <dc:creator>Mark van Holsteijn</dc:creator>
      <pubDate>Mon, 31 Jul 2023 22:16:00 +0000</pubDate>
      <link>https://forem.com/mvanholsteijn/how-to-create-and-deploy-a-golang-aws-cloudformation-custom-provider-in-less-than-5-minutes-38dd</link>
      <guid>https://forem.com/mvanholsteijn/how-to-create-and-deploy-a-golang-aws-cloudformation-custom-provider-in-less-than-5-minutes-38dd</guid>
      <description>&lt;p&gt;In this blog I will show you how to create and deploy a &lt;a href="https://golang.org"&gt;Golang&lt;/a&gt; AWS CloudFormation custom provider in less than 5 minutes using a &lt;a href="https://copier.readthedocs.io/"&gt;copier&lt;/a&gt; template.&lt;/p&gt;

&lt;p&gt;Creating a custom resource in CloudFormation is really simple. You just implement a create, update and delete method in a Lambda and you are done. But that is the easy part: you still have to create zip files, unit tests, documentation, demo’s, CI/CD deployment pipelines and more. This &lt;a href="https://github.com/binxio/cloudformation-custom-provider-golang-template"&gt;copier&lt;/a&gt; template has it all!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it creates the source code for a Golang custom resource provider&lt;/li&gt;
&lt;li&gt;it provides all the build commands you need to build, test and deploy your provider&lt;/li&gt;
&lt;li&gt;it deploys lambdas to buckets in all AWS regions in the world&lt;/li&gt;
&lt;li&gt;it provides a ready-to-deploy CI/CD pipeline on &lt;a href="https://aws.amazon.com/codebuild/"&gt;AWS Codebuild&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;it supports semantic versioning using &lt;a href="https://github.com/binxio/git-release-tag"&gt;git-release-tag&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  getting started!
&lt;/h2&gt;

&lt;p&gt;Let’s say you want to create a custom resource for a ECR Container Image, so that you an clone public images into an ECR repository. Although there is a &lt;a href="https://github.com/google/containerregistry"&gt;Python library&lt;/a&gt; to implement this, it is unfortunately no longer supported. Fortunately, there is a Golang library &lt;a href="https://github.com/google/go-containerregistry/tree/main"&gt;go-containerregistry&lt;/a&gt; to do the trick. To skaffold a project to implement a custom provider based on Golang, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pip install 'copier&amp;gt;=8.0.0'
$ copier copy --trust \
   https://github.com/binxio/cloudformation-custom-provider-golang-template \
   /tmp/cfn-container-image-provider

🎤 the name of your custom resource type?
   ContainerImage
🎤 The name of your resource provider?
   cfn-container-image-provider
🎤 a short description for the custom provider?
   manages container images
🎤 golang version to use
   1.20
🎤 Your full name?
   Mark van Holsteijn
🎤 Your email address?
   mark.vanholsteijn@xebia.com
🎤 the go module name
   github.com/binxio/cfn-container-image-provider
🎤 the URL to git source repository?
   https://github.com/binxio/cfn-container-image-provider.git
🎤 the AWS region name
   eu-central-1
🎤 prefix for the S3 bucket name to store the lambda zipfiles?
   binxio-public
🎤 Access to lambda zip files?
   public

Copying from template version 0.1.0
 ...
 &amp;gt; Running task 1 of 1: [! -f go.sum] &amp;amp;&amp;amp; (go mod download || echo "WARNING: failed to run go mod"&amp;gt;&amp;amp;2); [! -d .git] &amp;amp;&amp;amp; ( git init &amp;amp;&amp;amp; git add . &amp;amp;&amp;amp; git commit -m 'initial import' &amp;amp;&amp;amp; git tag 0.0.0) || exit 0
Initialized empty Git repository in ...
[main (root-commit) c97b9e2] initial import
 15 files changed, 529 insertions(+)

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  source code directory
&lt;/h3&gt;

&lt;p&gt;The copier generates the following source code directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── Dockerfile.lambda # creates the zip file
├── Makefile.mk # generic build steps for the provider
├── Makefile # customization of build steps
├── cloudformation
│ ├── cfn-custom-image-provider.yaml # to deploy the provider
│ ├── cicd-pipeline.yaml # to deploy the Codebuild CI/CD pipeline
│ └── demo.yaml # to deploy the demo
├── doc
│ └── ContainerImage.md # start documentation of resource
├── go.mod
├── go.sum
├── main.go # main entrypoint
└── pkg
    └── resources
        └── container_image
            └── handler.go # sample code

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

&lt;/div&gt;



&lt;p&gt;That is all that is needed to create a project with a working custom provider for the resource &lt;code&gt;ContainerImage&lt;/code&gt;. When you change to the directory and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make deploy-provider
$ make deploy-demo

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

&lt;/div&gt;



&lt;p&gt;Your provider will be up-and-running in less than 5 minutes! Now it is up to you refactor the implementation to provide the required functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Available build commands
&lt;/h2&gt;

&lt;p&gt;to help you in the development process, the following build commands are available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make help

build - build the lambda zip file
fmt - formats the source code

test - run unit tests
test-templates - validate CloudFormation templates

deploy - AWS lambda zipfile to bucket
deploy-all-regions - AWS lambda zipfiles to all regional buckets
undeploy-all-regions - deletes AWS lambda zipfile of this release from all
buckets in all regions

deploy-provider - deploys the custom provider
delete-provider - deletes the custom provider

deploy-pipeline - deploys the CI/CD deployment pipeline
delete-pipeline - deletes the CI/CD deployment pipeline

deploy-demo - deploys the demo stack
delete-demo - deletes the demo stack

tag-patch-release - create a tag for a new patch release
tag-minor-release - create a tag for a new minor release
tag-major-release - create a tag for new major release

show-version - shows the current version of the workspace
help - Show this help.

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploy the zip file to the bucket
&lt;/h3&gt;

&lt;p&gt;To copy the zip file with the source code of the AWS Lambda of the custom resource provider, the buckets must already exist. If they do not, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ BUCKET=&amp;lt;bucket-prefix&amp;gt;-&amp;lt;bucket-region&amp;gt;
$ aws s3 mb s3://$BUCKET
$ aws s3api put-bucket-ownership-controls \
    --bucket $BUCKET --ownership-controls \
    'Rules=[{ObjectOwnership=BucketOwnerPreferred}]'

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

&lt;/div&gt;



&lt;p&gt;The build system expects the bucket name to consists of the prefix and the region name. This allows the provider to be made available for use in all regions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy the custom resource provider into the account
&lt;/h3&gt;

&lt;p&gt;To configure the run-time parameters and permissions of the your provider, change the CloudFormation template in the directory &lt;code&gt;./cloudformation&lt;/code&gt;. Once that is done, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make deploy-provider

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploy the custom resource demo
&lt;/h3&gt;

&lt;p&gt;To deploy a CloudFormation stack with an example use of the custom resource, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make deploy-demo

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Version your custom resource provider
&lt;/h3&gt;

&lt;p&gt;Semantic versioning of the provider is implemented using the utility &lt;a href="https://github.com/binxio/git-release-tag"&gt;git-release-tag&lt;/a&gt;. If you have not installed git-release-tag, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pip install git-release-tag

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

&lt;/div&gt;



&lt;p&gt;To version your custom resource provider, you can use the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make tag-patch-release - create a tag for a new patch release
make tag-minor-release - create a tag for a new minor release
make tag-major-release - create a tag for new major release

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

&lt;/div&gt;



&lt;p&gt;This will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run the pre-tag command in the file &lt;code&gt;./release&lt;/code&gt;, to update all files with references to the semantic version&lt;/li&gt;
&lt;li&gt;commit all outstanding changes in the workspace&lt;/li&gt;
&lt;li&gt;tag the commit with the new version&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To show the current version of the workspace, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make show-version

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploy provider to all regions
&lt;/h3&gt;

&lt;p&gt;To deploy the current version of your provider to all regions, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make deploy-all-regions

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

&lt;/div&gt;



&lt;p&gt;This assumes you have buckets in all regions with the defined prefix.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy CI/CD pipeline
&lt;/h3&gt;

&lt;p&gt;To deploy the CI/CD pipeline based on AWS Codebuild, make sure that the AWS account can access the source repository. If that is the case, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make deploy-pipeline

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

&lt;/div&gt;



&lt;p&gt;Now, every time you tag a new release, it will automatically be deployed to all regions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This &lt;a href="https://copier.readthedocs.io/"&gt;copier&lt;/a&gt; template provides everything you need to quickly build, deploy and maintain a new &lt;a href="https://golang.org"&gt;Golang&lt;/a&gt; custom AWS CloudFormation Provider! If you have any questions, problems or feedback feel free to contact me or add issues at &lt;a href="https://github.com/binxio/cloudformation-custom-provider-golang-template"&gt;https://github.com/binxio/cloudformation-custom-provider-golang-template&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to create your resource provider in Python, we also have a &lt;a href="https://xebia.com/blog/how-to-create-and-deploy-an-aws-cloudformation-custom-provider-in-less-the-5-minutes/"&gt;solution&lt;/a&gt; for that!&lt;/p&gt;




&lt;p&gt;Image by &lt;a href="https://pixabay.com/users/jarmoluk-143740/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=1080492"&gt;Michal Jarmoluk&lt;/a&gt; from &lt;a href="https://pixabay.com//?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=1080492"&gt;Pixabay&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://xebia.com/blog/how-to-create-and-deploy-a-golang-aws-cloudformation-custom-provider-in-less-the-5-minutes/"&gt;How to create and deploy a golang AWS CloudFormation custom provider in less than 5 minutes&lt;/a&gt; appeared first on &lt;a href="https://xebia.com"&gt;Xebia&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
    </item>
    <item>
      <title>How to create and deploy a Slackbot on Google Cloud Platform in less than 5 minutes</title>
      <dc:creator>Mark van Holsteijn</dc:creator>
      <pubDate>Sun, 19 Mar 2023 09:39:00 +0000</pubDate>
      <link>https://forem.com/mvanholsteijn/how-to-create-and-deploy-a-slackbot-on-google-cloud-platform-in-less-than-5-minutes-4ijd</link>
      <guid>https://forem.com/mvanholsteijn/how-to-create-and-deploy-a-slackbot-on-google-cloud-platform-in-less-than-5-minutes-4ijd</guid>
      <description>&lt;p&gt;In this blog I will show you how to create and deploy a Slackbot on Google Cloud Platform in less than 5 minutes using &lt;a href="https://copier.readthedocs.io/"&gt;copier&lt;/a&gt; template. To write a bot for Slack is not too difficult. With a few lines of code, you can create a program which will respond to slack commands and mentions. But that is the easy part: you also need to configure the application in Slack, deploy it so that is available 7×24, write unit tests and create CI/CD deployment pipelines and more. This &lt;a href="https://copier.readthedocs.io/"&gt;copier&lt;/a&gt; template has it all!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it creates the source code for your slackbot.&lt;/li&gt;
&lt;li&gt;it provides the Terraform templates for the infrastructure, the application and the CI/CD pipeline.&lt;/li&gt;
&lt;li&gt;it provides a CI/CD pipeline using &lt;a href="https://cloud.google.com/build"&gt;Google CloudBuild&lt;/a&gt; to build and deploy the application and infrastructure changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means you can start interacting with your slackbot and iteratively improve the implementation until you have the perfect bot.&lt;/p&gt;

&lt;h1&gt;
  
  
  deploy a slackbot to Google Cloud Platform
&lt;/h1&gt;

&lt;p&gt;To create and deploy your slackbot, you need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;generate the source directory&lt;/li&gt;
&lt;li&gt;create the application in Slack&lt;/li&gt;
&lt;li&gt;install the application in the workspace&lt;/li&gt;
&lt;li&gt;obtain the application token&lt;/li&gt;
&lt;li&gt;obtain the signing secret&lt;/li&gt;
&lt;li&gt;obtain the bot user OAuth token&lt;/li&gt;
&lt;li&gt;deploy the slackbot&lt;/li&gt;
&lt;li&gt;deploy the tokens and secrets&lt;/li&gt;
&lt;li&gt;run the CI/CD pipeline&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The following sections provide a detailed explanation of each step.&lt;/p&gt;

&lt;h2&gt;
  
  
  generate the source directory
&lt;/h2&gt;

&lt;p&gt;Let’s say you want to create a slackbot which generates images using &lt;a href="https://openai.com/product/dall-e-2"&gt;Dall-e&lt;/a&gt;. To generate the source directory, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pip install copier
$ copier https://github.com/binxio/slackbot-on-google-cloud-platform-template.git /tmp/dali


&amp;gt; the human readable name of your slackbot
   Salvador Dali
&amp;gt; a short description of the Slackbot
   generates images on request
&amp;gt; the name of the package
   salvador_dali_slackbot
&amp;gt; the slackbot command prefix
   /dali
&amp;gt; Your full name?
   Mark van Holsteijn
&amp;gt; Your email address?
   mark.vanholsteijn@xebia.com
&amp;gt; the google project to deploy to
   speeltuin-mvanholsteijn
&amp;gt; primary region to deploy the slackbot to
   europe-west4
&amp;gt; the replica region for slackbot artifacts
   europe-west1
&amp;gt; the artifact repository location to deploy the image to
   europe
&amp;gt; name of the terraform state bucket
   speeltuin-mvanholsteijn-terraform-state

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

&lt;/div&gt;



&lt;p&gt;Now the source code is ready in /tmp/dali. The contents of that directory 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;.
├── src # bootstrap implementation
│   └── salvador_dali_slackbot
│   ├── __init__.py
│   ├── __main__.py
│   ├── bot.py
│   ├── google_secrets.py
│   └── manifest.yaml
├── tests # skaffold tests for bot functions
│   ├── test_command_help.py
│   └── test_mention_help.py
├── terraform # deployment definitions
│   ├── pipeline.tf
│   ├── slackbot.tf
│   ├── user-data.yaml
│   ├── variables.tf
│   └── versions.tf
│   ├── providers.tf
├── cloudbuild # CI/CD pipeline definitions
│   ├── build.yaml
│   └── deploy.yaml
├── secrets 
├── Dockerfile
├── Makefile
├── Makefile.mk
├── Pipfile
├── pyproject.toml
├── setup.cfg
├── tox.ini

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

&lt;/div&gt;



&lt;p&gt;As you can see everything you need to build, maintain and deploy a slackbot is there! Next, you need to create the application in Slack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the application in Slack
&lt;/h2&gt;

&lt;p&gt;To create the slackbot in Slack, you can use the application manifest &lt;code&gt;manifest.yaml&lt;/code&gt; found in the generated source directory. Copy the contents and goto &lt;a href="https://api.slack.com/apps"&gt;https://api.slack.com/apps&lt;/a&gt; and click on “create app from manifest”. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W7FkjhZx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://xebia.com/wp-content/uploads/2023/03/how-to-create-and-deploy-a-slack-bot-on-google-cloud-platform-in-less-than-5-minutes-create-app.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W7FkjhZx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://xebia.com/wp-content/uploads/2023/03/how-to-create-and-deploy-a-slack-bot-on-google-cloud-platform-in-less-than-5-minutes-create-app.jpg" alt="slack create new app from manifest" width="800" height="542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;your next step is to install the application in the slack workspace.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install the application in the workspace
&lt;/h2&gt;

&lt;p&gt;After you created the application, you can install it in your workspace. It is easy: just click the button and follow the flow.&lt;br&gt;&lt;br&gt;
  &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YLeGeM7J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://xebia.com/wp-content/uploads/2023/03/how-to-create-and-deploy-a-slack-bot-on-google-cloud-platform-in-less-than-5-minutes-install-app.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YLeGeM7J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://xebia.com/wp-content/uploads/2023/03/how-to-create-and-deploy-a-slack-bot-on-google-cloud-platform-in-less-than-5-minutes-install-app.jpg" alt="slack install application" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the application is installed, you need to obtain the application token, signing secret and bot token.&lt;/p&gt;
&lt;h2&gt;
  
  
  Obtain the application token
&lt;/h2&gt;

&lt;p&gt;After you install the application, scroll down the screen and generate an application token with the scope &lt;code&gt;connections:write&lt;/code&gt;. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yvUkHYgX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://xebia.com/wp-content/uploads/2023/03/how-to-create-and-deploy-a-slack-bot-on-google-cloud-platform-in-less-than-5-minutes-generate-app-token.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yvUkHYgX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://xebia.com/wp-content/uploads/2023/03/how-to-create-and-deploy-a-slack-bot-on-google-cloud-platform-in-less-than-5-minutes-generate-app-token.jpg" alt="slack generate app-token" width="800" height="621"&gt;&lt;/a&gt; Copy the generated app token into the file &lt;code&gt;secrets/app-token&lt;/code&gt;. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--58VNzi5n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://xebia.com/wp-content/uploads/2023/03/how-to-create-and-deploy-a-slack-bot-on-google-cloud-platform-in-less-than-5-minutes-app-token-generated.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--58VNzi5n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://xebia.com/wp-content/uploads/2023/03/how-to-create-and-deploy-a-slack-bot-on-google-cloud-platform-in-less-than-5-minutes-app-token-generated.jpg" alt="app token generated" width="800" height="556"&gt;&lt;/a&gt; This token will put into a Google secret manager secret later. First you need to get the signing secret and bot token.&lt;/p&gt;
&lt;h2&gt;
  
  
  Obtain the application signing secret
&lt;/h2&gt;

&lt;p&gt;To obtain the application signing secret, Navigate to Application Basic information, and copy the signing secret into the file &lt;code&gt;secrets/signing-secret&lt;/code&gt;. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y1qEHvaK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://xebia.com/wp-content/uploads/2023/03/how-to-create-and-deploy-a-slack-bot-on-google-cloud-platform-in-less-than-5-minutes-signing-secret.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y1qEHvaK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://xebia.com/wp-content/uploads/2023/03/how-to-create-and-deploy-a-slack-bot-on-google-cloud-platform-in-less-than-5-minutes-signing-secret.jpg" alt="signing secret" width="800" height="419"&gt;&lt;/a&gt; This secret will put into a Google secret manager secret later. The bot token is the last secret we need to get, before we can deploy the bot.&lt;/p&gt;
&lt;h2&gt;
  
  
  Obtain the bot user OAuth token
&lt;/h2&gt;

&lt;p&gt;To obtain the bot user OAuth token, navigate to OAuth and permissions and copy the token into the file &lt;code&gt;secrets/bot-token&lt;/code&gt;. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n9NLHPRa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://xebia.com/wp-content/uploads/2023/03/how-to-create-and-deploy-a-slack-bot-on-google-cloud-platform-in-less-than-5-minutes-bot-token.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n9NLHPRa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://xebia.com/wp-content/uploads/2023/03/how-to-create-and-deploy-a-slack-bot-on-google-cloud-platform-in-less-than-5-minutes-bot-token.png" alt="signing secret" width="800" height="197"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now everything is done to deploy the Slackbot using &lt;a href="https://terraform.io"&gt;Terraform&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  deploy the slackbot
&lt;/h2&gt;

&lt;p&gt;Before we can deploy the slackbot to Google Cloud Platform, you need to enable the used services and create the Terraform storage bucket. Type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make enable-services 
$ make state-bucket

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

&lt;/div&gt;



&lt;p&gt;Now you are ready to let Terraform do it’s magic. Type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd terraform
$ terraform init
$ terraform apply

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

&lt;/div&gt;



&lt;p&gt;This creates everything you need, but the bot will not yet run. The tokens and secrets needs to be made available as Google secrets.&lt;/p&gt;

&lt;h3&gt;
  
  
  deploy the tokens and secrets
&lt;/h3&gt;

&lt;p&gt;To deploy the tokens and secrets of the slackbot into the respective &lt;a href="https://cloud.google.com/secret-manager"&gt;Google secrets&lt;/a&gt;, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make configure-secrets

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  run the CI/CD pipeline
&lt;/h2&gt;

&lt;p&gt;Now deploy your changes to the git repository. This will trigger a build of the container image and a deployment of the newly created image using Google CloudBuild.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git push

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

&lt;/div&gt;



&lt;p&gt;Check the &lt;a href="https://console.cloud.google.com/cloud-build/builds"&gt;Google CloudBuild logs&lt;/a&gt; Once the build and deploy complete your bot is ready to run! You can now chat with your bot and start developing the functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This &lt;a href="https://copier.readthedocs.io/"&gt;copier&lt;/a&gt; template provides everything you need to quickly build, deploy and maintain a Slackbot on Google Cloud Platform. If you have any questions, problems or feedback feel free to contact me. You can also directly add issues on &lt;a href="https://github.com/binxio/slackbot-on-google-cloud-platform-template.git"&gt;Github&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@hostreviews?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Stephen Phillips – Hostreviews.co.uk&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/slack?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://xebia.com/blog/how-to-create-and-deploy-a-slack-bot-on-google-cloud-platform-in-less-than-5-minutes/"&gt;How to create and deploy a Slackbot on Google Cloud Platform in less than 5 minutes&lt;/a&gt; appeared first on &lt;a href="https://xebia.com"&gt;Xebia&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>googlecloudplatform</category>
    </item>
    <item>
      <title>How to create and deploy an AWS CloudFormation custom provider in less than 5 minutes</title>
      <dc:creator>Mark van Holsteijn</dc:creator>
      <pubDate>Wed, 08 Mar 2023 23:08:00 +0000</pubDate>
      <link>https://forem.com/mvanholsteijn/how-to-create-and-deploy-an-aws-cloudformation-custom-provider-in-less-than-5-minutes-2g27</link>
      <guid>https://forem.com/mvanholsteijn/how-to-create-and-deploy-an-aws-cloudformation-custom-provider-in-less-than-5-minutes-2g27</guid>
      <description>&lt;p&gt;In this blog I will show you how to create and deploy an AWS CloudFormation custom provider in less than 5 minutes using a Python &lt;a href="https://copier.readthedocs.io/"&gt;copier&lt;/a&gt; template. To create a custom resource in CloudFormation, is really simple. You just implement a create, update and delete method in a Lambda and you are done. But that is the easy part: you still have to create zip files, unit tests, documentation, demo’s, CI/CD deployment pipelines and more. This &lt;a href="https://copier.readthedocs.io/"&gt;copier&lt;/a&gt; template has it all!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it creates the source code for a custom resource provider&lt;/li&gt;
&lt;li&gt;all the build commands you need to build, test and deploy your provider&lt;/li&gt;
&lt;li&gt;it provides re-recordable unit testsusing &lt;a href="https://pypi.org/project/botocore-stubber-recorder/"&gt;botocore stubber recorder&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;it deploys lambdas to buckets in all AWS regions in the world&lt;/li&gt;
&lt;li&gt;it supports semantic versioning using &lt;a href="https://github.com/binxio/git-release-tag"&gt;git-release-tag&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;it provides a ready-to-deploy CI/CD pipeline on &lt;a href="https://aws.amazon.com/codebuild/"&gt;AWS Codebuild&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  getting started!
&lt;/h2&gt;

&lt;p&gt;Let’s say you want to create a custom resource for a Custom Domain of an AWS AppRunner service, because it does not yet exist. To get started, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pip install copier
$ copier https://github.com/binxio/cloudformation-custom-provider-template /tmp/cfn-app-runner-custom-domain-provider

🎤 the name of your custom resource type?
   AppRunnerCustomDomain
🎤 The name of your resource provider project?
   cfn-app-runner-custom-domain-provider
🎤 The name of your Python module?
   cfn_app_runner_custom_domain_provider
🎤 a short description for the custom provider?
   manages app runner custom domains
🎤 Python version to use
   3.9
🎤 Your full name?
   Mark van Holsteijn
🎤 Your email address?
   mark.vanholsteijn@xebia.com
🎤 the URL to git source repository?
   https://github.com/binxio/cfn-app-runner-custom-domain-provider
🎤 the AWS profile name
   integration-test
🎤 the AWS region name
   eu-central-1
🎤 prefix for the S3 bucket name to store the lambda zipfiles?
   binxio-public
🎤 Access to lambda zip files?
   public

&amp;gt; Running task 1 of 1: [[! -d .git]] &amp;amp;&amp;amp; ( git init &amp;amp;&amp;amp; git add . &amp;amp;&amp;amp; git commit -m 'initial import' &amp;amp;&amp;amp; git tag 0.0.0) || exit 0
Initialized empty Git repository in /tmp/cfn-app-runner-custom-domain-provider/.git/
[main (root-commit) b2ce863] initial import
 21 files changed, 619 insertions(+)
...

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  source code directory
&lt;/h3&gt;

&lt;p&gt;The copier generates the following source code directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── Dockerfile.lambda # creates the zip file
├── Makefile.mk # generic build steps for the provider
├── Makefile # customization of build steps
├── Pipfile # python virtual environment definition
├── cloudformation
│   ├── cfn-app-runner-custom-domain-provider.yaml # to deploy the provider
│   ├── cicd-pipeline.yaml # to deploy the Codebuild CI/CD pipeline
│   └── demo.yaml # to deploy the demo
├── doc
│   └── AppRunnerCustomDomain.md # start documentation of resource
├── pyproject.toml # Python project definition
├── setup.cfg # Python package settings
├── tox.ini # Python test definitions
├── src
│   └── cfn_app_runner_custom_domain_provider
│   ├── __init__.py
│   ├── app_runner_custom_domain.py # custom resource definition source
│   └── logger.py
├── tests
│   └── crud
│   ├── __init__.py
│   ├── base
│   │   └── __init__.py
│   └── test_crud.py # custom resource definition test

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

&lt;/div&gt;



&lt;p&gt;That is all that is needed to create a project with a working custom provider for the resource &lt;code&gt;AppRunnerCustomDomain&lt;/code&gt;. When you change to the directory and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pipenv install -d
$ make deploy-provider
$ make demo

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

&lt;/div&gt;



&lt;p&gt;Your provider will be up-and-running in less than 5 minutes!&lt;/p&gt;

&lt;h2&gt;
  
  
  Available build commands
&lt;/h2&gt;

&lt;p&gt;to see a list of all of available build commands, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make help

build - build the lambda zip file
fmt - formats the source code using black
test - run python unit tests
test-record - run python unit tests, while recording the boto3 calls
test-templates - validate CloudFormation templates

deploy - AWS lambda zipfile to bucket
deploy-all-regions - AWS lambda zipfiles to all regional buckets
undeploy-all-regions - deletes AWS lambda zipfile of this release from all buckets in all regions

deploy-provider - deploys the custom provider
delete-provider - deletes the custom provider

deploy-pipeline - deploys the CI/CD deployment pipeline
delete-pipeline - deletes the CI/CD deployment pipeline

deploy-demo - deploys the demo stack
delete-demo - deletes the demo stack

tag-patch-release - create a tag for a new patch release
tag-minor-release - create a tag for a new minor release
tag-major-release - create a tag for new major release

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run the unit tests
&lt;/h3&gt;

&lt;p&gt;To run the unit tests, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make test

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

&lt;/div&gt;



&lt;p&gt;The unit test will test the scaffold implementation generated by the &lt;a href="https://pypi.org/project/botocore-stubber-recorder/"&gt;botocore stubber recorder&lt;/a&gt;. To create unit tests for your resource, edit the source code in &lt;code&gt;./tests/&lt;/code&gt;. To implement your custom resource, edit the source code under &lt;code&gt;./src/&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Re-recordable unit tests
&lt;/h3&gt;

&lt;p&gt;Once you have your custom resource provider, it undoubtedly does some AWS API calls. The &lt;a href="https://pypi.org/project/botocore-stubber-recorder/"&gt;botocore stubber recorder&lt;/a&gt; library records the actual calls and generate the stub. The unit tests can be run in recording mode, where the test is against a real AWS account. To run your unit tests as integration test against a live system and record the stubs, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make test-record

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

&lt;/div&gt;



&lt;p&gt;To run the unit tests with the newly created stubs, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make test

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

&lt;/div&gt;



&lt;p&gt;The integration tests are run against the AWS profile and region you specified. To add a new test, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ botocore-stubber-recorder --test-name failed_create

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploy the zip file to the bucket
&lt;/h3&gt;

&lt;p&gt;To copy the zip file with the source code of the AWS Lambda of the custom resource provider, the buckets must already exist. If they do not, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws s3 mb s3://&amp;lt;bucket-prefix&amp;gt;-&amp;lt;bucket-region&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;The build system expects the bucket name to consists of the prefix and the region name. This allows the provider to be made available for use in all regions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy the custom resource provider into the account
&lt;/h3&gt;

&lt;p&gt;To configure the run-time parameters and permissions of the your provider, change the CloudFormation template in the directory &lt;code&gt;./cloudformation&lt;/code&gt;. Once that is done, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make deploy-provider

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploy the custom resource demo
&lt;/h3&gt;

&lt;p&gt;To deploy a CloudFormation stack with an example use of the custom resource, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make deploy-demo

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Version your custom resource provider
&lt;/h3&gt;

&lt;p&gt;Semantic versioning of the provider is implemented using the utility &lt;a href="https://github.com/binxio/git-release-tag"&gt;git-release-tag&lt;/a&gt;. To version your custom resource provider, you can use the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make tag-patch-release - create a tag for a new patch release
make tag-minor-release - create a tag for a new minor release
make tag-major-release - create a tag for new major release

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

&lt;/div&gt;



&lt;p&gt;This will: * runs the pre-tag command in the file &lt;code&gt;./release&lt;/code&gt;, to update all files with references to the semantic version * commit all outstanding changes in the workspace * tag the commit with the new version. To show the current version of the workspace, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make show-version

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploy provider to all regions
&lt;/h3&gt;

&lt;p&gt;To deploy the current version of your provider to all regions, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make deploy-all-regions

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

&lt;/div&gt;



&lt;p&gt;This assumes you have buckets in all regions with the defined prefix.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy CI/CD pipeline
&lt;/h3&gt;

&lt;p&gt;To deploy the CI/CD pipeline based on AWS Codebuild, make sure that the AWS account can access the source repository. If that is the case, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make deploy-pipeline

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

&lt;/div&gt;



&lt;p&gt;Now, every time you tag a new release, it will automatically be deployed to all regions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This &lt;a href="https://copier.readthedocs.io/"&gt;copier&lt;/a&gt; template provides everything you need to quickly build, deploy and maintain a new custom AWS CloudFormation Provider! If you have any questions, problems or feedback feel free to contact me or add issues at &lt;a href="https://github.com/binxio/cloudformation-custom-provider-template"&gt;https://github.com/binxio/cloudformation-custom-provider-template&lt;/a&gt;. If you want to create your resource provider in Golang, we also have a &lt;a href="https://xebia.com/blog/how-to-create-and-deploy-a-golang-aws-cloudformation-custom-provider-in-less-the-5-minutes/"&gt;solution&lt;/a&gt; for that!&lt;/p&gt;




&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@saffu?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Saffu&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/E4kKGI4oGaU?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://xebia.com/blog/how-to-create-and-deploy-an-aws-cloudformation-custom-provider-in-less-the-5-minutes/"&gt;How to create and deploy an AWS CloudFormation custom provider in less than 5 minutes&lt;/a&gt; appeared first on &lt;a href="https://xebia.com"&gt;Xebia&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
    </item>
    <item>
      <title>How to start a RDP session from the command line to a Windows server running on AWS</title>
      <dc:creator>Mark van Holsteijn</dc:creator>
      <pubDate>Tue, 25 Oct 2022 18:00:00 +0000</pubDate>
      <link>https://forem.com/mvanholsteijn/how-to-start-a-rdp-session-from-the-command-line-to-a-windows-server-running-on-aws-17fo</link>
      <guid>https://forem.com/mvanholsteijn/how-to-start-a-rdp-session-from-the-command-line-to-a-windows-server-running-on-aws-17fo</guid>
      <description>&lt;p&gt;To start a RDP session to a Windows server on AWS is a very labour-intensive task. You have to select the instance on the console, copy the private key to get the password, copy the password, download the RDP file. Then double-click on the RDP file, paste the password in a dialog box, and you are done. But it does not have to be this way. In this blog we will show you it can be as easy as using ssh!&lt;/p&gt;

&lt;h2&gt;
  
  
  prepare
&lt;/h2&gt;

&lt;p&gt;To allow quick and easy access you need to do prepare the following three things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;install &lt;a href="https://www.freerdp.com/"&gt;freeRDP&lt;/a&gt; on your machine&lt;/li&gt;
&lt;li&gt;install &lt;a href="https://www.xquartz.org/"&gt;XQuartz&lt;/a&gt; on MacOS&lt;/li&gt;
&lt;li&gt;store the private key material of the EC2 keypair in the SSM parameter store&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first two steps are simple, and will not be explained here. To store the private key material of the EC2 keypair in the SSM parameter store we use the following CloudFormation resource:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  KeyPair:
    Type: AWS::EC2::KeyPair
    Properties:
      KeyName: WindowsServer
      KeyType: rsa

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

&lt;/div&gt;



&lt;p&gt;Once you deploy this resource, the private key of the keypair named &lt;code&gt;WindowsServer&lt;/code&gt; is stored in the parameter store under the name &lt;code&gt;/ec2/keypair/&amp;lt;key-id&amp;gt;&lt;/code&gt;. This is nice, because it standardizes the name of the SSM parameter with the private key material.&lt;/p&gt;

&lt;h2&gt;
  
  
  start the rdp session
&lt;/h2&gt;

&lt;p&gt;Now we have everything to automate the start of a RDP session, using the following steps.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;determine the ec2 instance to connect to&lt;/li&gt;
&lt;li&gt;retrieve the private key of the keypair&lt;/li&gt;
&lt;li&gt;retrieve the admin password of the Windows server&lt;/li&gt;
&lt;li&gt;start the RDP session \o/&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  determine ec2 instance to connect to
&lt;/h3&gt;

&lt;p&gt;First we determine the EC2 instance id of the machine we want to connect to. In the following snippet, we assume that you have a single machine with tagged with the name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;instance_name=mydemo
instance_id=$(aws ec2 describe-instances \
              --query 'join(`\n`, Reservations[].Instances[].InstanceId)' \
              --output text \
              --filter "Name=tag:Name,Values=$instance_name" \
                       "Name=instance-state-name,Value=running")

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  retrieve the private key of the keypair
&lt;/h3&gt;

&lt;p&gt;To retrieve the private key of the keypair, we first retrieve the name of the keypair associated with the instance and retrieve the key id.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;key_name=$(aws ec2 describe-instances \
          --instance-id $instance_id \
          --query Reservations[0].Instances[0].KeyName \
          --output text)

key_id=$(aws ec2 describe-key-pairs \
         --key-names $key_name \
         --query KeyPairs[0].KeyPairId \
         --output text)

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

&lt;/div&gt;



&lt;p&gt;Now we can pull the private key material in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private_key=$(mktemp)
chmod 0600 $private_key
aws ssm get-parameter --name /ec2/keypair/$key_id \
      --with-decryption --query Parameter.Value \
      --output text &amp;gt; $private_key

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  retrieve the admin password of the Windows server
&lt;/h3&gt;

&lt;p&gt;To retrieve the admin password of the Windows server, we call &lt;code&gt;get-password-data&lt;/code&gt; with the private key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;password=$(aws ec2 get-password-data \
          --priv-launch-key $private_key --instance-id $instance_id \
          --query PasswordData \
          --output text)
rm -f $private_key

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  start the rdp session
&lt;/h3&gt;

&lt;p&gt;Finally, we have everything to automatically login using RDP. we just have to pick an IP address and run FreeRDP!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ip_address=$(aws ec2 describe-instances \
                --instance-ids $instance_id \
                --query 'join(`\n`, Reservations[].Instances[].PublicIpAddress)' \
                --output text)

xfreerdp /u:administrator /p:$password /v:$ip_address /cert:ignore

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

&lt;/div&gt;



&lt;p&gt;That is all there is to it! It is just as easy as running ssh :-p You can find the complete script on &lt;a href="https://gist.github.com/mvanholsteijn/fee96ea9baf23449ca9641f08f79814d"&gt;github&lt;/a&gt;. You can tailor it anyway you like.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why freeRDP and not Microsoft’s Remote Desktop Client
&lt;/h2&gt;

&lt;p&gt;So you may ask: Why not use &lt;a href="https://learn.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-clients"&gt;Microsoft’s Remote Desktop Client&lt;/a&gt;? That is quite easy: it does not support command line options. The alternative would be to generate the RDP file, but on non-Windows platforms you cannot store the password as the required encryption function only works on Windows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With the freeRDP client, you can fully automate starting an RDP session to a Windows Server running on AWS!&lt;/p&gt;

&lt;p&gt;Image by &lt;a href="https://pixabay.com/users/artificialog-1886751/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=2690101"&gt;ArtificialOG&lt;/a&gt; from &lt;a href="https://pixabay.com//?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=2690101"&gt;Pixabay&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://xebia.com/blog/how-to-start-a-rdp-session-to-a-windows-server-running-on-aws/"&gt;How to start a RDP session from the command line to a Windows server running on AWS&lt;/a&gt; appeared first on &lt;a href="https://xebia.com"&gt;Xebia&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
