Creating a custom Amazon Machine Image (AMI) using EC2 Image Builder involves defining a pipeline that handles the image creation process. The pipeline takes components and an infrastructure configuration to create the image.

Here's a minimal example of how you can use Terraform to create a custom AMI using EC2 Image Builder:

  1. First, make sure you have the AWS provider defined:
    1
    2
    3
    provider "aws" {
      region = "us-west-2"
    }
    
  2. Define the IAM Role and permissions EC2 Image Builder will use:
    resource "aws_iam_role" "ec2imagebuilder" {
      name = "EC2ImageBuilderRole"
    
      assume_role_policy = jsonencode({
        Version = "2012-10-17",
        Statement = [
          {
            Action = "sts:AssumeRole",
            Principal = {
              Service = "imagebuilder.amazonaws.com"
            },
            Effect = "Allow",
            Sid    = ""
          }
        ]
      })
    }
    
    resource "aws_iam_policy" "ec2imagebuilder" {
      name        = "EC2ImageBuilderPolicy"
      description = "Permissions for EC2 Image Builder"
    
      policy = jsonencode({
        Version = "2012-10-17",
        Statement = [
          {
            Effect   = "Allow",
            Action   = "ec2:*",
            Resource = "*"
          }
        ]
      })
    }
    
    resource "aws_iam_role_policy_attachment" "ec2imagebuilder" {
      policy_arn = aws_iam_policy.ec2imagebuilder.arn
      role       = aws_iam_role.ec2imagebuilder.name
    }
    
  3. Define an EC2 Image Builder component. This is a sequence of steps to customize the image (e.g., installing software). Here's a simple example that updates the software packages on an Amazon Linux 2 base:
    resource "aws_imagebuilder_component" "update_software" {
      name          = "update-software"
      description   = "Update software packages"
      version       = "1.0.0"
      platform      = "Linux"
    
      change_description = "Update software packages"
    
      data = <<-EOD
    {
      "schemaVersion": "2.0",
      "phases": [
        {
          "name": "build",
          "steps": [
            {
              "name": "Update",
              "action": "ExecuteBash",
              "inputs": {
                "commands": [
                  "sudo yum update -y"
                ]
              }
            }
          ]
        }
      ]
    }
      EOD
    }
    
  4. Define the Image Recipe and Infrastructure Configuration:
    resource "aws_imagebuilder_image_recipe" "example" {
      name         = "example"
      description  = "Example recipe"
      version      = "1.0.0"
      parent_image = "arn:aws:imagebuilder:us-west-2:aws:image/amazon-linux-2-x86/x.x.x"
    
      block_device_mapping {
        device_name = "/dev/sda1"
    
        ebs {
          delete_on_termination = true
          volume_size           = 30
          volume_type           = "gp2"
        }
      }
    
      component {
        component_arn = aws_imagebuilder_component.update_software.arn
      }
    }
    
    resource "aws_imagebuilder_infrastructure_configuration" "example" {
      name = "example"
    
      instance_types = ["t2.micro"]
    
      instance_profile_name = aws_iam_instance_profile.ec2imagebuilder.name
    
      logging {
        s3_logs {
          s3_bucket_name = aws_s3_bucket.example.bucket
          s3_key_prefix  = "logs/"
        }
      }
    }
    
    resource "aws_iam_instance_profile" "ec2imagebuilder" {
      name = "ec2imagebuilder"
      role = aws_iam_role.ec2imagebuilder.name
    }
    
    resource "aws_s3_bucket" "example" {
      bucket = "ec2-imagebuilder-logs-example"
      acl    = "private"
    }
    
  5. Finally, create the Image Pipeline to build the image:
    1
    2
    3
    4
    5
    6
    7
    resource "aws_imagebuilder_image_pipeline" "example" {
      name = "example"
    
      image_recipe_arn = aws_imagebuilder_image_recipe.example.arn
    
      infrastructure_configuration_arn = aws_imagebuilder_infrastructure_configuration.example.arn
    }
    

With this configuration, once you apply it with terraform apply, an EC2 Image Builder pipeline will be created. When triggered, it will produce an AMI based on the latest Amazon Linux 2 and then apply the defined component (in this case, updating software packages).

Don't forget to adjust the example according to your specific needs, like selecting the correct parent image or customizing the software you want installed. Also, always review and tighten IAM policies based on the principle of least privilege.

Edit

Pub: 12 Sep 2023 13:25 UTC

Views: 49