Add ability to use custom keyvault into azure builds
This commit is contained in:
parent
a1d9ba0e32
commit
6d6b94d515
|
@ -231,8 +231,16 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
||||||
keyVaultDeploymentName := b.stateBag.Get(constants.ArmKeyVaultDeploymentName).(string)
|
keyVaultDeploymentName := b.stateBag.Get(constants.ArmKeyVaultDeploymentName).(string)
|
||||||
steps = []multistep.Step{
|
steps = []multistep.Step{
|
||||||
NewStepCreateResourceGroup(azureClient, ui),
|
NewStepCreateResourceGroup(azureClient, ui),
|
||||||
NewStepValidateTemplate(azureClient, ui, &b.config, GetKeyVaultDeployment),
|
}
|
||||||
NewStepDeployTemplate(azureClient, ui, &b.config, keyVaultDeploymentName, GetKeyVaultDeployment),
|
if b.config.BuildKeyVaultName == "" {
|
||||||
|
steps = append(steps,
|
||||||
|
NewStepValidateTemplate(azureClient, ui, &b.config, GetKeyVaultDeployment),
|
||||||
|
NewStepDeployTemplate(azureClient, ui, &b.config, keyVaultDeploymentName, GetKeyVaultDeployment),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
steps = append(steps, NewStepCertificateInKeyVault(azureClient, ui, &b.config))
|
||||||
|
}
|
||||||
|
steps = append(steps,
|
||||||
NewStepGetCertificate(azureClient, ui),
|
NewStepGetCertificate(azureClient, ui),
|
||||||
NewStepSetCertificate(&b.config, ui),
|
NewStepSetCertificate(&b.config, ui),
|
||||||
NewStepValidateTemplate(azureClient, ui, &b.config, GetVirtualMachineDeployment),
|
NewStepValidateTemplate(azureClient, ui, &b.config, GetVirtualMachineDeployment),
|
||||||
|
@ -261,7 +269,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
||||||
NewStepDeleteResourceGroup(azureClient, ui),
|
NewStepDeleteResourceGroup(azureClient, ui),
|
||||||
NewStepDeleteOSDisk(azureClient, ui),
|
NewStepDeleteOSDisk(azureClient, ui),
|
||||||
NewStepDeleteAdditionalDisks(azureClient, ui),
|
NewStepDeleteAdditionalDisks(azureClient, ui),
|
||||||
}
|
)
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("Builder does not support the os_type '%s'", b.config.OSType)
|
return nil, fmt.Errorf("Builder does not support the os_type '%s'", b.config.OSType)
|
||||||
}
|
}
|
||||||
|
@ -395,7 +403,14 @@ func (b *Builder) configureStateBag(stateBag multistep.StateBag) {
|
||||||
stateBag.Put(constants.ArmKeyVaultDeploymentName, fmt.Sprintf("kv%s", b.config.tmpDeploymentName))
|
stateBag.Put(constants.ArmKeyVaultDeploymentName, fmt.Sprintf("kv%s", b.config.tmpDeploymentName))
|
||||||
}
|
}
|
||||||
|
|
||||||
stateBag.Put(constants.ArmKeyVaultName, b.config.tmpKeyVaultName)
|
if b.config.BuildKeyVaultName != "" {
|
||||||
|
stateBag.Put(constants.ArmKeyVaultName, b.config.BuildKeyVaultName)
|
||||||
|
b.config.tmpKeyVaultName = b.config.BuildKeyVaultName
|
||||||
|
stateBag.Put(constants.ArmIsExistingKeyVault, false)
|
||||||
|
} else {
|
||||||
|
stateBag.Put(constants.ArmKeyVaultName, b.config.tmpKeyVaultName)
|
||||||
|
stateBag.Put(constants.ArmIsExistingKeyVault, true)
|
||||||
|
}
|
||||||
stateBag.Put(constants.ArmNicName, b.config.tmpNicName)
|
stateBag.Put(constants.ArmNicName, b.config.tmpNicName)
|
||||||
stateBag.Put(constants.ArmPublicIPAddressName, b.config.tmpPublicIPAddressName)
|
stateBag.Put(constants.ArmPublicIPAddressName, b.config.tmpPublicIPAddressName)
|
||||||
stateBag.Put(constants.ArmResourceGroupName, b.config.BuildResourceGroupName)
|
stateBag.Put(constants.ArmResourceGroupName, b.config.BuildResourceGroupName)
|
||||||
|
|
|
@ -253,7 +253,10 @@ type Config struct {
|
||||||
// group is deleted at the end of the build.
|
// group is deleted at the end of the build.
|
||||||
TempResourceGroupName string `mapstructure:"temp_resource_group_name"`
|
TempResourceGroupName string `mapstructure:"temp_resource_group_name"`
|
||||||
// Specify an existing resource group to run the build in.
|
// Specify an existing resource group to run the build in.
|
||||||
BuildResourceGroupName string `mapstructure:"build_resource_group_name"`
|
BuildResourceGroupName string `mapstructure:"build_resource_group_name"`
|
||||||
|
// Specify an existing key vault to use for uploading certificates to the
|
||||||
|
// instance to connect.
|
||||||
|
BuildKeyVaultName string `mapstructure:"build_key_vault_name"`
|
||||||
storageAccountBlobEndpoint string
|
storageAccountBlobEndpoint string
|
||||||
// This value allows you to
|
// This value allows you to
|
||||||
// set a virtual_network_name and obtain a public IP. If this value is not
|
// set a virtual_network_name and obtain a public IP. If this value is not
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package arm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/packer/builder/azure/common/constants"
|
||||||
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
|
"github.com/hashicorp/packer/packer"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StepCertificateInKeyVault struct {
|
||||||
|
config *Config
|
||||||
|
client *AzureClient
|
||||||
|
say func(message string)
|
||||||
|
error func(e error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStepCertificateInKeyVault(cli *AzureClient, ui packer.Ui, config *Config) *StepCertificateInKeyVault {
|
||||||
|
var step = &StepCertificateInKeyVault{
|
||||||
|
client: cli,
|
||||||
|
config: config,
|
||||||
|
say: func(message string) { ui.Say(message) },
|
||||||
|
error: func(e error) { ui.Error(e.Error()) },
|
||||||
|
}
|
||||||
|
|
||||||
|
return step
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepCertificateInKeyVault) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||||
|
s.say("Setting the certificate in the KeyVault...")
|
||||||
|
|
||||||
|
var keyVaultName = state.Get(constants.ArmKeyVaultName).(string)
|
||||||
|
// err := s.client.CreateKey(keyVaultName, DefaultSecretName)
|
||||||
|
// if err != nil {
|
||||||
|
// s.error(fmt.Errorf("Error setting winrm cert in custom keyvault: %s", err))
|
||||||
|
// return multistep.ActionHalt
|
||||||
|
// }
|
||||||
|
|
||||||
|
err := s.client.SetSecret(keyVaultName, DefaultSecretName, s.config.winrmCertificate)
|
||||||
|
if err != nil {
|
||||||
|
s.error(fmt.Errorf("Error setting winrm cert in custom keyvault: %s", err))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
return multistep.ActionContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*StepCertificateInKeyVault) Cleanup(multistep.StateBag) {
|
||||||
|
}
|
|
@ -44,9 +44,12 @@ func (s *StepDeleteResourceGroup) deleteResourceGroup(ctx context.Context, state
|
||||||
}
|
}
|
||||||
|
|
||||||
if keyVaultDeploymentName, ok := state.GetOk(constants.ArmKeyVaultDeploymentName); ok {
|
if keyVaultDeploymentName, ok := state.GetOk(constants.ArmKeyVaultDeploymentName); ok {
|
||||||
err = s.deleteDeploymentResources(ctx, keyVaultDeploymentName.(string), resourceGroupName)
|
// Only delete if custom keyvault was not provided.
|
||||||
if err != nil {
|
if exists := state.Get(constants.ArmIsExistingKeyVault).(bool); exists {
|
||||||
return err
|
err = s.deleteDeploymentResources(ctx, keyVaultDeploymentName.(string), resourceGroupName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,10 @@ func (s *StepDeployTemplate) deleteTemplate(ctx context.Context, state multistep
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StepDeployTemplate) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
func (s *StepDeployTemplate) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||||
|
if s.config.BuildKeyVaultName != "" {
|
||||||
|
// Deployment already exists
|
||||||
|
|
||||||
|
}
|
||||||
s.say("Deploying deployment template ...")
|
s.say("Deploying deployment template ...")
|
||||||
|
|
||||||
var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string)
|
var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string)
|
||||||
|
|
|
@ -36,6 +36,7 @@ const (
|
||||||
ArmTags string = "arm.Tags"
|
ArmTags string = "arm.Tags"
|
||||||
ArmVirtualMachineCaptureParameters string = "arm.VirtualMachineCaptureParameters"
|
ArmVirtualMachineCaptureParameters string = "arm.VirtualMachineCaptureParameters"
|
||||||
ArmIsExistingResourceGroup string = "arm.IsExistingResourceGroup"
|
ArmIsExistingResourceGroup string = "arm.IsExistingResourceGroup"
|
||||||
|
ArmIsExistingKeyVault string = "arm.IsExistingKeyVault"
|
||||||
|
|
||||||
ArmIsManagedImage string = "arm.IsManagedImage"
|
ArmIsManagedImage string = "arm.IsManagedImage"
|
||||||
ArmManagedImageResourceGroupName string = "arm.ManagedImageResourceGroupName"
|
ArmManagedImageResourceGroupName string = "arm.ManagedImageResourceGroupName"
|
||||||
|
|
|
@ -54,7 +54,8 @@ func (client *VaultClient) GetSecret(vaultName, secretName string) (*Secret, err
|
||||||
autorest.AsGet(),
|
autorest.AsGet(),
|
||||||
autorest.WithBaseURL(client.getVaultUrl(vaultName)),
|
autorest.WithBaseURL(client.getVaultUrl(vaultName)),
|
||||||
autorest.WithPathParameters("/secrets/{secret-name}", p),
|
autorest.WithPathParameters("/secrets/{secret-name}", p),
|
||||||
autorest.WithQueryParameters(q))
|
autorest.WithQueryParameters(q),
|
||||||
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -86,6 +87,47 @@ func (client *VaultClient) GetSecret(vaultName, secretName string) (*Secret, err
|
||||||
return &secret, nil
|
return &secret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (client *VaultClient) SetSecret(vaultName, secretName string, secretValue string) error {
|
||||||
|
p := map[string]interface{}{
|
||||||
|
"secret-name": autorest.Encode("path", secretName),
|
||||||
|
}
|
||||||
|
q := map[string]interface{}{
|
||||||
|
"api-version": AzureVaultApiVersion,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonBody := fmt.Sprintf(`{"value": "%s"}`, secretValue)
|
||||||
|
|
||||||
|
req, err := autorest.Prepare(
|
||||||
|
&http.Request{},
|
||||||
|
autorest.AsPut(),
|
||||||
|
autorest.AsContentType("application/json; charset=utf-8"),
|
||||||
|
autorest.WithBaseURL(client.getVaultUrl(vaultName)),
|
||||||
|
autorest.WithPathParameters("/secrets/{secret-name}", p),
|
||||||
|
autorest.WithQueryParameters(q),
|
||||||
|
autorest.WithString(jsonBody),
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := autorest.SendWithSender(client, req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"Failed to set secret to %s/%s, HTTP status code=%d (%s)",
|
||||||
|
vaultName,
|
||||||
|
secretName,
|
||||||
|
resp.StatusCode,
|
||||||
|
http.StatusText(resp.StatusCode))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Delete deletes the specified Azure key vault.
|
// Delete deletes the specified Azure key vault.
|
||||||
//
|
//
|
||||||
// resourceGroupName is the name of the Resource Group to which the vault belongs. vaultName is the name of the vault
|
// resourceGroupName is the name of the Resource Group to which the vault belongs. vaultName is the name of the vault
|
||||||
|
|
Loading…
Reference in New Issue