Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
packer
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kristopher Ruzic
packer
Commits
ff149df3
Commit
ff149df3
authored
Nov 17, 2014
by
Evan Brown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use golang/oauth2, no longer require client_secrets.json, and use
Service Account when run from a GCE Instance.
parent
ec216a52
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
82 additions
and
134 deletions
+82
-134
builder/googlecompute/account.go
builder/googlecompute/account.go
+0
-10
builder/googlecompute/builder.go
builder/googlecompute/builder.go
+1
-1
builder/googlecompute/config.go
builder/googlecompute/config.go
+0
-20
builder/googlecompute/config_test.go
builder/googlecompute/config_test.go
+0
-33
builder/googlecompute/driver_gce.go
builder/googlecompute/driver_gce.go
+27
-31
test/README.md
test/README.md
+1
-2
test/builder_googlecompute.bats
test/builder_googlecompute.bats
+3
-5
test/fixtures/builder-googlecompute/minimal.json
test/fixtures/builder-googlecompute/minimal.json
+3
-5
website/source/docs/builders/googlecompute.markdown
website/source/docs/builders/googlecompute.markdown
+47
-27
No files found.
builder/googlecompute/account.go
View file @
ff149df3
...
@@ -13,16 +13,6 @@ type accountFile struct {
...
@@ -13,16 +13,6 @@ type accountFile struct {
ClientId
string
`json:"client_id"`
ClientId
string
`json:"client_id"`
}
}
// clientSecretsFile represents the structure of the client secrets JSON file.
type
clientSecretsFile
struct
{
Web
struct
{
AuthURI
string
`json:"auth_uri"`
ClientEmail
string
`json:"client_email"`
ClientId
string
`json:"client_id"`
TokenURI
string
`json:"token_uri"`
}
}
func
loadJSON
(
result
interface
{},
path
string
)
error
{
func
loadJSON
(
result
interface
{},
path
string
)
error
{
f
,
err
:=
os
.
Open
(
path
)
f
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
builder/googlecompute/builder.go
View file @
ff149df3
...
@@ -35,7 +35,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
...
@@ -35,7 +35,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
// representing a GCE machine image.
// representing a GCE machine image.
func
(
b
*
Builder
)
Run
(
ui
packer
.
Ui
,
hook
packer
.
Hook
,
cache
packer
.
Cache
)
(
packer
.
Artifact
,
error
)
{
func
(
b
*
Builder
)
Run
(
ui
packer
.
Ui
,
hook
packer
.
Hook
,
cache
packer
.
Cache
)
(
packer
.
Artifact
,
error
)
{
driver
,
err
:=
NewDriverGCE
(
driver
,
err
:=
NewDriverGCE
(
ui
,
b
.
config
.
ProjectId
,
&
b
.
config
.
account
,
&
b
.
config
.
clientSecrets
)
ui
,
b
.
config
.
ProjectId
,
&
b
.
config
.
account
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
builder/googlecompute/config.go
View file @
ff149df3
...
@@ -17,7 +17,6 @@ type Config struct {
...
@@ -17,7 +17,6 @@ type Config struct {
common
.
PackerConfig
`mapstructure:",squash"`
common
.
PackerConfig
`mapstructure:",squash"`
AccountFile
string
`mapstructure:"account_file"`
AccountFile
string
`mapstructure:"account_file"`
ClientSecretsFile
string
`mapstructure:"client_secrets_file"`
ProjectId
string
`mapstructure:"project_id"`
ProjectId
string
`mapstructure:"project_id"`
BucketName
string
`mapstructure:"bucket_name"`
BucketName
string
`mapstructure:"bucket_name"`
...
@@ -38,7 +37,6 @@ type Config struct {
...
@@ -38,7 +37,6 @@ type Config struct {
Zone
string
`mapstructure:"zone"`
Zone
string
`mapstructure:"zone"`
account
accountFile
account
accountFile
clientSecrets
clientSecretsFile
instanceName
string
instanceName
string
privateKeyBytes
[]
byte
privateKeyBytes
[]
byte
sshTimeout
time
.
Duration
sshTimeout
time
.
Duration
...
@@ -106,7 +104,6 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
...
@@ -106,7 +104,6 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
// Process Templates
// Process Templates
templates
:=
map
[
string
]
*
string
{
templates
:=
map
[
string
]
*
string
{
"account_file"
:
&
c
.
AccountFile
,
"account_file"
:
&
c
.
AccountFile
,
"client_secrets_file"
:
&
c
.
ClientSecretsFile
,
"bucket_name"
:
&
c
.
BucketName
,
"bucket_name"
:
&
c
.
BucketName
,
"image_name"
:
&
c
.
ImageName
,
"image_name"
:
&
c
.
ImageName
,
...
@@ -138,16 +135,6 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
...
@@ -138,16 +135,6 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
errs
,
errors
.
New
(
"a bucket_name must be specified"
))
errs
,
errors
.
New
(
"a bucket_name must be specified"
))
}
}
if
c
.
AccountFile
==
""
{
errs
=
packer
.
MultiErrorAppend
(
errs
,
errors
.
New
(
"an account_file must be specified"
))
}
if
c
.
ClientSecretsFile
==
""
{
errs
=
packer
.
MultiErrorAppend
(
errs
,
errors
.
New
(
"a client_secrets_file must be specified"
))
}
if
c
.
ProjectId
==
""
{
if
c
.
ProjectId
==
""
{
errs
=
packer
.
MultiErrorAppend
(
errs
=
packer
.
MultiErrorAppend
(
errs
,
errors
.
New
(
"a project_id must be specified"
))
errs
,
errors
.
New
(
"a project_id must be specified"
))
...
@@ -185,13 +172,6 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
...
@@ -185,13 +172,6 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
}
}
}
}
if
c
.
ClientSecretsFile
!=
""
{
if
err
:=
loadJSON
(
&
c
.
clientSecrets
,
c
.
ClientSecretsFile
);
err
!=
nil
{
errs
=
packer
.
MultiErrorAppend
(
errs
,
fmt
.
Errorf
(
"Failed parsing client secrets file: %s"
,
err
))
}
}
// Check for any errors.
// Check for any errors.
if
errs
!=
nil
&&
len
(
errs
.
Errors
)
>
0
{
if
errs
!=
nil
&&
len
(
errs
.
Errors
)
>
0
{
return
nil
,
nil
,
errs
return
nil
,
nil
,
errs
...
...
builder/googlecompute/config_test.go
View file @
ff149df3
...
@@ -9,7 +9,6 @@ func testConfig(t *testing.T) map[string]interface{} {
...
@@ -9,7 +9,6 @@ func testConfig(t *testing.T) map[string]interface{} {
return
map
[
string
]
interface
{}{
return
map
[
string
]
interface
{}{
"account_file"
:
testAccountFile
(
t
),
"account_file"
:
testAccountFile
(
t
),
"bucket_name"
:
"foo"
,
"bucket_name"
:
"foo"
,
"client_secrets_file"
:
testClientSecretsFile
(
t
),
"project_id"
:
"hashicorp"
,
"project_id"
:
"hashicorp"
,
"source_image"
:
"foo"
,
"source_image"
:
"foo"
,
"zone"
:
"us-east-1a"
,
"zone"
:
"us-east-1a"
,
...
@@ -69,22 +68,6 @@ func TestConfigPrepare(t *testing.T) {
...
@@ -69,22 +68,6 @@ func TestConfigPrepare(t *testing.T) {
false
,
false
,
},
},
{
"client_secrets_file"
,
nil
,
true
,
},
{
"client_secrets_file"
,
testClientSecretsFile
(
t
),
false
,
},
{
"client_secrets_file"
,
"/tmp/i/should/not/exist"
,
true
,
},
{
{
"private_key_file"
,
"private_key_file"
,
"/tmp/i/should/not/exist"
,
"/tmp/i/should/not/exist"
,
...
@@ -180,22 +163,6 @@ func testAccountFile(t *testing.T) string {
...
@@ -180,22 +163,6 @@ func testAccountFile(t *testing.T) string {
return
tf
.
Name
()
return
tf
.
Name
()
}
}
func
testClientSecretsFile
(
t
*
testing
.
T
)
string
{
tf
,
err
:=
ioutil
.
TempFile
(
""
,
"packer"
)
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
defer
tf
.
Close
()
if
_
,
err
:=
tf
.
Write
([]
byte
(
testClientSecretsContent
));
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
return
tf
.
Name
()
}
// This is just some dummy data that doesn't actually work (it was revoked
// This is just some dummy data that doesn't actually work (it was revoked
// a long time ago).
// a long time ago).
const
testAccountContent
=
`{}`
const
testAccountContent
=
`{}`
const
testClientSecretsContent
=
`{"web":{"auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","client_email":"774313886706-eorlsj0r4eqkh5e7nvea5fuf59ifr873@developer.gserviceaccount.com","client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/774313886706-eorlsj0r4eqkh5e7nvea5fuf59ifr873@developer.gserviceaccount.com","client_id":"774313886706-eorlsj0r4eqkh5e7nvea5fuf59ifr873.apps.googleusercontent.com","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs"}}`
builder/googlecompute/driver_gce.go
View file @
ff149df3
...
@@ -6,9 +6,9 @@ import (
...
@@ -6,9 +6,9 @@ import (
"net/http"
"net/http"
"time"
"time"
"code.google.com/p/goauth2/oauth"
"code.google.com/p/goauth2/oauth/jwt"
"code.google.com/p/google-api-go-client/compute/v1"
"code.google.com/p/google-api-go-client/compute/v1"
"github.com/golang/oauth2"
"github.com/golang/oauth2/google"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/packer"
)
)
...
@@ -20,39 +20,35 @@ type driverGCE struct {
...
@@ -20,39 +20,35 @@ type driverGCE struct {
ui
packer
.
Ui
ui
packer
.
Ui
}
}
const
DriverScopes
string
=
"https://www.googleapis.com/auth/compute "
+
var
DriverScopes
=
[]
string
{
"https://www.googleapis.com/auth/compute"
,
"https://www.googleapis.com/auth/devstorage.full_control"
}
"https://www.googleapis.com/auth/devstorage.full_control"
func
NewDriverGCE
(
ui
packer
.
Ui
,
p
string
,
a
*
accountFile
,
c
*
clientSecretsFile
)
(
Driver
,
error
)
{
func
NewDriverGCE
(
ui
packer
.
Ui
,
p
string
,
a
*
accountFile
)
(
Driver
,
error
)
{
// Get the token for use in our requests
var
f
*
oauth2
.
Flow
log
.
Printf
(
"[INFO] Requesting Google token..."
)
var
err
error
// Auth with AccountFile first if provided
if
a
.
PrivateKey
!=
""
{
log
.
Printf
(
"[INFO] Requesting Google token via AccountFile..."
)
log
.
Printf
(
"[INFO] -- Email: %s"
,
a
.
ClientEmail
)
log
.
Printf
(
"[INFO] -- Email: %s"
,
a
.
ClientEmail
)
log
.
Printf
(
"[INFO] -- Scopes: %s"
,
DriverScopes
)
log
.
Printf
(
"[INFO] -- Scopes: %s"
,
DriverScopes
)
log
.
Printf
(
"[INFO] -- Private Key Length: %d"
,
len
(
a
.
PrivateKey
))
log
.
Printf
(
"[INFO] -- Private Key Length: %d"
,
len
(
a
.
PrivateKey
))
log
.
Printf
(
"[INFO] -- Token URL: %s"
,
c
.
Web
.
TokenURI
)
jwtTok
:=
jwt
.
NewToken
(
f
,
err
=
oauth2
.
New
(
a
.
ClientEmail
,
oauth2
.
JWTClient
(
a
.
ClientEmail
,
[]
byte
(
a
.
PrivateKey
))
,
DriverScopes
,
oauth2
.
Scope
(
DriverScopes
...
)
,
[]
byte
(
a
.
PrivateKey
))
google
.
JWTEndpoint
(
))
jwtTok
.
ClaimSet
.
Aud
=
c
.
Web
.
TokenURI
}
else
{
token
,
err
:=
jwtTok
.
Assert
(
new
(
http
.
Client
)
)
log
.
Printf
(
"[INFO] Requesting Google token via GCE Service Role..."
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"Error retrieving auth token: %s"
,
err
)
f
,
err
=
oauth2
.
New
(
google
.
ComputeEngineAccount
(
""
)
)
}
}
// Instantiate the transport to communicate to Google
if
err
!=
nil
{
transport
:=
&
oauth
.
Transport
{
return
nil
,
err
Config
:
&
oauth
.
Config
{
ClientId
:
a
.
ClientId
,
Scope
:
DriverScopes
,
TokenURL
:
c
.
Web
.
TokenURI
,
AuthURL
:
c
.
Web
.
AuthURI
,
},
Token
:
token
,
}
}
log
.
Printf
(
"[INFO] Instantiating GCE client..."
)
log
.
Printf
(
"[INFO] Instantiating GCE client
using
..."
)
service
,
err
:=
compute
.
New
(
transport
.
Client
()
)
service
,
err
:=
compute
.
New
(
&
http
.
Client
{
Transport
:
f
.
NewTransport
()}
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
test/README.md
View file @
ff149df3
...
@@ -41,8 +41,7 @@ Set the following self-explanatory environmental variables:
...
@@ -41,8 +41,7 @@ Set the following self-explanatory environmental variables:
Set the following environmental variables:
Set the following environmental variables:
*
`GC_BUCKET_NAME`
*
`GC_BUCKET_NAME`
*
`GC_CLIENT_SECRETS_FILE`
*
`GC_ACCOUNT_FILE`
*
`GC_PRIVATE_KEY_FILE`
*
`GC_PROJECT_ID`
*
`GC_PROJECT_ID`
### Running
### Running
...
...
test/builder_googlecompute.bats
View file @
ff149df3
...
@@ -8,8 +8,7 @@ fixtures builder-googlecompute
...
@@ -8,8 +8,7 @@ fixtures builder-googlecompute
# Required parameters
# Required parameters
: ${GC_BUCKET_NAME:?}
: ${GC_BUCKET_NAME:?}
: ${GC_CLIENT_SECRETS_FILE:?}
: ${GC_ACCOUNT_FILE:?}
: ${GC_PRIVATE_KEY_FILE:?}
: ${GC_PROJECT_ID:?}
: ${GC_PROJECT_ID:?}
command -v gcutil >/dev/null 2>&1 || {
command -v gcutil >/dev/null 2>&1 || {
echo "'gcutil' must be installed" >&2
echo "'gcutil' must be installed" >&2
...
@@ -17,8 +16,7 @@ command -v gcutil >/dev/null 2>&1 || {
...
@@ -17,8 +16,7 @@ command -v gcutil >/dev/null 2>&1 || {
}
}
USER_VARS="-var bucket_name=${GC_BUCKET_NAME}"
USER_VARS="-var bucket_name=${GC_BUCKET_NAME}"
USER_VARS="${USER_VARS} -var client_secrets_file=${GC_CLIENT_SECRETS_FILE}"
USER_VARS="${USER_VARS} -var account_file=${GC_ACCOUNT_FILE}"
USER_VARS="${USER_VARS} -var private_key_file=${GC_PRIVATE_KEY_FILE}"
USER_VARS="${USER_VARS} -var project_id=${GC_PROJECT_ID}"
USER_VARS="${USER_VARS} -var project_id=${GC_PROJECT_ID}"
# This tests if GCE has an image that contains the given parameter.
# This tests if GCE has an image that contains the given parameter.
...
@@ -30,7 +28,7 @@ gc_has_image() {
...
@@ -30,7 +28,7 @@ gc_has_image() {
teardown() {
teardown() {
gcutil --format=names --project=${GC_PROJECT_ID} listimages \
gcutil --format=names --project=${GC_PROJECT_ID} listimages \
| grep packerbats \
| grep packerbats \
| xargs -n1 gcutil --project=${GC_PROJECT_ID}
--force deleteimag
e
| xargs -n1 gcutil --project=${GC_PROJECT_ID}
deleteimage --forc
e
}
}
@test "googlecompute: build minimal.json" {
@test "googlecompute: build minimal.json" {
...
...
test/fixtures/builder-googlecompute/minimal.json
View file @
ff149df3
{
{
"variables"
:
{
"variables"
:
{
"bucket_name"
:
null
,
"bucket_name"
:
null
,
"client_secrets_file"
:
null
,
"account_file"
:
null
,
"private_key_file"
:
null
,
"project_id"
:
null
"project_id"
:
null
},
},
"builders"
:
[{
"builders"
:
[{
"type"
:
"googlecompute"
,
"type"
:
"googlecompute"
,
"bucket_name"
:
"{{user `bucket_name`}}"
,
"bucket_name"
:
"{{user `bucket_name`}}"
,
"client_secrets_file"
:
"{{user `client_secrets_file`}}"
,
"account_file"
:
"{{user `account_file`}}"
,
"private_key_file"
:
"{{user `private_key_file`}}"
,
"project_id"
:
"{{user `project_id`}}"
,
"project_id"
:
"{{user `project_id`}}"
,
"image_name"
:
"packerbats-minimal-{{timestamp}}"
,
"image_name"
:
"packerbats-minimal-{{timestamp}}"
,
"source_image"
:
"debian-7-wheezy-v201
31120
"
,
"source_image"
:
"debian-7-wheezy-v201
41108
"
,
"zone"
:
"us-central1-a"
"zone"
:
"us-central1-a"
}]
}]
}
}
website/source/docs/builders/googlecompute.markdown
View file @
ff149df3
...
@@ -9,19 +9,49 @@ description: |-
...
@@ -9,19 +9,49 @@ description: |-
Type:
`googlecompute`
Type:
`googlecompute`
The
`googlecompute`
Packer builder is able to create
The
`googlecompute`
Packer builder is able to create
[
images
](
https://developers.google.com/compute/docs/images
)
for use with
[
images
](
https://developers.google.com/compute/docs/images
)
[
Google Compute Engine
](
https://cloud.google.com/products/compute-engine
)(
GCE
)
based on existing images. Google
for use with
[
Google Compute Engine
](
https://cloud.google.com/products/compute-engine
)
Compute Engine doesn't allow the creation of images from scratch.
(GCE) based on existing images. Google Compute Engine doesn't allow the creation
of images from scratch.
## Authentication
## Authentication
Authenticating with Google Cloud services requires two separate JSON
Authenticating with Google Cloud services requires at most one JSON file,
files: one which we call the _account file_ and the _client secrets file_.
called the _account file_. The _account file_ is
**not**
required if you are running
the
`googlecompute`
Packer builder from a GCE instance with a properly-configured
[
Compute Engine Service Account
](
https://cloud.google.com/compute/docs/authentication.
Both of these files are downloaded directly from the
### Running With a Compute Engine Service Account
[
Google Developers Console
](
https://console.developers.google.com
)
. To make
If you run the
`googlecompute`
Packer builder from a GCE instance, you can configure that
instance to use a
[
Compute Engine Service Account
](
https://cloud.google.com/compute/docs/authentication
)
. This will allow Packer to authenticate
to Google Cloud without having to bake in a separate credential/authentication file.
To create a GCE instance that uses a service account, provide the required scopes when
launching the intance.
For
`gcloud`
, do this via the
`--scopes`
parameter:
```
sh
gcloud compute
--project
YOUR_PROJECT instances create
"INSTANCE-NAME"
...
\
--scopes
"https://www.googleapis.com/auth/compute"
\
"https://www.googleapis.com/auth/devstorage.full_control"
\
...
```
For the
[
Google Developers Console
](
https://console.developers.google.com
)
:
1.
Choose "Show advanced options"
2.
Tick "Enable Compute Engine service account"
3.
Choose "Read Write" for Compute
4.
Chose "Full" for "Storage"
**
The service account will be used automatically by Packer as long as there is
no _account file_ specified in the Packer configuration file.
**
### Running Without a Compute Engine Service Account
The
[
Google Developers Console
](
https://console.developers.google.com
)
allows you to
create and download a credential file that will let you use the
`googlecompute`
Packer
builder anywhere. To make
the process more straightforwarded, it is documented here.
the process more straightforwarded, it is documented here.
1.
Log into the
[
Google Developers Console
](
https://console.developers.google.com
)
1.
Log into the
[
Google Developers Console
](
https://console.developers.google.com
)
...
@@ -29,27 +59,22 @@ the process more straightforwarded, it is documented here.
...
@@ -29,27 +59,22 @@ the process more straightforwarded, it is documented here.
2.
Under the "APIs & Auth" section, click "Credentials."
2.
Under the "APIs & Auth" section, click "Credentials."
3.
Click the "Download JSON" button under the "Compute Engine and App Engine"
3.
Click the "Create new Client ID" button, select "Service account", and click "Create Client ID"
account in the OAuth section. The file should start with "client
\_
secrets".
This is your _client secrets file_.
4.
Create a new OAuth client ID and select "Service Account" as the type
4.
Click "Generate new JSON key" for the Service Account you just created. A JSON file will be downloaded automatically. This is your
of account. Once created, a JSON file should be downloaded. This is your
_account file_.
_account file_.
## Basic Example
## Basic Example
Below is a fully functioning example. It doesn't do anything useful,
Below is a fully functioning example. It doesn't do anything useful,
since no provisioners are defined, but it will effectively repackage an
since no provisioners are defined, but it will effectively repackage an
existing GCE image. The client secrets file and private key file are the
existing GCE image. The account file is obtained in the previous section.
files obtained in the previous section.
```
javascript
```
javascript
{
{
"
type
"
:
"
googlecompute
"
,
"
type
"
:
"
googlecompute
"
,
"
bucket_name
"
:
"
my-project-packer-images
"
,
"
bucket_name
"
:
"
my-project-packer-images
"
,
"
account_file
"
:
"
account.json
"
,
"
account_file
"
:
"
account.json
"
,
"
client_secrets_file
"
:
"
client_secret.json
"
,
"
project_id
"
:
"
my-project
"
,
"
project_id
"
:
"
my-project
"
,
"
source_image
"
:
"
debian-7-wheezy-v20140718
"
,
"
source_image
"
:
"
debian-7-wheezy-v20140718
"
,
"
zone
"
:
"
us-central1-a
"
"
zone
"
:
"
us-central1-a
"
...
@@ -63,17 +88,8 @@ each category, the available options are alphabetized and described.
...
@@ -63,17 +88,8 @@ each category, the available options are alphabetized and described.
### Required:
### Required:
*
`account_file`
(string) - The JSON file containing your account credentials.
Instructions for how to retrieve these are above.
*
`bucket_name`
(string) - The Google Cloud Storage bucket to store the
*
`bucket_name`
(string) - The Google Cloud Storage bucket to store the
images that are created. The bucket must already exist in your project.
images that are created. The bucket must already exist in your project
*
`client_secrets_file`
(string) - The client secrets JSON file that
was set up in the section above.
*
`private_key_file`
(string) - The client private key file that was
generated in the section above.
*
`project_id`
(string) - The project ID that will be used to launch instances
*
`project_id`
(string) - The project ID that will be used to launch instances
and store images.
and store images.
...
@@ -86,6 +102,10 @@ each category, the available options are alphabetized and described.
...
@@ -86,6 +102,10 @@ each category, the available options are alphabetized and described.
### Optional:
### Optional:
*
`account_file`
(string) - The JSON file containing your account credentials.
Not required if you run Packer on a GCE instance with a service account.
Instructions for creating file or using service accounts are above.
*
`disk_size`
(integer) - The size of the disk in GB.
*
`disk_size`
(integer) - The size of the disk in GB.
This defaults to 10, which is 10GB.
This defaults to 10, which is 10GB.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment