diff --git a/website/source/docs/post-processors/manifest.html.md b/website/source/docs/post-processors/manifest.html.md index 9d930d241..774884fea 100644 --- a/website/source/docs/post-processors/manifest.html.md +++ b/website/source/docs/post-processors/manifest.html.md @@ -41,3 +41,64 @@ You can simply add `{"type":"manifest"}` to your post-processor section. Below i ] } ``` + +An example manifest file looks like: + +``` json +{ + "builds": [ + { + "name": "docker", + "builder_type": "docker", + "build_time": 1507245986, + "files": [ + { + "name": "packer_example", + "size": 102219776 + } + ], + "artifact_id": "Container", + "packer_run_uuid": "6d5d3185-fa95-44e1-8775-9e64fe2e2d8f" + } + ], + "last_run_uuid": "6d5d3185-fa95-44e1-8775-9e64fe2e2d8f" +} +``` + +If I run the build again, my new build will be added to the manifest file rather than replacing it, so you can always grab specific builds from the manifest by uuid. + +The mainfest above was generated from this packer.json: +``` +{ + "builders": [ + { + "type": "docker", + "image": "ubuntu:latest", + "export_path": "packer_example", + "run_command": [ "-d", "-i", "-t", "--entrypoint=/bin/bash", "{{.Image}}" ] + } + ], + "provisioners": [ + { + "type": "shell", + "inline": "mkdir /Setup" + }, + { + "type": "file", + "source": "../scripts/dummy_bash.sh", + "destination": "/Setup" + }, + { + "type": "shell", + "inline":["ls -alh /Setup/"] + } + ], + "post-processors": [ + { + "type": "manifest", + "output": "manifest.json", + "strip_path": true + } + ] +} +``` diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 2e9a67768..23f60252d 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -12,9 +12,8 @@ description: |- # Build an Image With Packer installed, let's just dive right into it and build our first image. -Our first image will be an [Amazon EC2 AMI](https://aws.amazon.com/ec2/) with -Redis pre-installed. This is just an example. Packer can create images for [many -platforms][platforms] with anything pre-installed. +Our first image will be an [Amazon EC2 AMI](https://aws.amazon.com/ec2/) +This is just an example. Packer can create images for [many platforms][platforms]. If you don't have an AWS account, [create one now](https://aws.amazon.com/free/). For the example, we'll use a "t2.micro" instance to build our image, which @@ -161,8 +160,8 @@ typically represent an ID (such as in the case of an AMI) or a set of files (such as for a VMware virtual machine). In this example, we only have a single artifact: the AMI in us-east-1 that was created. -This AMI is ready to use. If you wanted you could go and launch this AMI right now -and it would work great. +This AMI is ready to use. If you wanted you could go and launch this AMI right +now and it would work great. -> **Note:** Your AMI ID will surely be different than the one above. If you try to launch the one in the example output above, you will get an error. If you @@ -200,4 +199,290 @@ image was pretty useless in this case (nothing was changed about it), this page should've given you a general idea of how Packer works, what templates are and how to validate and build templates into machine images. +## Some more examples: + +### Another Linux Example, with provisioners: +Create a file named `welcome.txt` and add the following: +``` +WELCOME TO PACKER! +``` + +Create a file named `example.sh` and add the following: +``` +#!/bin/bash +echo "hello +``` + +Set your access key and id as environment variables, so we don't need to pass +them in through the command line: +``` +export AWS_ACCESS_KEY_ID=MYACCESSKEYID +export AWS_SECRET_ACCESS_KEY=MYSECRETACCESSKEY +``` + +Now save the following text in a file named `firstrun.json`: + +``` +{ + "variables": { + "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}", + "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}", + "region": "us-east-1" + }, + "builders": [ + { + "access_key": "{{user `aws_access_key`}}", + "ami_name": "packer-linux-aws-demo-{{timestamp}}", + "instance_type": "t2.micro", + "region": "us-east-1", + "secret_key": "{{user `aws_secret_key`}}", + "source_ami_filter": { + "filters": { + "virtualization-type": "hvm", + "name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*", + "root-device-type": "ebs" + }, + "owners": ["099720109477"], + "most_recent": true + }, + "ssh_username": "ubuntu", + "type": "amazon-ebs" + } + ], + "provisioners": [ + { + "type": "file", + "source": "./welcome.txt", + "destination": "/home/ubuntu/" + }, + { + "type": "shell", + "inline":[ + "ls -al /home/ubuntu", + "cat /home/ubuntu/welcome.txt" + ] + }, + { + "type": "shell", + "script": "./example.sh" + } + ] +} +``` + +and to build, run `packer build firstrun.json` + +Note that if you wanted to use a `source_ami` instead of a `source_ami_filter` +it might look something like this: `"source_ami": "ami-fce3c696",` + +Your output will look like this: + +``` +amazon-ebs output will be in this color. + +==> amazon-ebs: Prevalidating AMI Name: packer-linux-aws-demo-1507231105 + amazon-ebs: Found Image ID: ami-fce3c696 +==> amazon-ebs: Creating temporary keypair: packer_59d68581-e3e6-eb35-4ae3-c98d55cfa04f +==> amazon-ebs: Creating temporary security group for this instance: packer_59d68584-cf8a-d0af-ad82-e058593945ea +==> amazon-ebs: Authorizing access to port 22 on the temporary security group... +==> amazon-ebs: Launching a source AWS instance... +==> amazon-ebs: Adding tags to source instance + amazon-ebs: Adding tag: "Name": "Packer Builder" + amazon-ebs: Instance ID: i-013e8fb2ced4d714c +==> amazon-ebs: Waiting for instance (i-013e8fb2ced4d714c) to become ready... +==> amazon-ebs: Waiting for SSH to become available... +==> amazon-ebs: Connected to SSH! +==> amazon-ebs: Uploading ./scripts/welcome.txt => /home/ubuntu/ +==> amazon-ebs: Provisioning with shell script: /var/folders/8t/0yb5q0_x6mb2jldqq_vjn3lr0000gn/T/packer-shell661094204 + amazon-ebs: total 32 + amazon-ebs: drwxr-xr-x 4 ubuntu ubuntu 4096 Oct 5 19:19 . + amazon-ebs: drwxr-xr-x 3 root root 4096 Oct 5 19:19 .. + amazon-ebs: -rw-r--r-- 1 ubuntu ubuntu 220 Apr 9 2014 .bash_logout + amazon-ebs: -rw-r--r-- 1 ubuntu ubuntu 3637 Apr 9 2014 .bashrc + amazon-ebs: drwx------ 2 ubuntu ubuntu 4096 Oct 5 19:19 .cache + amazon-ebs: -rw-r--r-- 1 ubuntu ubuntu 675 Apr 9 2014 .profile + amazon-ebs: drwx------ 2 ubuntu ubuntu 4096 Oct 5 19:19 .ssh + amazon-ebs: -rw-r--r-- 1 ubuntu ubuntu 18 Oct 5 19:19 welcome.txt + amazon-ebs: WELCOME TO PACKER! +==> amazon-ebs: Provisioning with shell script: ./example.sh + amazon-ebs: hello +==> amazon-ebs: Stopping the source instance... + amazon-ebs: Stopping instance, attempt 1 +==> amazon-ebs: Waiting for the instance to stop... +==> amazon-ebs: Creating the AMI: packer-linux-aws-demo-1507231105 + amazon-ebs: AMI: ami-f76ea98d +==> amazon-ebs: Waiting for AMI to become ready... +``` + +### A windows example + +Note that this uses a larger instance. You will be charged for it. Also keep +in mind that using windows AMIs incurs a fee that you don't get when you use +linux AMIs. + +You'll need to have a boostrapping file to enable ssh or winrm; here's a basic +example of that file. + +``` +# set administrator password +net user Administrator SuperS3cr3t! +wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE + +# First, make sure WinRM doesn't run and can't be connected to +netsh advfirewall firewall add rule name="WinRM" protocol=TCP dir=in localport=5985 action=block +net stop winrm + +# turn off PowerShell execution policy restrictions +Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope LocalMachine + +# configure WinRM +winrm quickconfig -q +winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="0"}' +winrm set winrm/config '@{MaxTimeoutms="7200000"}' +winrm set winrm/config/service '@{AllowUnencrypted="true"}' +winrm set winrm/config/service '@{MaxConcurrentOperationsPerUser="12000"}' +winrm set winrm/config/service/auth '@{Basic="true"}' +winrm set winrm/config/client/auth '@{Basic="true"}' + +net stop winrm +set-service winrm -startupType automatic + +# Finally, allow WinRM connections and start the service +netsh advfirewall firewall set rule name="WinRM" new action=allow +net start winrm +``` + + +Save the above code in a file named `bootstrap_win.txt`. + +The example config below shows the two different ways of using the powershell +provisioner: `inline` and `script`. +The first example, `inline`, allows you to provide short snippets of code, and +will create the script file for you. The second example allows you to run more +complex code by providing the path to a script to run on the guest vm. + +Here's an example of a `sample_script.ps1` that will work with the environment +variables we will set in our packer config; copy the contents into your own +`sample_script.ps1` and provide the path to it in your packer config: + +``` +Write-Output("PACKER_BUILD_NAME is automatically set for you,) +Write-Output("or you can set it in your builder variables; ) +Write-Output("the default for this builder is: " + $Env:PACKER_BUILD_NAME ) +Write-Output("Remember that escaping variables in powershell requires backticks: ) +Write-Output("for example, VAR1 from our config is " + $Env:VAR1 ) +Write-Output("Likewise, VAR2 is " + $Env:VAR2 ) +Write-Output("and VAR3 is " + $Env:VAR3 ) +``` + +Next you need to create a packer config that will use this bootstrap file. See +the example below, which contains examples of using source_ami_filter for +windows in addition to the powershell and windows-restart provisioners: + +``` +{ + "variables": { + "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}", + "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}", + "region": "us-east-1" + }, + "builders": [ + { + "type": "amazon-ebs", + "access_key": "{{ user `aws_access_key` }}", + "secret_key": "{{ user `aws_secret_key` }}", + "region": "us-east-1", + "instance_type": "m3.medium", + "source_ami_filter": { + "filters": { + "virtualization-type": "hvm", + "name": "*WindowsServer2012R2*", + "root-device-type": "ebs" + }, + "most_recent": true, + "owners": "amazon" + }, + "ami_name": "packer-demo-{{timestamp}}", + "user_data_file": "./bootstrap_win.txt", + "communicator": "winrm", + "winrm_username": "Administrator", + "winrm_password": "SuperS3cr3t!" + }], + "provisioners": [ + { + "type": "powershell", + "environment_vars": ["DEVOPS_LIFE_IMPROVER=PACKER"], + "inline": "Write-Output(\"HELLO NEW USER; WELCOME TO $Env:DEVOPS_LIFE_IMPROVER\")" + }, + { + "type": "windows-restart" + }, + { + "script": "./sample_script.ps1", + "type": "powershell", + "environment_vars": [ + "VAR1=A`$Dollar", + "VAR2=A``Backtick", + "VAR3=A`'SingleQuote" + ] + } + ] +} +``` + +Then `packer build firstrun.json` + +You should see output like this: + +``` +amazon-ebs output will be in this color. + +==> amazon-ebs: Prevalidating AMI Name: packer-demo-1507234504 + amazon-ebs: Found Image ID: ami-d79776ad +==> amazon-ebs: Creating temporary keypair: packer_59d692c8-81f9-6a15-2502-0ca730980bed +==> amazon-ebs: Creating temporary security group for this instance: packer_59d692f0-dd01-6879-d8f8-7765327f5365 +==> amazon-ebs: Authorizing access to port 5985 on the temporary security group... +==> amazon-ebs: Launching a source AWS instance... +==> amazon-ebs: Adding tags to source instance + amazon-ebs: Adding tag: "Name": "Packer Builder" + amazon-ebs: Instance ID: i-04467596029d0a2ff +==> amazon-ebs: Waiting for instance (i-04467596029d0a2ff) to become ready... +==> amazon-ebs: Skipping waiting for password since WinRM password set... +==> amazon-ebs: Waiting for WinRM to become available... + amazon-ebs: WinRM connected. +==> amazon-ebs: Connected to WinRM! +==> amazon-ebs: Provisioning with Powershell... +==> amazon-ebs: Provisioning with powershell script: /var/folders/8t/0yb5q0_x6mb2jldqq_vjn3lr0000gn/T/packer-powershell-provisioner079851514 + amazon-ebs: HELLO NEW USER; WELCOME TO PACKER +==> amazon-ebs: Restarting Machine +==> amazon-ebs: Waiting for machine to restart... + amazon-ebs: WIN-164614OO21O restarted. +==> amazon-ebs: Machine successfully restarted, moving on +==> amazon-ebs: Provisioning with Powershell... +==> amazon-ebs: Provisioning with powershell script: ./scripts/sample_script.ps1 + amazon-ebs: PACKER_BUILD_NAME is automatically set for you, or you can set it in your builder variables; the default for this builder is: amazon-ebs + amazon-ebs: Remember that escaping variables in powershell requires backticks; for example VAR1 from our config is A$Dollar + amazon-ebs: Likewise, VAR2 is A`Backtick + amazon-ebs: and VAR3 is A'SingleQuote +==> amazon-ebs: Stopping the source instance... + amazon-ebs: Stopping instance, attempt 1 +==> amazon-ebs: Waiting for the instance to stop... +==> amazon-ebs: Creating the AMI: packer-demo-1507234504 + amazon-ebs: AMI: ami-2970b753 +==> amazon-ebs: Waiting for AMI to become ready... +==> amazon-ebs: Terminating the source AWS instance... +==> amazon-ebs: Cleaning up any extra volumes... +==> amazon-ebs: No volumes to clean up, skipping +==> amazon-ebs: Deleting temporary security group... +==> amazon-ebs: Deleting temporary keypair... +Build 'amazon-ebs' finished. + +==> Builds finished. The artifacts of successful builds are: +--> amazon-ebs: AMIs were created: +us-east-1: ami-2970b753 +``` + +And if you navigate to your EC2 dashboard you should see your shiny new AMI. + + [platforms]: /docs/builders/index.html