Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for Secure Boot UEFI keys in Azure images #70

Merged
merged 1 commit into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ terraform {
required_providers {
imagefactory = {
source = "nordcloud/imagefactory"
version = "1.9.1"
version = "1.10.0"
}
}
}
Expand Down
33 changes: 33 additions & 0 deletions docs/resources/template.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,30 @@ resource "imagefactory_template" "azure_template" {
}
}

# AZURE Template - additional signatures on Gen2 images

resource "imagefactory_variable" "uefi_key" {
name = "UEFI_KEY"
value = "MIIDQTCCAimgAwIBAgIQDd70KTXzSXuUqRAfm+RzqzANBgkqhkiG9w0BAQsFADAj...."
}

resource "imagefactory_template" "azure_template" {
name = "Ubuntu1804"
description = "Ubuntu 18.04 on Azure"
cloud_provider = "AZURE"
distribution_id = data.imagefactory_distribution.ubuntu18.id
config {
azure {
trusted_launch = true
additional_signatures {
variable_name = imagefactory_variable.uefi_key.name
# If the variable is not defined in the template, the value can be set directly
# variable_value = "UEFI_KEY"
}
}
}
}

output "azure_template" {
value = imagefactory_template.azure_template
}
Expand Down Expand Up @@ -308,6 +332,7 @@ Required:
Optional:

- `additional_data_disks` (Block List, Max: 10) (see [below for nested schema](#nestedblock--config--azure--additional_data_disks))
- `additional_signatures` (Block List) Additional UEFI keys that are used to validate the boot loader. This feature allows you to bind UEFI keys for driver/kernel modules that are signed by using a private key that's owned by third-party vendors. (see [below for nested schema](#nestedblock--config--azure--additional_signatures))
- `eol_date_option` (Boolean) Default value is set to true
- `exclude_from_latest` (Boolean)
- `replica_regions` (List of String)
Expand All @@ -322,6 +347,14 @@ Required:
- `size` (Number) Data disk size between 1 and 10 GB.


<a id="nestedblock--config--azure--additional_signatures"></a>
### Nested Schema for `config.azure.additional_signatures`

Required:

- `variable_name` (String) The name of the Customer Variable that is used to store the UEFI key.


<a id="nestedblock--config--azure--vm_image_definition"></a>
### Nested Schema for `config.azure.vm_image_definition`

Expand Down
2 changes: 1 addition & 1 deletion examples/provider/provider.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ terraform {
required_providers {
imagefactory = {
source = "nordcloud/imagefactory"
version = "1.9.1"
version = "1.10.0"
}
}
}
Expand Down
24 changes: 24 additions & 0 deletions examples/resources/imagefactory_template/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,30 @@ resource "imagefactory_template" "azure_template" {
}
}

# AZURE Template - additional signatures on Gen2 images

resource "imagefactory_variable" "uefi_key" {
name = "UEFI_KEY"
value = "MIIDQTCCAimgAwIBAgIQDd70KTXzSXuUqRAfm+RzqzANBgkqhkiG9w0BAQsFADAj...."
}

resource "imagefactory_template" "azure_template" {
name = "Ubuntu1804"
description = "Ubuntu 18.04 on Azure"
cloud_provider = "AZURE"
distribution_id = data.imagefactory_distribution.ubuntu18.id
config {
azure {
trusted_launch = true
additional_signatures {
variable_name = imagefactory_variable.uefi_key.name
# If the variable is not defined in the template, the value can be set directly
# variable_value = "UEFI_KEY"
}
}
}
}

output "azure_template" {
value = imagefactory_template.azure_template
}
Expand Down
18 changes: 18 additions & 0 deletions imagefactory/imagetemplate/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ var additionalDataDisksResource = &schema.Resource{
},
}

var additionalSignaturesResource = &schema.Resource{
Schema: map[string]*schema.Schema{
"variable_name": {
Type: schema.TypeString,
Required: true,
Description: "The name of the Customer Variable that is used to store the UEFI key.",
},
},
}

var azureTemplateConfigResource = &schema.Resource{
Schema: map[string]*schema.Schema{
"exclude_from_latest": {
Expand Down Expand Up @@ -162,6 +172,14 @@ var azureTemplateConfigResource = &schema.Resource{
Type: schema.TypeBool,
Optional: true,
},
"additional_signatures": {
Type: schema.TypeList,
Optional: true,
Elem: additionalSignaturesResource,
Description: "Additional UEFI keys that are used to validate the boot loader. " +
"This feature allows you to bind UEFI keys for driver/kernel modules that " +
"are signed by using a private key that's owned by third-party vendors.",
},
},
}

Expand Down
16 changes: 16 additions & 0 deletions imagefactory/imagetemplate/structures.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,18 @@ func expandAdditionalDataDisks(in []interface{}) *[]graphql.NewAdditionalDataDis
return &out
}

func expandAdditionalSignatures(in []interface{}) *[]graphql.NewUefiKey {
out := []graphql.NewUefiKey{}
for i := range in {
m := in[i].(map[string]interface{})
out = append(out, graphql.NewUefiKey{
VariableName: graphql.String(m["variable_name"].(string)),
})
}

return &out
}

func expandTemplateAzureConfig(in []interface{}) *graphql.NewTemplateAZUREConfig {
if len(in) == 0 {
return nil
Expand Down Expand Up @@ -149,6 +161,10 @@ func expandTemplateAzureConfig(in []interface{}) *graphql.NewTemplateAZUREConfig
out.AdditionalDataDisks = expandAdditionalDataDisks(m["additional_data_disks"].([]interface{}))
}

if m["additional_signatures"] != nil {
out.AdditionalSignatures = expandAdditionalSignatures(m["additional_signatures"].([]interface{}))
}

return out
}

Expand Down
50 changes: 38 additions & 12 deletions pkg/graphql/graphql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 35 additions & 1 deletion pkg/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ type CustomerStats {
}


# Copyright 2021-2023 Nordcloud Oy or its affiliates. All Rights Reserved.
# Copyright 2021-2024 Nordcloud Oy or its affiliates. All Rights Reserved.

"""
Distribution defines the cloud image that can be created by the ImageFactory.
Expand All @@ -631,6 +631,7 @@ type Distribution {
osEolDate: String
complianceScore: ComplianceScore
deprecated: Boolean
config: Config
}

type ComplianceScore {
Expand All @@ -644,6 +645,19 @@ type DistributionResults {
count: Int!
}

type Config {
azure: AZUREConfig
}

enum HyperVGeneration {
HYPERV_GENERATION_V1
HYPERV_GENERATION_V2
}

type AZUREConfig {
hypervGeneration: HyperVGeneration
}


# Copyright 2022-2024 Nordcloud Oy or its affiliates. All Rights Reserved.

Expand Down Expand Up @@ -1010,13 +1024,18 @@ type AdditionalDataDisks {
size: Int!
}

type UefiKey {
variableName: String!
}

type TemplateAZUREConfig {
replicaRegions: [String]
excludeFromLatest: Boolean
vmImageDefinition: VMImageDefinition
eolDateOption: Boolean
additionalDataDisks: [AdditionalDataDisks!]
trustedLaunch: Boolean
additionalSignatures: [UefiKey!]
}

type TemplateExoscaleConfig {
Expand Down Expand Up @@ -1150,6 +1169,13 @@ input NewVMImageDefinition {
sku: String!
}

input NewUefiKey {
"""
variableName is the name of the Customer Variable that is used to store the UEFI key.
"""
variableName: String!
}

input NewAdditionalDataDisks {
"""
size is in GB, from 1G to 10G.
Expand All @@ -1172,6 +1198,14 @@ input NewTemplateAZUREConfig {
"""
trustedLaunch: Boolean

"""
`additionalSignatures` defines additional UEFI keys that are used to validate the boot loader.

This feature allows you to bind unified extensible firmware interface (UEFI) keys for driver/kernel modules
that are signed by using a private key that's owned by third-party vendors.
"""
additionalSignatures: [NewUefiKey!]

"""
`additionalDataDisks` defines extra data disks attached to the image with a limit of 10.

Expand Down
Loading