<?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: Sydney Schreckengost</title>
    <description>The latest articles on DEV Community by Sydney Schreckengost (@sydneybrokeit).</description>
    <link>https://dev.to/sydneybrokeit</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%2F101763%2F79454d56-b22c-4fd5-a3f0-204e2da59f62.jpg</url>
      <title>DEV Community: Sydney Schreckengost</title>
      <link>https://dev.to/sydneybrokeit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sydneybrokeit"/>
    <language>en</language>
    <item>
      <title>Getting Started with goreleaser</title>
      <dc:creator>Sydney Schreckengost</dc:creator>
      <pubDate>Wed, 09 Sep 2020 06:26:29 +0000</pubDate>
      <link>https://dev.to/sydneybrokeit/getting-started-with-goreleaser-5672</link>
      <guid>https://dev.to/sydneybrokeit/getting-started-with-goreleaser-5672</guid>
      <description>&lt;p&gt;One of the best parts of Go is that you can get a single binary for a given platform that can then be deployed without much fuss.  Of course, this simplicity exposes another issue - doing all those builds is maybe a little finicky and it's hard to make a cross-platform way to do all of them at once, and then you have to release them on GitHub, and it's, ugh, a mess.&lt;/p&gt;

&lt;p&gt;I started using &lt;code&gt;goreleaser&lt;/code&gt; for my newest project &lt;a href="https://github.com/hmschreck/goad"&gt;goad&lt;/a&gt;, a load-testing tool that I tried to mimic as much of the interface of &lt;code&gt;curl&lt;/code&gt; as possible.&lt;/p&gt;

&lt;p&gt;It's a good system, I think, though it does have a few peculiarities that might limit it for a narrow range of uses, but we'll get into that later.&lt;/p&gt;

&lt;h1&gt;
  
  
  Installing goreleaser
&lt;/h1&gt;

&lt;p&gt;Since it's written in Go, goreleaser is distributed as a single binary, so we have a few options for installation.&lt;/p&gt;

&lt;h2&gt;
  
  
  MacOS
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;brew install goreleaser/tap/goreleaser&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  MacOS/Linux
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;brew install goreleaser&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This may be an out of date version, according to the documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Linux
&lt;/h2&gt;

&lt;p&gt;goreleaser is also available as a &lt;code&gt;.deb&lt;/code&gt; or &lt;code&gt;.rpm&lt;/code&gt; package for whatever distribution you might be on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manually
&lt;/h2&gt;

&lt;p&gt;This option works for everything.  Go to the &lt;a href="https://github.com/goreleaser/goreleaser/releases"&gt;releases page for goreleaser&lt;/a&gt; and download the appropriate file for your system.  Extract it, and place the &lt;code&gt;goreleaser&lt;/code&gt; binary (or &lt;code&gt;goreleaser.exe&lt;/code&gt; on Windows) somewhere in your &lt;code&gt;PATH&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Initializing goreleaser
&lt;/h1&gt;

&lt;p&gt;Once you've installed goreleaser, you need to initialize it for each project you want to use it on.&lt;/p&gt;

&lt;p&gt;Navigate to a project you want to manage using goreleaser, and run&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;goreleaser init&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;After this, you will have a file called &lt;code&gt;.goreleaser.yml&lt;/code&gt;.  This gives us a basic configuration.  This will only do GitHub releases, but it does them really cleanly, and it gives us a skeleton to flesh out later.&lt;/p&gt;

&lt;h1&gt;
  
  
  Adding a GitHub token
&lt;/h1&gt;

&lt;p&gt;Next, we need to give goreleaser a GitHub token to use to access our release uploads.  You can create a new token &lt;a href="https://github.com/settings/tokens/new"&gt;here&lt;/a&gt; if you're signed in.  You'll need to give it the "repo" permissions.  Name the token something useful (like &lt;code&gt;goreleaser&lt;/code&gt;, etc), and copy the value you're given.  &lt;em&gt;Make sure you don't lose this&lt;/em&gt;, because once this value stops being displayed, you can't get it again.&lt;/p&gt;

&lt;p&gt;Now, however it works for your environment, add this token value to your environment variables with the name &lt;code&gt;GITHUB_TOKEN&lt;/code&gt;.  On a temporary basis on Linux or MacOS, you can use &lt;code&gt;export GITHUB_TOKEN=token_string&lt;/code&gt; from your command line.&lt;/p&gt;

&lt;h1&gt;
  
  
  Enable go modules
&lt;/h1&gt;

&lt;p&gt;goreleaser really expects you to be using modules, which were introduced in Go 1.11, and are a default in Go 1.13 on.  You may need to run &lt;code&gt;export GO111MODULE=on&lt;/code&gt; to do this.&lt;/p&gt;

&lt;p&gt;If your project isn't already using them, be sure to initialize the module system using &lt;code&gt;go mod init&lt;/code&gt;.  This will generate a go.mod and go.sum file.  Make sure these are committed to your repo!&lt;/p&gt;

&lt;h1&gt;
  
  
  Clean up your repo
&lt;/h1&gt;

&lt;p&gt;By default, goreleaser will stop if the git repo is anything other than strictly clean - that means no untracked files, no differences in tracked files.  The first few times you do this, you will probably need to add things to your &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Tag the release
&lt;/h1&gt;

&lt;p&gt;Goreleaser uses &lt;a href="https://semver.org/"&gt;semver&lt;/a&gt; for versioning, so make sure your version tags are in line with that.  &lt;em&gt;It will fail if you are not following semver!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Just need to run&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;git tag x.y.z&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 to complete tagging.&lt;/p&gt;

&lt;h1&gt;
  
  
  Run goreleaser
&lt;/h1&gt;

&lt;p&gt;From here, we can run &lt;code&gt;goreleaser&lt;/code&gt; as a command, and it will build the project, update our releases on GitHub.  That's it!  We now have our releases completely automated!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sFV4xp53--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mn6jpun1nscqd7wj9t9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sFV4xp53--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mn6jpun1nscqd7wj9t9v.png" alt="Annotation 2020-09-09 012247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Goreleaser's limitations
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Some people may not like that it requires semver.  I know there are some cases where semver is possible but at best a hack.&lt;/li&gt;
&lt;li&gt;If you're using older Go versions, you may not want to switch your code to a newer Go that supports modules.  While code should Just Work, that's not always guaranteed.&lt;/li&gt;
&lt;li&gt;There are lots of options, and you may overwhelm yourself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, I've been liking goreleaser.  It's made one of my biggest loves of Go even easier to tag advantage of, and it's highly configurable, support homebrew formulas, Docker, and plenty more.  If you're in charge of a Go project, definitely &lt;a href="https://goreleaser.com/"&gt;check it out&lt;/a&gt;! &lt;/p&gt;

</description>
      <category>go</category>
    </item>
    <item>
      <title>The Platypus</title>
      <dc:creator>Sydney Schreckengost</dc:creator>
      <pubDate>Fri, 10 May 2019 22:45:04 +0000</pubDate>
      <link>https://dev.to/sydneybrokeit/the-platypus-ppd</link>
      <guid>https://dev.to/sydneybrokeit/the-platypus-ppd</guid>
      <description>&lt;p&gt;I'm usually an "evolution over revolution" sort when it comes to systems.  I don't like make big sweeping changes - they tend to break things, they tend to have a really big "blast radius", and so on.&lt;/p&gt;

&lt;p&gt;But evolutionary systems tend to have the same problems that natural evolution has.&lt;/p&gt;

&lt;p&gt;Sometimes, evolution creates a platypus. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CEnu7GVz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://upload.wikimedia.org/wikipedia/commons/f/f2/Platypus_BrokenRiver_QLD_Australia.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CEnu7GVz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://upload.wikimedia.org/wikipedia/commons/f/f2/Platypus_BrokenRiver_QLD_Australia.jpg" alt="platypus"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Look at it.  Just-- Just &lt;em&gt;look at it&lt;/em&gt;.  Its existence is a mystery - it has a bill; it lays eggs; it swims around; it has poisonous claws.  And it's a mammal.  None of those things make any sort of sense.  But somehow, somewhere, those things made it when tons of other species didn't.  At some point, the environment was such a way that a platypus was better suited to survival than other species, or at least not so bad that it killed them off.&lt;/p&gt;

&lt;p&gt;When you work on an evolving system, you will eventually find a system that you just stare at blankly, nod your head, and wander off, because its very existence makes no sense. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ve4btTz1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgflip.com/30o0ag.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ve4btTz1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgflip.com/30o0ag.jpg" alt='Jackie Chan WTF: "Why does this thing even exist?  What possible collection of forces could have possibly led to this?"'&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a platypus system.  No matter how much we try to understand why it exists, we never really will.  It probably does things that no other system of its kind does, and we're not sure why; maybe it's a mail system that also plays chess, and no one quite understands why.&lt;/p&gt;

&lt;p&gt;So what should we do with these types of systems?  Look, your guess is as good as mine.  I'm fine trying to make them extinct.  Mammals shouldn't have bills, and an HTTP server should't have a roguelike in the logs.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>architecture</category>
    </item>
    <item>
      <title>DevOps is Culture, Not Cargo</title>
      <dc:creator>Sydney Schreckengost</dc:creator>
      <pubDate>Wed, 02 Jan 2019 06:27:12 +0000</pubDate>
      <link>https://dev.to/sydneybrokeit/devops-is-culture-not-cargo-2lo7</link>
      <guid>https://dev.to/sydneybrokeit/devops-is-culture-not-cargo-2lo7</guid>
      <description>&lt;p&gt;"Hey, we need start doing this thing I read about."  Some of you have probably heard that at some point.  Depending on who was talking to you, it can usually be one of two reactions: "This is just great!  We can finally make some real improvements!" or "This is just great.  We have another stupid thing to add to our graveyard of half-thoughts."&lt;/p&gt;

&lt;p&gt;One of the hardest sets of lessons to learn is around selecting tooling; knowing how to make the best use of your toolbox, and when it's time to invest in a new tool, and how to push for the right (or better) tooling, can be difficult.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Right Tool for the Right Job
&lt;/h1&gt;

&lt;p&gt;For most problems, there are multiple ways of solving it.  Selecting the right tool is important - selecting the wrong tool means you're going to be slower, less effective, and you're going to end up with a worse product.  Selecting the right tool for your problem is a well-studied problem, and your methodologies will vary from team to team.&lt;/p&gt;

&lt;p&gt;What a lot of people miss is the core question: what's the right problem to solve?  This is the most important question to ask, through every step of a process as complex as software design.  If you solve the wrong problem perfectly, you've still solved the wrong problem, and you haven't made any real progress; solve the right problem in a minimal way, and you can bootstrap that into something bigger and better.&lt;/p&gt;

&lt;p&gt;When you're looking at a problem, start by stepping back and understanding why it's a problem; from there, keep working your way back, and eventually you'll find the real problem you're trying to solve.&lt;/p&gt;

&lt;p&gt;For example, some time ago I was asked to figure out how to make a certain process able to be deployed without incurring any downtime.  This is a large process, and while I knew what problem I was trying to solve on the surface - making this process work through deployments.  By digging deeper, I was able to look at the real problem: requiring a complete restart in order to make changes to this process meant that making changes happened at a glacial pace, because it could only be restarted during off hours.&lt;/p&gt;

&lt;p&gt;Not only did this question help me make better decisions on this project, but it has informed my decision-making moving forward; when I have to make a choice in the midst of a project, I am able to make the best decisions moving forward in a general sense.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Should We Aim For?
&lt;/h1&gt;

&lt;p&gt;When it comes to DevOps, our tooling doesn't matter so much as understanding what our goals are.&lt;/p&gt;

&lt;p&gt;I tend to break the general goals for doing DevOps into three large goals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce risk&lt;/li&gt;
&lt;li&gt;Increase velocity&lt;/li&gt;
&lt;li&gt;Reduce toil&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these intertwine heavily; a lot of things that reduce toil reduce risk; a lot of things that increase velocity reduce toil, and so on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reduce Risk
&lt;/h2&gt;

&lt;p&gt;It's 4:58 on Friday afternoon, and the developers have a change to make before the weekend.  What do we do here?  If we don't push, the devs get mad because they're being held back; if we do push and it fails, we may have just thrown away a weekend for everyone who has to fix it.&lt;/p&gt;

&lt;p&gt;Part of what we should be doing is our risk; if a deployment needs to happen at 4:58 on a Friday afternoon, we want to know it will work.  There are multiple ways of doing this, but the important thing is this: when we look at the problem of how to handle a deployment at 4:58 on a Friday afternoon, what we're looking at is how to make something less risky.  Whether we make the software itself less risky, or the deployment process, or our environment, our real end goals are the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Increase Velocity
&lt;/h2&gt;

&lt;p&gt;A developer has spent a week implementing a feature; now, it needs to be integrated into the main branch and deployed.  Sometimes, this is easy; sometimes, it can take as long, or even longer, as the actual development.&lt;/p&gt;

&lt;p&gt;What can we do to make this process faster?  What can we to do completely eliminate the need to spend extra time mushing codebases back together after a divergence?  What can be done to make it so that our developers can work faster and more effectively?&lt;/p&gt;

&lt;h2&gt;
  
  
  Reduce Toil
&lt;/h2&gt;

&lt;p&gt;Every day at 9 AM, you have to restart some service or it will fail.  If you don't, your entire infrastructure may fail.  If you get sick, or forget to do it, or even just get busy at that exact moment, congrats - you're service is down.  Even though it's only 2 minutes a day, it adds up, and the context switching can be brutal.  It's busywork.  It's &lt;em&gt;toil&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When we reduce the amount of work we need to do in order to do something, we are multiplying our effort; now, we don't have to handle this, we don't have to watch the clock, we don't have to touch it at all.  This does a few things for us - when we have fewer things to worry about, we don't have to spend time on them, and we don't feel as exhausted.&lt;/p&gt;

&lt;p&gt;We can do this in two ways - removing things that don't need to be done (for example, is the service that needs to be restarted every morning broken?  Let's fix it, removing the need to do it at all) and automating what's left.&lt;/p&gt;

&lt;h1&gt;
  
  
  Culture Over Cargo
&lt;/h1&gt;

&lt;p&gt;So what does real DevOps look like?  It's not about using certain tools, it's about asking the questions to make the best decisions to help us reduce risk, increase velocity, and reduce toil.&lt;/p&gt;

&lt;p&gt;When we are able to ask these questions and really focus on what matters to making things better, not only do we get to start making products better, faster, but we're less frustrated, we're more reliable, and we can start making the right tool choices even in new circumstances.  Tooling isn't what matters when it comes down to it -- knowing where you want to be is.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>culture</category>
      <category>management</category>
      <category>leadership</category>
    </item>
    <item>
      <title>Building a super cheap transcoder using AWS Lambda</title>
      <dc:creator>Sydney Schreckengost</dc:creator>
      <pubDate>Tue, 18 Dec 2018 03:41:49 +0000</pubDate>
      <link>https://dev.to/sydneybrokeit/building-a-super-cheap-transcoder-using-aws-lambda-1j76</link>
      <guid>https://dev.to/sydneybrokeit/building-a-super-cheap-transcoder-using-aws-lambda-1j76</guid>
      <description>&lt;p&gt;Have you ever looked at the price of Amazon's Elastic Transcoder?  If you haven't I'll spare you the lookup - it's 3 cents (USD) per minute of video transcoded, if the video is considered "HD".  If you have a handful of videos, or you need a lot of flexibility, Elastic Transcoder is pretty cool.&lt;/p&gt;

&lt;p&gt;Just one problem - if that's not your use case, Elastic Transcoder can get really expensive.  For example, the company I work for processes hundreds of thousands of videos every month, and our needs are very simple - we need to turn a specific type of video into a different specific type of video.  This is all we need to do, nothing more and nothing less.&lt;/p&gt;

&lt;p&gt;Using Elastic Transcoder, our average monthly bill is high enough to really worry about.  While there's no reason not to use the right tool for the job, Elastic Transcoder is overkill for our needs.&lt;/p&gt;

&lt;p&gt;After this is done, we'll have a usable, cheap transcoder that we can use.  While this does have some limitations, it is still very cost-effective for what it's good for, and understanding this can help understand a lot of really interesting aspects of using S3 and Lambda.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating our Lambda function
&lt;/h1&gt;

&lt;p&gt;First, we need to create the Lambda function that we will be using.  Log in to AWS, and navigate to Lambda.  Click &lt;code&gt;Create Function&lt;/code&gt; and create your function.  Any language with the ability to call system commands should work fine, though I used Go here because, well, I like it.  It's that simple, it doesn't provide a major advantage here.&lt;/p&gt;

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

&lt;p&gt;Name your transcoder, select a language, and create a custom role - if you're not familiar with AWS, this part might get confusing.  Something like this should be right for your custom role, if you're looking to get started:&lt;/p&gt;

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

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObjectAcl",
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:GetBucketAcl",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::testBucketName",
                "arn:aws:s3:::testBucketName/*"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:HeadBucket",
            "Resource": "*"
        }
    ]
}


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

&lt;/div&gt;

&lt;p&gt;In the above example, note that you do need both &lt;code&gt;testBucketName&lt;/code&gt; and &lt;code&gt;testBucketName/*&lt;/code&gt; - one set of the policies is for the bucket itself, the other is the files themselves.&lt;/p&gt;

&lt;h1&gt;
  
  
  Coding our function
&lt;/h1&gt;

&lt;p&gt;After we've created the function, we need to tell it how to operate.  This will vary from language to language, but the general gist is like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download the existing file from S3.  The filename and bucket are sent in as part of a an S3 Event in most cases, depending on the library used. 
As a side note on this, because of the way Lambda works, make sure you have a unique identifier for the video, or you can end up with weird errors.  Go on, ask me how I know.&lt;/li&gt;
&lt;li&gt;Transcode using ffmpeg - we'll make use of a newer feature to make this simple and portable across any function we might need ffmpeg for.  For now, just expect to use &lt;code&gt;/opt/ffmpeg/ffmpeg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Upload the video to S3.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's really about it. This will vary from language to language, but AWS fortunately provides pretty usable documentation for this.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting up S3 events
&lt;/h1&gt;

&lt;p&gt;Now that we've written our function, the last major thing we need to do is set up S3 to actually send events to Lambda.&lt;/p&gt;

&lt;p&gt;Go to the S3 bucket you want to use, and click "Properties", and under "Advanced", click "Events".  Now click "Add Notification", and select the object actions that should trigger a transcode (most likely "All Object Create Events").&lt;/p&gt;

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

&lt;p&gt;If there are specific folders you want to include, that can go into &lt;code&gt;prefix&lt;/code&gt;; if you are looking for a specific extension, set that in the &lt;code&gt;suffix&lt;/code&gt;.  Click the dropdown for &lt;code&gt;Send To&lt;/code&gt;: and select "Lambda Function".  Another dropdown will be created; in here, select the function you created previously.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating a layer
&lt;/h1&gt;

&lt;p&gt;Layers are &lt;code&gt;.zip&lt;/code&gt; files that are included in the filesystem of a Lambda function.  In this case, we are using a statically compiled (that is, it doesn't require anything outside the binary, generally speaking) version of ffmpeg.  You can find the one I used here:  &lt;a href="https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz" rel="noopener noreferrer"&gt;https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz&lt;/a&gt;.  Extract this, and you should get an ffmpeg directory; add this to a zip file.&lt;/p&gt;

&lt;p&gt;Go to your Lambda function, and under the code part at the top of a tree, click "Layers".&lt;/p&gt;

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

&lt;p&gt;Click "Add Layers" and upload the zip file containing ffmpeg.  Attach it to the function, and you're done.&lt;/p&gt;

&lt;h1&gt;
  
  
  Done!
&lt;/h1&gt;

&lt;p&gt;Mostly, at least.  Some minor changes to make here and there once it's up, and it can take a little while to figure out the right way to do this in a given language.&lt;/p&gt;

&lt;p&gt;When a video gets uploaded, it will be sent to the Lambda function, which will then transcode it and upload it.&lt;/p&gt;

&lt;p&gt;This project was designed as part of a way to reduce costs, so let's take a look at that aspect.&lt;/p&gt;

&lt;p&gt;A 10-minute video in this setup takes about 105 seconds to transcode.  With Lambda, we can give it more RAM to work with, and for longer or higher resolution videos we absolutely do need more; I have our current configuration set to 1280MB.&lt;/p&gt;

&lt;p&gt;If our transcoder takes 1280MB and 105 seconds, we can easily calculate our cost to transcode a 10-minute video:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$0.00001667 * (1280/1024)&lt;/code&gt; gives us our cost to run the function for a second.  This works out to ~$0.000021 per second.  Multiplying this by 105, the run-time, gives us a figure of $0.0022.  Keep in mind, that with Elastic Transcoder, a 10-minute video would be $0.30.  This means that our transcoder, running on Lambda, can provide a greater than 99% discount over Elastic Transcoder.&lt;/p&gt;

&lt;p&gt;This does have some limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This will work much better on shorter videos; due to the run time limitation on Lambda, I doubt anything over 45 minutes to an hour is worth transcoding this way.&lt;/li&gt;
&lt;li&gt;Longer videos will require more RAM, so the savings do drop a little bit - but even with the RAM maxed out to 4GB, it's still 97+% cheaper than Elastic Transcoder.&lt;/li&gt;
&lt;li&gt;It is not very flexible - though this can be overcome with a little creativity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For our needs, this is perfect, but remember that all engineering is knowing your constraints and getting the best for what you have.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>functions</category>
      <category>scaling</category>
    </item>
  </channel>
</rss>
