One place for hosting & domains

      Explained

      Infrastructure as Code Explained


      Introduction

      Cloud computing provides on-demand computing resources, which are decoupled from physical hardware and necessary underlying configuration. Autonomous software systems provision these computing resources in the cloud to achieve the automation that cloud computing offers. Because of such automation, it’s possible to control and manipulate the available resources programmatically by interfacing with the cloud providers. This way, infrastructure changes (such as resource scaling) can be implemented more quickly and reliably and operated mostly without manual interaction, but still with the ability to oversee the whole process and revert changes if something does not go according to plan.

      Infrastructure as Code (IaC) is the approach of automating infrastructure deployment and changes by defining the desired resource states and their mutual relationships in code. The code is written in specialized, human-readable languages of IaC tools. The actual resources in the cloud are created (or modified) when you execute the code. This then prompts the tool to interface with the cloud provider or deployment system on your behalf to apply the necessary changes, without using a cloud provider’s web interface. The code can be modified whenever needed—upon code execution the IaC tool will take care of finding the differences between the desired infrastructure in code and the actual infrastructure in the cloud, taking steps to make the actual state equal to the desired one.

      For IaC to work in practice, created resources must not be manually modified afterward (an immutable infrastructure), as this creates discord between the expected infrastructure in code and the actual state in the cloud. In addition, the manually modified resources could get recreated or deleted during future code executions, and all such customization would be lost. The solution to this is to incorporate the modifications into the infrastructure code.

      In this conceptual article, we’ll explore the IaC approach, its benefits, and examples of real-world implementations. We’ll also introduce Terraform, an open source IaC provisioning tool. We’ll review Terraform’s role in this approach and how it compares to other IaC tools.

      Benefits of IaC

      With IaC, you can quickly create as many instances of your entire infrastructure as you need, in multiple provider regions, from a single source of truth: your declarative code. This has many advantages that ensures you’re creating resources consistently without error while reducing management and manual setup time.

      The main benefits of IaC are:

      • Deployment: removing the manual provisioning interaction with cloud providers means a quicker deployment speed.
      • Recovery: identifying issues in the configuration can mean quick recovery from failures.
      • Consistency: deploying resources are the same each time, resolving infrastructure fragility.
      • Modification: modifying resources can have a quick turnaround time.
      • Reusability: reusing parts of the infrastructure architecture in future projects.
      • Version Control: storing the infrastructure code in version control systems.
      • Visibility: writing configuration as code acts as documentation for the infrastructure.

      Within an IaC workflow you can repeatedly spin up infrastructure in a standardized fashion, which means software development and testing is a quicker process because development, staging, quality-assurance testing, and production environments are separated. You can repeat the process of writing code and testing it live by deploying the infrastructure as many times as needed. Once your written infrastructure fulfills all requirements, you can deploy it in desired cloud environments. When new requirements arise, you can reiterate the process.

      General IaC Workflow

      IaC, being based on code, should always be coupled with version control software (VCS), such as Git. Storing your infrastructure declarations in VCS makes it easily retrievable, with changes visible to everyone on your team, and provides snapshots at historical points, so you can always roll back to an earlier version if new modifications create errors. Advanced VCS can be configured to automatically trigger the IaC tool to update the infrastructure in the cloud when an approved change is added.

      You now know what the IaC approach is, and what benefits it brings. You’ll now learn about states, the resource tracking mechanism employed in IaC. Then, you’ll follow up with the role of Terraform and other tools using IaC.

      What is ‘state’?

      In an IaC environment, the term ‘state’ refers to the state of affairs of desired infrastructure resources in a deployment. There are at least three states at a given moment: the actual one in the cloud, the ideal state presented in code, and the cached state that the IaC tool maintains. The cached state describes the state in the cloud as it was when the code was last executed. Terraform allows you to deploy the same code multiple times, forming multiple states for each deployment.

      How State is Changed

      The actual state in the cloud (of the managed resources) should always be the same as the cached state of the tool. When executing the code, the tool will compare the ideal state with the cached one and apply the detected differences to the cloud. If the cached and actual states do not match, it’s highly likely that the execution will fail or that resources will be incorrectly provisioned.

      Role of Terraform in IaC

      Terraform is an open source IaC resource provisioning tool, written in Go and developed by Hashicorp. It supports multiple cloud providers, including DigitalOcean. The infrastructure definitions are written in the Hashicorp Configuration Language (HCL), and source code files written in it have the file extension tf.

      Terraform works by reading the code describing your infrastructure and generating a graph containing all resources with their mutual relationships. It then compares it to the cached state of the resources in the cloud, and prepares an execution plan that details what will be applied to the cloud, and in what order, to reach the desired state.

      The two main types of underlying components in Terraform are providers and provisioners. Providers are responsible for interacting with a given cloud provider, creating, managing, and deleting resources, while provisioners are used to execute specific actions on created remote resources or the local machine the code is executing on.

      Terraform supports managing basic cloud provider components, such as compute instances, load balancers, storage, and DNS records, though more providers and provisioners can be added, owing to its extensible nature.

      In IaC Terraform’s role is to ensure that the state of resources in the cloud is equal to the state expressed in code. It does not monitor the deployed resources, and its main focus is not on further bootstrapping of the provisioned compute instances with software and tasks. In the next section, you’ll learn how it compares to other tools and how they extend each other in a typical workflow.

      The IaC approach is widespread in modern deployment, configuration management, virtualization, and orchestration software. Docker and Kubernetes, the leading tools used for container creation and orchestration, both use YAML as their language for declaring the desired end result. On the other hand, Hashicorp Packer, a tool for creating snapshots of deployments, uses JSON to declare the template and variables from which a snapshot of the system will be built.

      Ansible, Chef, and Puppet, the three most popular configuration management tools, all use the IaC approach to define the desired state of the servers they manage.

      Ansible bootstraps provided servers according to a given playbook. A playbook is a textual file written in appropriate YAML, instructing Ansible what operations to perform on the existing target resources. Examples of such operations include running and starting services, installing packages using the system-provided package manager, or executing custom bash commands. To learn more about writing Ansible playbooks, read Configuration Managment 101: Writing Ansible Playbooks.

      Chef and Puppet both require central servers with agents installed on each of the managed ones. Unlike Ansible, Chef uses Ruby, and Puppet uses its own declarative language for describing the resources.

      Terraform is not mutually exclusive with other IaC tools and DevOps systems. Its strength is in provisioning hardware resources, rather than further software installation and initial server setup.

      Unlike configuration management tools such as Ansible and Chef, Terraform is not suitable for installing software on the target resources and setting up tasks. Instead Terraform offers providers for interacting with their supported resources.

      Terraform can work from a single machine and does not require central servers with client agents installed on the provisioned resources, unlike some other tools. It does not check their actual state and reapplies the configuration automatically, because its main focus is on provisioning them. A typical workflow is to provision the infrastructure resources using Terraform and then bootstrap them using a configuration management tool, if needed.

      For Chef, Terraform has a built-in provisioner that sets up its client agent on provisioned remote resources. With it you can automatically have all your provisioned servers added to the main server, from where you can additionally configure them using cookbooks, Chef’s infrastructure declarations. You can learn more about writing them in Configuration Management 101: Writing Chef Recipes.

      Conclusion

      This article covered the paradigms of the IaC approach, its advantages over traditional manual system administration, the basics of Terraform as an IaC resource provisioning tool, and how it compares to other popular infrastructure automation tools.

      If you’re looking to incorporate Infrastructure as Code into your workflow, check out our Terraform series to learn the fundamentals of using this tool in your development and deployment process.

      One way to start with Terraform is to read How To Structure Your Terraform Project to understand how to ensure your infrastructure stays scalable and extensible.



      Source link

      CSS Units Explained


      While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or
      edited it to ensure you have an error-free learning experience. It’s on our list, and we’re working on it!
      You can help us out by using the “report an issue” button at the bottom of the tutorial.

      Introduction

      CSS has several options for which units to use when determining the size of various CSS properties. Learning all your options for CSS units can be key for styling in a way that’s easy to manage and looks great on any screen.

      What is a CSS Unit?

      A CSS unit determines the size of a property you’re setting for an element or its content. For example, if you wanted to set the property margin of a paragraph, you would give it a specific value. This value includes the CSS unit.

      Let’s look at a small example:

      p {
        margin: 20px;
      }
      

      In this case, margin is the property, 20px; is the value, and px (or “pixel”) is the CSS unit.

      Even though it’s common to see units like px used, the big question is often, “What’s the best unit to use here?”

      Here are some considerations to make when picking a unit type, and example use cases:


      Absolute vs. Relative Units

      When considering all the options for which units to use, it’s important to consider the two categories of units: absolute and relative.

      Absolute Units

      Units that are “absolute” are the same size regardless of the parent element or window size. This means a property set with a value that has an absolute unit will be that size when looked at on a phone or on a large monitor (and everything in between!)

      Absolute units can be useful when working on a project where responsiveness is not being considered. For example, desktop apps that can’t be resized can be styled for the default dimensions. If the window doesn’t scale, you don’t need the content to either.

      Hint: Absolute units can be less favourable for responsive sites because they don’t scale when the screen size changes.

      Absolute Unit Description Example
      px 1/96 of 1 inch (96px = 1 inch) font-size: 12px;
      pt 1/72 of 1 inch (72pt = 1 inch) font-size: 12pt;
      pc 12pt = 1pc font-size: 1.2pc;
      cm centimeter font-size: 0.6cm;
      mm millimeter (10 mm = 1 cm) font-size: 4mm;
      in inches font-size: 0.2in;

      Pixels (px) are typically the most popular absolute unit for screens. Centimeters, millimeters, and inches are more common for print and you may not have even known they were options!


      Relative Units

      Relative units are useful for styling responsive sites because they scale relative to the parent or window size (depending on the unit).

      As a general rule, relative units can be used as the default for responsive sites. This can help you avoid having to update styles for different screen sizes.

      Relative units can be a little more difficult than absolute units in determining which to use, so let’s go through your options in detail.

      Relative Unit Description
      % Relative to the parent element’s value for that property
      em Relative to the current font-size of the element
      rem Relative to the font-size of the root (e.g. the <html> element). “rem” = “root em”
      ch Number of characters (1 character is equal to the width of the current font’s 0/zero)
      vh Relative to the height of the viewport (window or app size). 1vh = 1/100 of the viewport’s height
      vw Relative to the width of viewport. 1vw = 1/100 of the viewport’s width.
      vmin Relative to viewport’s smaller dimension (e.g. for portrait orientation, the width is smaller than the height so it’s relative to the width). 1vmin = 1/100 of viewport’s smaller dimension.
      vmax Relative to viewport’s larger dimension (e.g. height for portrait orientation). 1vmax = 1/100 of viewport’s larger dimension.
      ex Relative to height of the current font’s lowercase “x”.

      It’s not always clear which of these options is best to use for each type of CSS property. For example, % is usually more appropriate for layout-related properties like width than it would be for font-size.

      Here are some examples of when you would use each relative unit.

      • %: You want a child element to have 10% of the parent’s width as a margin so it never fills the whole parent element. If the parent’s size changes, the margin will update too.

        .child {
          margin: 10%;
        }
        
      • em: You want the font of a child element to be half the size of its parent’s font-size (e.g. the paragraph under a section’s title).

        .child {
          font-size: 0.5em;
        }
        
      • rem: The font-size should be twice the size as the root element’s font. This could be how you size your headers because they should all be the same size regardless of the parent container.

        .header {
          font-size: 2rem;
        }
        
      • ch: You have a mono-spaced font (the characters are always the same width) and you only have space for 10 characters.

        .small-text {
          width: 10ch;
        }
        
      • vh: Your landing page should always be the height of the viewport/window.

        .wrapper {
          height: 100vh;
        }
        
      • vw: You have a section with text that should be half as wide as the viewport/window.

        .half-size {
          width: 50vw;
        }
        
      • vmin: You have an image that should always be as wide as the viewport’s smaller dimension. On a phone being held in portrait mode, the image will be as wide as the viewport’s width.

        .min-width {
          width: 100vmin;
        }
        
      • vmax: You don’t care if an image gets cut off because you want it to completely fill the larger dimension of the viewport. For example, if an image of a pattern is used as a background.

        .max-width {
          width: 100vmax;
        }
        
      • ex: You probably won’t come across ex very often but it’s generally a good measure of a font’s mid-section. Let’s say you want to a font’s line-height to be double the height of the font’s “x”.

        .double-x {
          line-height: 2ex;
        }
        

      Overall, when and how you choose your CSS units will come down to a couple questions:

      • Do I want what I’m styling to scale when the viewport size changes?
      • If I do want it to scale, what do I want it to scale relative to in the app?

      Once you’ve answered these questions, it’s a lot easier to nail down which unit to use. 💪

      Further Reading

      You can dig deeper into viewport units by reading this article, or have a look at this article about em vs rem units if the difference between those two units is still somewhat unclear.



      Source link

      The JavaScript Reduce Method Explained


      While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or
      edited it to ensure you have an error-free learning experience. It’s on our list, and we’re working on it!
      You can help us out by using the “report an issue” button at the bottom of the tutorial.

      Introduction

      Reduce is a method that can be difficult to understand especially with all the vague explanations that can be found on the web. There are a lot of benefits to understanding reduce as it is often used in state management (think Redux).

      The signature for the reduce array method in JavaScript is:

      arr.reduce(callback, initialValue);
      

      Terminology

      Reduce comes with some terminology such as reducer & accumulator. The accumulator is the value that we end with and the reducer is what action we will perform in order to get to one value.

      You must remember that a reducer will only return one value and one value only hence the name reduce.

      Take the following classic example:

      const value = 0; 
      
      const numbers = [5, 10, 15];
      
      for(let i = 0; i < numbers.length; i++) {
        value += numbers[i];
      }
      

      The above will give us 30 (5 + 10 + 15). This works just fine, but we can do this with reduce instead which will save us from mutating our value variable.

      The below code will also output 30, but will not mutate our value variable (which we have now called initialValue)

      /* this is our initial value i.e. the starting point*/
      const initialValue = 0;
      
      /* numbers array */
      const numbers = [5, 10, 15];
      
      /* reducer method that takes in the accumulator and next item */
      const reducer = (accumulator, item) => {
        return accumulator + item;
      };
      
      /* we give the reduce method our reducer function
        and our initial value */
      const total = numbers.reduce(reducer, initialValue)
      

      The above code may look a little confusing, but under the hood there is no magic going on. Let’s add a console.log in our reducer method that will output the accumulator and the item arguments.

      The following screenshot shows what’s logged to the console:

      Reduce Output

      So the first thing we notice is our method is called 3 times because there are 3 values in our array. Our accumulator begins at 0 which is our initialValue we passed to reduce. On each call to the function the item is added to the accumulator. The final call to the method has the accumulator value of 15 and item is 15, 15 + 15 gives us 30 which is our final value. Remember the reducer method returns the accumulator plus the item.

      So that is a simple example of how you would use reduce, now let’s dive into more a complicated example.

      Flattening an Array Using Reduce

      Let’s say we have the following array:

      const numArray = [1, 2, [3, 10, [11, 12]], [1, 2, [3, 4]], 5, 6];
      

      And let’s say for some crazy reason, JavaScript has removed the .flat method so we have to flatten this array ourselves.

      So we’ll write a function to flatten any array no matter how deeply nested the arrays are:

      function flattenArray(data) {
        // our initial value this time is a blank array
        const initialValue = [];
      
        // call reduce on our data
        return data.reduce((total, value) => {
          // if the value is an array then recursively call reduce
          // if the value is not an array then just concat our value
          return total.concat(Array.isArray(value) ? flattenArray(value) : value);
        }, initialValue);
      }
      

      If we pass our numArray to this method and log the result we get the following:

      Flatten Array Output

      This is a great example on how we can make a very common operation quite simple.

      Let’s go over one more example.

      Final Example – Changing an Object Structure

      So with the new Pokemon game coming out, let’s pretend we have a server that sends us an array of Pokemon objects like so:

      const pokemon = [
        { name: "charmander", type: "fire" },
        { name: "squirtle", type: "water" },
        { name: "bulbasaur", type: "grass" }
      ]
      

      We want to change this object to look like:

      const pokemonModified = {
        charmander: { type: "fire" },
        squirtle: { type: "water" },
        bulbasaur: { type: "grass" }
      };
      

      To get to that desired output we do the following:

      const getMapFromArray = data =>
        data.reduce((acc, item) => {
          // add object key to our object i.e. charmander: { type: 'water' }
          acc[item.name] = { type: item.type };
          return acc;
        }, {});
      

      If we call our method like so:

      getMapFromArray(pokemon)
      

      We get our desired output:

      Pokemon Output

      You can check out the Codesandbox here.

      Conclusion

      At first sight, the reduce looks more complex than other JavaScript Array Iteration Methods like map and filter, but once the syntax, core concepts and use-cases are understood it can be another powerful tool for JavaScript developers.



      Source link