Image Builders Comparison #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Image Builders Comparison | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| run_packer: | |
| description: 'Run Packer build' | |
| type: boolean | |
| default: true | |
| run_ec2_imagebuilder: | |
| description: 'Run EC2 Image Builder' | |
| type: boolean | |
| default: true | |
| env: | |
| AWS_REGION: us-west-2 | |
| permissions: | |
| id-token: write | |
| contents: read | |
| jobs: | |
| packer-build: | |
| name: HashiCorp Packer Build | |
| runs-on: ubuntu-latest | |
| if: ${{ github.event.inputs.run_packer == 'true' }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Setup Packer | |
| uses: hashicorp/setup-packer@main | |
| with: | |
| version: "1.9.4" | |
| - name: Get latest Ubuntu AMI | |
| run: | | |
| echo "π Searching for Ubuntu 22.04 AMI..." | |
| # Try specific search first | |
| UBUNTU_AMI=$(aws ec2 describe-images \ | |
| --owners 099720109477 \ | |
| --filters \ | |
| "Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-22.04-amd64-server-*" \ | |
| "Name=state,Values=available" \ | |
| --query 'Images | sort_by(@, &CreationDate) | [-1].ImageId' \ | |
| --output text 2>/dev/null || echo "") | |
| # If that fails, try broader search | |
| if [ "$UBUNTU_AMI" = "" ] || [ "$UBUNTU_AMI" = "None" ]; then | |
| echo "β οΈ First search failed, trying broader search..." | |
| UBUNTU_AMI=$(aws ec2 describe-images \ | |
| --owners 099720109477 \ | |
| --filters \ | |
| "Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-*-amd64-server-*" \ | |
| "Name=state,Values=available" \ | |
| --query 'Images | sort_by(@, &CreationDate) | [-1].ImageId' \ | |
| --output text) | |
| fi | |
| # Fallback to known AMI | |
| if [ "$UBUNTU_AMI" = "" ] || [ "$UBUNTU_AMI" = "None" ]; then | |
| echo "β οΈ Using hardcoded Ubuntu 22.04 AMI for us-west-2" | |
| UBUNTU_AMI="ami-0c2d3e23eb7b0270d" | |
| fi | |
| echo "β Using Ubuntu AMI: $UBUNTU_AMI" | |
| echo "UBUNTU_AMI=$UBUNTU_AMI" >> $GITHUB_ENV | |
| - name: Create Packer template | |
| run: | | |
| cat > packer-template.pkr.hcl << EOF | |
| packer { | |
| required_plugins { | |
| amazon = { | |
| source = "github.com/hashicorp/amazon" | |
| version = "~> 1" | |
| } | |
| } | |
| } | |
| source "amazon-ebs" "ubuntu" { | |
| ami_name = "packer-demo-\${timestamp()}" | |
| instance_type = "t3.micro" | |
| region = "${{ env.AWS_REGION }}" | |
| source_ami = "${{ env.UBUNTU_AMI }}" | |
| ssh_username = "ubuntu" | |
| tags = { | |
| Name = "packer-demo-\${timestamp()}" | |
| Tool = "HashiCorp-Packer" | |
| } | |
| } | |
| build { | |
| sources = ["source.amazon-ebs.ubuntu"] | |
| provisioner "shell" { | |
| inline = [ | |
| "sudo apt-get update", | |
| "sudo apt-get install -y nginx", | |
| "sudo systemctl enable nginx", | |
| "echo '<h1>Built with HashiCorp Packer</h1>' | sudo tee /var/www/html/index.html" | |
| ] | |
| } | |
| } | |
| EOF | |
| - name: Initialize and build with Packer | |
| run: | | |
| echo "π Starting Packer build with AMI: $UBUNTU_AMI" | |
| packer init packer-template.pkr.hcl | |
| packer validate packer-template.pkr.hcl | |
| packer build packer-template.pkr.hcl | tee packer-build.log | |
| echo "β Packer build completed!" | |
| - name: Upload Packer logs | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: packer-build-logs | |
| path: packer-build.log | |
| ec2-imagebuilder-build: | |
| name: AWS EC2 Image Builder Build | |
| runs-on: ubuntu-latest | |
| if: ${{ github.event.inputs.run_ec2_imagebuilder == 'true' }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Get latest Ubuntu AMI | |
| run: | | |
| echo "π Searching for Ubuntu 22.04 AMI..." | |
| # Try multiple search patterns | |
| UBUNTU_AMI=$(aws ec2 describe-images \ | |
| --owners 099720109477 \ | |
| --filters \ | |
| "Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-22.04-amd64-server-*" \ | |
| "Name=state,Values=available" \ | |
| --query 'Images | sort_by(@, &CreationDate) | [-1].ImageId' \ | |
| --output text 2>/dev/null || echo "") | |
| # If that fails, try a broader search | |
| if [ "$UBUNTU_AMI" = "" ] || [ "$UBUNTU_AMI" = "None" ]; then | |
| echo "β οΈ First search failed, trying broader search..." | |
| UBUNTU_AMI=$(aws ec2 describe-images \ | |
| --owners 099720109477 \ | |
| --filters \ | |
| "Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-*-amd64-server-*" \ | |
| "Name=state,Values=available" \ | |
| --query 'Images | sort_by(@, &CreationDate) | [-1].ImageId' \ | |
| --output text) | |
| fi | |
| # If still fails, use a known working AMI | |
| if [ "$UBUNTU_AMI" = "" ] || [ "$UBUNTU_AMI" = "None" ]; then | |
| echo "β οΈ AMI search failed, using hardcoded Ubuntu 22.04 AMI for us-west-2" | |
| UBUNTU_AMI="ami-0c2d3e23eb7b0270d" # Ubuntu 22.04 LTS in us-west-2 | |
| fi | |
| echo "β Using Ubuntu AMI: $UBUNTU_AMI" | |
| # Verify the AMI exists | |
| aws ec2 describe-images --image-ids $UBUNTU_AMI --query 'Images[0].Name' --output text | |
| echo "UBUNTU_AMI=$UBUNTU_AMI" >> $GITHUB_ENV | |
| - name: Run EC2 Image Builder pipeline | |
| run: | | |
| echo "π Starting EC2 Image Builder with AMI: $UBUNTU_AMI" | |
| # Verify we have a valid AMI | |
| if [ "$UBUNTU_AMI" = "" ] || [ "$UBUNTU_AMI" = "None" ]; then | |
| echo "β No valid AMI found. Exiting." | |
| exit 1 | |
| fi | |
| # Create component with proper YAML formatting | |
| cat > component.yml << 'EOF' | |
| name: InstallNginx | |
| description: Install Nginx web server | |
| schemaVersion: 1.0 | |
| phases: | |
| - name: build | |
| steps: | |
| - name: UpdateOS | |
| action: UpdateOS | |
| - name: InstallNginx | |
| action: ExecuteBash | |
| inputs: | |
| commands: | |
| - apt-get update | |
| - apt-get install -y nginx | |
| - systemctl enable nginx | |
| - echo '<h1>Built with EC2 Image Builder</h1>' > /var/www/html/index.html | |
| EOF | |
| echo "π Component YAML:" | |
| cat component.yml | |
| # Create component | |
| COMPONENT_ARN=$(aws imagebuilder create-component \ | |
| --name "nginx-component-$(date +%s)" \ | |
| --semantic-version "1.0.0" \ | |
| --description "Install Nginx" \ | |
| --platform Linux \ | |
| --data file://component.yml \ | |
| --query 'componentBuildVersionArn' \ | |
| --output text) | |
| echo "β Component created: $COMPONENT_ARN" | |
| # Create image recipe | |
| RECIPE_ARN=$(aws imagebuilder create-image-recipe \ | |
| --name "nginx-recipe-$(date +%s)" \ | |
| --semantic-version "1.0.0" \ | |
| --description "Ubuntu with Nginx" \ | |
| --parent-image "$UBUNTU_AMI" \ | |
| --components componentArn=$COMPONENT_ARN \ | |
| --query 'imageRecipeArn' \ | |
| --output text) | |
| echo "β Recipe created: $RECIPE_ARN" | |
| # Get default VPC info for infrastructure config | |
| DEFAULT_VPC=$(aws ec2 describe-vpcs \ | |
| --filters "Name=is-default,Values=true" \ | |
| --query 'Vpcs[0].VpcId' \ | |
| --output text) | |
| DEFAULT_SUBNET=$(aws ec2 describe-subnets \ | |
| --filters "Name=vpc-id,Values=$DEFAULT_VPC" \ | |
| --query 'Subnets[0].SubnetId' \ | |
| --output text) | |
| echo "π Using VPC: $DEFAULT_VPC, Subnet: $DEFAULT_SUBNET" | |
| # Create infrastructure configuration | |
| INFRA_ARN=$(aws imagebuilder create-infrastructure-configuration \ | |
| --name "basic-infra-$(date +%s)" \ | |
| --instance-types t3.micro \ | |
| --subnet-id "$DEFAULT_SUBNET" \ | |
| --query 'infrastructureConfigurationArn' \ | |
| --output text) | |
| echo "β Infrastructure config created: $INFRA_ARN" | |
| # Start image build | |
| IMAGE_ARN=$(aws imagebuilder create-image \ | |
| --image-recipe-arn "$RECIPE_ARN" \ | |
| --infrastructure-configuration-arn "$INFRA_ARN" \ | |
| --query 'imageBuildVersionArn' \ | |
| --output text) | |
| echo "β Image build started: $IMAGE_ARN" | |
| # Create build log | |
| echo "Build Summary:" > ec2-imagebuilder-build.log | |
| echo "Base AMI: $UBUNTU_AMI" >> ec2-imagebuilder-build.log | |
| echo "Image ARN: $IMAGE_ARN" >> ec2-imagebuilder-build.log | |
| echo "Recipe ARN: $RECIPE_ARN" >> ec2-imagebuilder-build.log | |
| echo "Component ARN: $COMPONENT_ARN" >> ec2-imagebuilder-build.log | |
| echo "Infrastructure ARN: $INFRA_ARN" >> ec2-imagebuilder-build.log | |
| - name: Upload EC2 Image Builder logs | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ec2-imagebuilder-logs | |
| path: ec2-imagebuilder-build.log | |
| comparison-summary: | |
| name: Build Comparison Summary | |
| runs-on: ubuntu-latest | |
| needs: [packer-build, ec2-imagebuilder-build] | |
| if: always() | |
| steps: | |
| - name: Generate comparison report | |
| run: | | |
| echo "# Image Builder Comparison Report" > comparison-report.md | |
| echo "" >> comparison-report.md | |
| echo "## Build Results" >> comparison-report.md | |
| echo "" >> comparison-report.md | |
| if [ "${{ needs.packer-build.result }}" = "success" ]; then | |
| echo "β **HashiCorp Packer**: Build completed successfully" >> comparison-report.md | |
| else | |
| echo "β **HashiCorp Packer**: Build failed or skipped" >> comparison-report.md | |
| fi | |
| if [ "${{ needs.ec2-imagebuilder-build.result }}" = "success" ]; then | |
| echo "β **AWS EC2 Image Builder**: Build completed successfully" >> comparison-report.md | |
| else | |
| echo "β **AWS EC2 Image Builder**: Build failed or skipped" >> comparison-report.md | |
| fi | |
| echo "" >> comparison-report.md | |
| echo "## Key Differences Observed" >> comparison-report.md | |
| echo "- **Packer**: Uses direct AMI ID, faster execution" >> comparison-report.md | |
| echo "- **EC2 Image Builder**: More verbose setup, better AWS integration" >> comparison-report.md | |
| echo "" >> comparison-report.md | |
| echo "Build completed at: $(date)" >> comparison-report.md | |
| cat comparison-report.md | |
| - name: Upload comparison report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: comparison-report | |
| path: comparison-report.md |