<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: okamos</title>
    <description>The latest articles on DEV Community by okamos (@okamos102).</description>
    <link>https://dev.to/okamos102</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%2F1069627%2Fe22c76e9-b102-447e-97dd-8ce8a1823def.jpeg</url>
      <title>DEV Community: okamos</title>
      <link>https://dev.to/okamos102</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/okamos102"/>
    <language>en</language>
    <item>
      <title>An Essential CloudFormation Template for robust Scheduled Tasks in ECS on EC2</title>
      <dc:creator>okamos</dc:creator>
      <pubDate>Mon, 26 Jun 2023 13:58:43 +0000</pubDate>
      <link>https://dev.to/okamos102/an-essential-cloudformation-template-for-robust-scheduled-tasks-in-ecs-on-ec2-1gi6</link>
      <guid>https://dev.to/okamos102/an-essential-cloudformation-template-for-robust-scheduled-tasks-in-ecs-on-ec2-1gi6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This is a true story.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One day&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Me: Okay, the batch program is complete. This batch processing is super important, so it needs to work flawlessly.&lt;/p&gt;

&lt;p&gt;Me: If it doesn't run...&lt;/p&gt;

&lt;p&gt;Me: No use thinking about it now.&lt;/p&gt;

&lt;p&gt;Me: Registering it with ECS's scheduled tasks..., Done!&lt;/p&gt;

&lt;p&gt;Me: Even if the program fails, I'm monitoring for program errors and task failures, so it should be fine!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Few months later&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Boss: Hey! The batch program seems to be not working!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TAZPGzeV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p6oeyju5tv6p4545omkp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TAZPGzeV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p6oeyju5tv6p4545omkp.gif" alt="Image description" width="498" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Me: Wha...? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---emVeARG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3oyskdwaqetghito52mm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---emVeARG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3oyskdwaqetghito52mm.gif" alt="Image description" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Me: I haven't received any error or task failure notifications!&lt;/p&gt;

&lt;p&gt;Boss: It's doesn't matter! Fix it!!&lt;/p&gt;

&lt;p&gt;Me: Yes, sir! For now, I have manually run the task for today!!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After work&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Me: I wonder why it didn't run. Let's take a look at CloudTrail...ECS tasks are launched via the RunTask API, so let's search for the event name RunTask...&lt;/p&gt;

&lt;p&gt;Me: There it is. And the reason for the failure is...?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"failures"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"arn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:ecs:ap-northeast-1:xxx:container-instance/xxx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AGENT"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Me: The reason is...AGENT?&lt;/p&gt;
&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;Ever heard of the saying, 'You can't stop the waves, but you can learn to surf'?&lt;br&gt;
Well, in my case, the 'waves' were task failures in an ECS on EC2 environment and 'learning to surf' involved a lot of head-scratching, frantic Googling, and, ultimately, a date with CloudFormation Templates and Step Functions.&lt;br&gt;
This post is a chronicle of my 'surfing' lessons: the struggles I faced and how I eventually tamed the 'waves'.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Root Cause
&lt;/h2&gt;

&lt;p&gt;In an ECS on EC2 environment, there are three patterns of failure for scheduled tasks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Failure due to a program: This happens when a task fails due to an error in the program. If there is a stack trace in the standard output of the task indicating a program error, this is the case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Failure due to task settings: This represents situations like insufficient memory. If there is not enough memory to launch the ECS task and run the program, the task will terminate prematurely.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Failure due to an inability to launch the task: This is the problem this article is addressing. It occurs when the connection with the ECS Agent is lost, or when there isn't enough memory left on the EC2 itself to launch the task. This case is difficult to detect because the task ends without running.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As we focus on the third type of failure in this article, let's delve deeper into its root cause.&lt;/p&gt;

&lt;p&gt;On an EC2 running as a container instance, the ECS Agent is constantly active in order to communicate with ECS. However, this Agent is updated once every few hours, and if this timing overlaps with the launch of an ECS task, the operation results in an error. This is not due to a program error or an abnormal termination of the ECS task, but rather because it can't even board the EC2 in the first place.&lt;/p&gt;

&lt;p&gt;So, what's the best way to counter this issue?"&lt;/p&gt;
&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;Firstly, one possible solution is to interpose StepFunctions. &lt;br&gt;
This method is brilliant, as it allows for retries with StepFunctions via RunTask, and the changes are minimal. (While retries are possible with EventBridge Rules, it appears that it won't detect this particular case.)&lt;/p&gt;

&lt;p&gt;However, if many tasks are in operation, the cost of migrating all of them can be a bit high.&lt;/p&gt;

&lt;p&gt;Therefore, I thought about creating an infrastructure capable of detecting a failure to launch and retrying, and ended up creating the following CloudFormation Template 🎉&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/iisyos"&gt;
        iisyos
      &lt;/a&gt; / &lt;a href="https://github.com/iisyos/ecs_rerun_cfn"&gt;
        ecs_rerun_cfn
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/iisyos/ecs_rerun_cfnarchitect.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hwxxg8wR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/iisyos/ecs_rerun_cfnarchitect.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
ecs_rerun_cfn&lt;/h1&gt;
&lt;p&gt;This repository contains a CloudFormation stack to rerun ECS tasks on EC2 instances if they fail before reaching the EC2 instance. This typically occurs when the ECS Agent running on the EC2 instance is disconnected. You can refer to &lt;a href="https://docs.aws.amazon.com/en_us/AmazonECS/latest/developerguide/api_failures_messages.html" rel="nofollow"&gt;API failure reasons&lt;/a&gt; for a comprehensive list of reasons why the ECS API may fail, particularly the &lt;code&gt;RunTask&lt;/code&gt; or &lt;code&gt;StartTask&lt;/code&gt; actions.&lt;/p&gt;
&lt;h2&gt;
How it works&lt;/h2&gt;
&lt;p&gt;The stack creates the following resources:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;EventBridge (and rules)&lt;/li&gt;
&lt;li&gt;Step Functions&lt;/li&gt;
&lt;li&gt;SNS Topic&lt;/li&gt;
&lt;li&gt;Lambda Function&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And some IAM roles and policies.&lt;/p&gt;
&lt;p&gt;When an ECS API failure occurs, EventBridge catches the error and triggers the Step Functions. The Step Functions then notify the SNS Topic of the error, which triggers a Lambda Function to send a message to Slack. If the reason for the failure is AGENT, the task is retried up to three times.&lt;/p&gt;
&lt;h2&gt;
How to use&lt;/h2&gt;
&lt;p&gt;To create the stack, use the &lt;a href="https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/create/review?templateURL=https://s3.ap-northeast-1.amazonaws.com/cd-template-okamos/ecs_rerun_cfn/main.yml" rel="nofollow"&gt;quick-create links&lt;/a&gt;…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/iisyos/ecs_rerun_cfn"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--brWiBSlg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/surrwiv2hpjk46j5npa8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--brWiBSlg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/surrwiv2hpjk46j5npa8.png" alt="Image description" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(Right-side resources of the architecture diagram will be created. The repository also includes Terraform for creating left-side resources.)&lt;/p&gt;

&lt;p&gt;This template detects the failure of ECS task launch using EventBridge and uses Step Functions to retry the task.&lt;/p&gt;

&lt;p&gt;Unlike the previously mentioned infrastructure, you don't need to migrate all existing ECS tasks to this template. &lt;br&gt;
&lt;strong&gt;It attempts to retry only when the launch of a task fails.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Quick create link is here 💁‍♂️&lt;/p&gt;

&lt;p&gt;&lt;a href="https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/create/review?templateURL=https://s3.ap-northeast-1.amazonaws.com/cd-template-okamos/ecs_rerun_cfn/main.yml"&gt;https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/create/review?templateURL=https://s3.ap-northeast-1.amazonaws.com/cd-template-okamos/ecs_rerun_cfn/main.yml&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Template Description
&lt;/h2&gt;

&lt;p&gt;As shown in the architecture diagram, the Template creates the following resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EventBridge (and rules)&lt;/li&gt;
&lt;li&gt;Step Functions&lt;/li&gt;
&lt;li&gt;SNS Topic&lt;/li&gt;
&lt;li&gt;Lambda Function&lt;/li&gt;
&lt;li&gt;(And associated IAM Roles and Policies.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  EventBridge
&lt;/h3&gt;

&lt;p&gt;Firstly, we need to detect failure events. That's where EventBridge comes in. Here's a rule I created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"detail-type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"AWS API Call via CloudTrail"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"aws.ecs"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"responseElements"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"failures"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"exists"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"requestParameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"startedBy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"anything-but"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS Step Functions"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"eventSource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"ecs.amazonaws.com"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"eventName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"RunTask"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;I'll provide a simple explanation of this rule. 'anything-but' means negation, implying that ECS task events kicked by StepFunctions are excluded to avoid the risk of an infinite loop. In fact, I experienced an infinite loop during testing and had to hurriedly delete the resources...&lt;/p&gt;

&lt;p&gt;'exists' is a condition of existence, meaning in this case, it triggers when 'failures' are not an empty array.&lt;/p&gt;

&lt;p&gt;For more details, refer to the official document.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-event-patterns.html"&gt;https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-event-patterns.html&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step Functions
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ydb9Qqqg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1jnev75xgaccak95h38d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ydb9Qqqg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1jnev75xgaccak95h38d.png" alt="Image description" width="623" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SNS collaborates with Lambda and is used for Slack notifications. Check Reason verifies the cause of failure, and if it's AGENT, it attempts a retry.&lt;/p&gt;

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

&lt;p&gt;Batch programs play a crucial role in many applications. When their execution is interrupted, it can lead to major problems. In this article, we proposed a solution for when task execution on Amazon ECS fails due to an AGENT error.&lt;/p&gt;

&lt;p&gt;As a solution, we created a CloudFormation template to detect ECS launch failures and retry. We used EventBridge to detect failure events and Step Functions to restart tasks.&lt;/p&gt;

&lt;p&gt;Moreover, this method does not require migrating all existing ECS tasks, and it only attempts to retry when a task's launch fails, making it an easy-to-implement external resource.&lt;/p&gt;

&lt;p&gt;I hope this article will help you achieve reliable batch programs on Amazon ECS.😉&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ecs</category>
      <category>cloudformation</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Shipping Environment variables from AWS to Heroku</title>
      <dc:creator>okamos</dc:creator>
      <pubDate>Mon, 08 May 2023 13:09:48 +0000</pubDate>
      <link>https://dev.to/okamos102/shipping-environment-variables-from-aws-to-heroku-3i6a</link>
      <guid>https://dev.to/okamos102/shipping-environment-variables-from-aws-to-heroku-3i6a</guid>
      <description>&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;I built a GitHub Action that sets Heroku environment variables from the AWS SSM Parameter Store. This Action was created to efficiently synchronize environment variables when using both AWS and Heroku.&lt;/p&gt;

&lt;h3&gt;
  
  
  Category Submission:
&lt;/h3&gt;

&lt;p&gt;DIY Deployments&lt;/p&gt;

&lt;h3&gt;
  
  
  App Link
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/iisyos"&gt;
        iisyos
      &lt;/a&gt; / &lt;a href="https://github.com/iisyos/ssm-to-heroku-env-action"&gt;
        ssm-to-heroku-env-action
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h2&gt;
ssm-to-heroku-env-action&lt;/h2&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/iisyos/ssm-to-heroku-env-action./thumbnail.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WUfkl4Vp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/iisyos/ssm-to-heroku-env-action./thumbnail.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;GitHub Action that sets Heroku environment variables from AWS SSM Parameter Store
This Action was created to efficiently synchronize when using the same environment variables on AWS and Heroku.&lt;/p&gt;
&lt;h2&gt;
Inputs&lt;/h2&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;th&gt;Info&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;path&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;The path to the environment variable in the AWS SSM Parameter Store that you want to set in Heroku&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;email&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Heroku email&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;token&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Heroku token&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;app&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Heroku app name&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;And you need to set AWS credentials by using like &lt;a href="https://github.com/aws-actions/configure-aws-credentials"&gt;AWS Credentials for GitHub Actions&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
Description&lt;/h2&gt;
&lt;p&gt;First of all, this actions retrieve environment variables from AWS SSM Parameter Store specifying &lt;code&gt;path&lt;/code&gt; input. This mean when you set like under CLI command, you can retrieve under &lt;code&gt;'/test/'&lt;/code&gt;　recursively if you specified path as &lt;code&gt;'/test/'&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;aws ssm put-parameter \
    --name &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;/test/VALUE1&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt; \
    --value &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;test1&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt; \
    --type String \
    --region &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;ap-northeast-3&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Authentication…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/iisyos/ssm-to-heroku-env-action"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://github.com/marketplace/actions/ssm-to-heroku-env-action"&gt;marketplace&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;N/A&lt;/p&gt;

&lt;h3&gt;
  
  
  Description
&lt;/h3&gt;

&lt;p&gt;This action retrieves environment variables from the AWS SSM Parameter Store using the specified path input. For example, if you have set a parameter with the following CLI command and specified the path as '/test/', the action will retrieve the parameter stored under '/test/'.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ssm put-parameter &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"/test/VALUE1"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--value&lt;/span&gt; &lt;span class="s2"&gt;"test1"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--type&lt;/span&gt; String &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-3"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Authentication with Heroku is done by writing the &lt;code&gt;email&lt;/code&gt; and　&lt;code&gt;token&lt;/code&gt;　in the &lt;code&gt;.netrc&lt;/code&gt; file, as described in &lt;a href="https://devcenter.heroku.com/articles/authentication"&gt;Heroku CLI Authentication&lt;/a&gt;. You can get your token from &lt;a href="https://dashboard.heroku.com/account"&gt;here&lt;/a&gt;. Additionally, you need to set your app name in the &lt;code&gt;app&lt;/code&gt;　input.&lt;/p&gt;

&lt;h3&gt;
  
  
  Link to Source Code
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/iisyos/ssm-to-heroku-env-action"&gt;repository&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Permissive License
&lt;/h3&gt;

&lt;p&gt;MIT&lt;/p&gt;

&lt;h2&gt;
  
  
  Background (What made you decide to build this particular app? What inspired you?)
&lt;/h2&gt;

&lt;p&gt;Honestly, it was mainly about money. 🥺&lt;br&gt;
Initially, I had the application running on AWS, but the cost of maintaining it was a bit high, so I decided to switch to Heroku. However, there was still a possibility that I would use AWS in the future, so I stopped the resources without deleting them. As the application scales, the number of environment variables will grow, and managing them becomes a challenge. Since they were originally managed in the AWS SSM Parameter Store, migrating them would be cumbersome. Therefore, I decided to create an infrastructure with AWS as the master and Heroku as a reference.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I built it (How did you utilize GitHub Actions or GitHub Codespaces? Did you learn something new along the way? Pick up a new skill?)
&lt;/h3&gt;

&lt;p&gt;I learned how to authenticate Heroku by writing emails and tokens in the &lt;code&gt;.netrc&lt;/code&gt; file and the basics of AWS CLI.&lt;br&gt;
I also learned the application of Interface and Class in TypeScript.&lt;br&gt;
It was difficult to implement a generic interface.&lt;/p&gt;

</description>
      <category>githubhack23</category>
      <category>githubactions</category>
      <category>aws</category>
      <category>heroku</category>
    </item>
    <item>
      <title>#GitHubHack23: StarTweet</title>
      <dc:creator>okamos</dc:creator>
      <pubDate>Wed, 03 May 2023 13:05:31 +0000</pubDate>
      <link>https://dev.to/okamos102/githubhack23-startweet-5e87</link>
      <guid>https://dev.to/okamos102/githubhack23-startweet-5e87</guid>
      <description>&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;StarTweet is a GitHub Action that sends a thank you tweet to users who star your GitHub repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  Category Submission:
&lt;/h3&gt;

&lt;p&gt;Wacky Wildcards&lt;/p&gt;

&lt;h3&gt;
  
  
  App Link
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/iisyos/star_tweet"&gt;repository&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/marketplace/actions/star-tweet"&gt;marketplace&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U1N1KMTt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z9wki43z6xfeqxck7lbv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U1N1KMTt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z9wki43z6xfeqxck7lbv.png" alt="Image description" width="593" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Description
&lt;/h3&gt;

&lt;p&gt;This action sends a thank you tweet to users who star your GitHub repository. It aims to appreciate and engage with your community on Twitter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Link to Source Code
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/iisyos/star_tweet"&gt;https://github.com/iisyos/star_tweet&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Permissive License
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://choosealicense.com/licenses/mit/"&gt;MIT License&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Background (What made you decide to build this particular app? What inspired you?)
&lt;/h2&gt;

&lt;p&gt;I built this GitHub Action to create a more engaging and personal experience for people who support your projects. When users star my repositories, I wanted to show them my appreciation and start a conversation on Twitter.&lt;br&gt;
I hope that this action will encourage communication among engineers around the world.😉&lt;/p&gt;

&lt;h3&gt;
  
  
  How I built it (How did you utilize GitHub Actions or GitHub Codespaces? Did you learn something new along the way? Pick up a new skill?)
&lt;/h3&gt;

&lt;p&gt;I use this template (&lt;a href="https://github.com/actions/typescript-action).It"&gt;https://github.com/actions/typescript-action).It&lt;/a&gt;' easy to start GitHub Action for TS engineer.&lt;br&gt;
While building this GitHub Action, I learned how to work with the Twitter API and how to effectively use webhooks to create automated workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Resources/Info
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/rest?apiVersion=2022-11-28"&gt;GitHub REST API documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.twitter.com/en/docs"&gt;Twitter API Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>githubhack23</category>
      <category>twitter</category>
      <category>githubactions</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Simple Action: YAML Replacement</title>
      <dc:creator>okamos</dc:creator>
      <pubDate>Wed, 03 May 2023 02:26:28 +0000</pubDate>
      <link>https://dev.to/okamos102/placeholder-title-1ceh</link>
      <guid>https://dev.to/okamos102/placeholder-title-1ceh</guid>
      <description>&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;I build a GitHub Action called "YAML Replacement"  that allows you yto replace specific values in a YAML file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Category Submission:
&lt;/h3&gt;

&lt;p&gt;Wacky Wildcards&lt;/p&gt;

&lt;h3&gt;
  
  
  App Link
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/iisyos/yaml-replacement-action"&gt;Repository&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/marketplace/actions/yaml-replacement"&gt;Marketplace&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;N/A&lt;/p&gt;
&lt;h3&gt;
  
  
  Description
&lt;/h3&gt;

&lt;p&gt;When you want to update a file cached in the browser, you change the URL of the file, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"production.min.js?ver=1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"production.min.js?ver=2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tails of url is often managed in YAML file. So when you deploy application, you need update the phrase 1 to 2. This action update the phrase to current date formatted YYYYMMDDhhmm.&lt;/p&gt;

&lt;p&gt;The version number at the end of the URL is often managed in a YAML file. So, when you deploy your application, you need to update the version number from 1 to 2. This action updates the version number to the current date formatted as YYYYMMDDhhmm.&lt;/p&gt;

&lt;h3&gt;
  
  
  Link to Source Code
&lt;/h3&gt;

&lt;p&gt;You can find the source code for the YAML Replacement action on GitHub: &lt;a href="https://github.com/iisyos/yaml-replacement-action"&gt;https://github.com/iisyos/yaml-replacement-action&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Permissive License
&lt;/h3&gt;

&lt;p&gt;This action is released under the MIT License.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background (What made you decide to build this particular app? What inspired you?)
&lt;/h2&gt;

&lt;p&gt;I decided to build GitHub Action because I often encountered scenarios where I needed to update the version number in a YAML file when deploying applications for updating browser cached files or just maintaining versions. Manually updating the version number was time-consuming and error-prone, so I wanted to automate this process to improve efficiency and accuracy.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I built it (How did you utilize GitHub Actions or GitHub Codespaces? Did you learn something new along the way? Pick up a new skill?)
&lt;/h3&gt;

&lt;p&gt;I built the YAML Replacement action using JavaScript and the GitHub Actions framework. The action takes inputs such as the path to the YAML file, the target key of the value to be replaced, and an optional flag indicating whether the changes should be pushed.&lt;/p&gt;

&lt;p&gt;During the execution of the action, it reads the YAML file, identifies the target key, and replaces the corresponding value with the current date formatted as YYYYMMDDhhmm. If the "need-push" flag is set to true, the action commits and pushes the changes to the repository.&lt;/p&gt;

&lt;p&gt;Along the way, I gained a deeper understanding of GitHub Actions, because it was my first time building actions😉.&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Resources/Info
&lt;/h3&gt;

&lt;p&gt;N/A&lt;/p&gt;

</description>
      <category>githubhack23</category>
      <category>github</category>
      <category>githubactions</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
