mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-24 23:19:39 -05:00
terraform: support AWS marketplace images (#2888)
* terraform: support AWS marketplace images * terraform-provider: support AWS marketplace images * docs: add instructions on AWS marketplace images * ci: adapt marketplace image test for AWS * Update internal/config/config.go Co-authored-by: Moritz Eckert <m1gh7ym0@gmail.com> * docs: update config * Update docs/docs/getting-started/marketplaces.md Co-authored-by: Thomas Tendyck <51411342+thomasten@users.noreply.github.com> * docs: update license information * docs: use CSP tabs for marketplace overview * Update docs/docs/getting-started/marketplaces.md Co-authored-by: Thomas Tendyck <51411342+thomasten@users.noreply.github.com> * Update docs/docs/getting-started/marketplaces.md Co-authored-by: Thomas Tendyck <51411342+thomasten@users.noreply.github.com> * Update docs/docs/getting-started/marketplaces.md Co-authored-by: Thomas Tendyck <51411342+thomasten@users.noreply.github.com> --------- Co-authored-by: Moritz Eckert <m1gh7ym0@gmail.com> Co-authored-by: Thomas Tendyck <51411342+thomasten@users.noreply.github.com>
This commit is contained in:
parent
64c32c2236
commit
dde3430da8
@ -109,6 +109,13 @@ runs:
|
|||||||
yq eval -i "(.image) = \"${imageInput}\"" constellation-conf.yaml
|
yq eval -i "(.image) = \"${imageInput}\"" constellation-conf.yaml
|
||||||
echo "image=${imageInput}" | tee -a "$GITHUB_OUTPUT"
|
echo "image=${imageInput}" | tee -a "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Set marketplace image flag (AWS)
|
||||||
|
if: inputs.marketplaceImageVersion != '' && inputs.cloudProvider == 'aws'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
yq eval -i "(.provider.aws.useMarketplaceImage) = true" constellation-conf.yaml
|
||||||
|
yq eval -i "(.image) = \"${{ inputs.marketplaceImageVersion }}\"" constellation-conf.yaml
|
||||||
|
|
||||||
- name: Set marketplace image flag (Azure)
|
- name: Set marketplace image flag (Azure)
|
||||||
if: inputs.marketplaceImageVersion != '' && inputs.cloudProvider == 'azure'
|
if: inputs.marketplaceImageVersion != '' && inputs.cloudProvider == 'azure'
|
||||||
shell: bash
|
shell: bash
|
||||||
|
@ -14,8 +14,7 @@ on:
|
|||||||
- "gcp-sev-es"
|
- "gcp-sev-es"
|
||||||
- "azure-sev-snp"
|
- "azure-sev-snp"
|
||||||
- "azure-tdx"
|
- "azure-tdx"
|
||||||
# AWS not yet supported
|
- "aws-sev-snp"
|
||||||
# - "aws-sev-snp"
|
|
||||||
default: "azure-sev-snp"
|
default: "azure-sev-snp"
|
||||||
required: true
|
required: true
|
||||||
runner:
|
runner:
|
||||||
|
@ -91,6 +91,7 @@ func awsTerraformVars(conf *config.Config, imageRef string) *terraform.AWSCluste
|
|||||||
DiskType: group.StateDiskType,
|
DiskType: group.StateDiskType,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &terraform.AWSClusterVariables{
|
return &terraform.AWSClusterVariables{
|
||||||
Name: conf.Name,
|
Name: conf.Name,
|
||||||
NodeGroups: nodeGroups,
|
NodeGroups: nodeGroups,
|
||||||
|
@ -1,12 +1,24 @@
|
|||||||
# Using Constellation via Cloud Marketplaces
|
# Using Constellation via Cloud Marketplaces
|
||||||
|
|
||||||
Constellation is available through the Marketplaces of Azure and GCP. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please [contact us](https://www.edgeless.systems/enterprise-support/).
|
Constellation is available through the Marketplaces of AWS, Azure, and GCP. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please [contact us](https://www.edgeless.systems/enterprise-support/).
|
||||||
|
|
||||||
This document explains how to run Constellation with the dynamically billed cloud marketplace images.
|
This document explains how to run Constellation with the dynamically billed cloud marketplace images.
|
||||||
|
|
||||||
## Azure
|
<tabs groupId="csp">
|
||||||
|
<tabItem value="aws" label="AWS">
|
||||||
|
|
||||||
On Azure, Constellation has a private marketplace plan. Please [contact us](https://www.edgeless.systems/enterprise-support/) to gain access.
|
To use Constellation's marketplace images, ensure that you are subscribed to the [marketplace offering](https://aws.amazon.com/marketplace/pp/prodview-2mbn65nv57oys) through the web portal.
|
||||||
|
|
||||||
|
Then, enable the use of marketplace images in your Constellation `constellation-conf.yaml` [config file](../workflows/config.md):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yq eval -i ".provider.aws.useMarketplaceImage = true" constellation-conf.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
</tabItem>
|
||||||
|
<tabItem value="azure" label="Azure">
|
||||||
|
|
||||||
|
Constellation has a private marketplace plan. Please [contact us](https://www.edgeless.systems/enterprise-support/) to gain access.
|
||||||
|
|
||||||
To use a marketplace image, you need to accept the marketplace image's terms once for your subscription with the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/vm/image/terms?view=azure-cli-latest):
|
To use a marketplace image, you need to accept the marketplace image's terms once for your subscription with the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/vm/image/terms?view=azure-cli-latest):
|
||||||
|
|
||||||
@ -20,13 +32,10 @@ Then, enable the use of marketplace images in your Constellation `constellation-
|
|||||||
yq eval -i ".provider.azure.useMarketplaceImage = true" constellation-conf.yaml
|
yq eval -i ".provider.azure.useMarketplaceImage = true" constellation-conf.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
Ensure that the cluster uses an official release image version (i.e., `.image=vX.Y.Z` in the `constellation-conf.yaml` file).
|
</tabItem>
|
||||||
|
<tabItem value="gcp" label="GCP">
|
||||||
|
|
||||||
From there, you can proceed with the [cluster creation](../workflows/create.md) as usual.
|
To use a marketplace image, ensure that the account is entitled to use marketplace images by Edgeless Systems by accepting the terms through the [web portal](https://console.cloud.google.com/marketplace/vm/config/edgeless-systems-public/constellation).
|
||||||
|
|
||||||
## GCP
|
|
||||||
|
|
||||||
On GCP, to use a marketplace image, ensure that the account is entitled to use marketplace images by Edgeless Systems by accepting the terms through the [web portal](https://console.cloud.google.com/marketplace/vm/config/edgeless-systems-public/constellation).
|
|
||||||
|
|
||||||
Then, enable the use of marketplace images in your Constellation `constellation-conf.yaml` [config file](../workflows/config.md):
|
Then, enable the use of marketplace images in your Constellation `constellation-conf.yaml` [config file](../workflows/config.md):
|
||||||
|
|
||||||
@ -34,6 +43,9 @@ Then, enable the use of marketplace images in your Constellation `constellation-
|
|||||||
yq eval -i ".provider.gcp.useMarketplaceImage = true" constellation-conf.yaml
|
yq eval -i ".provider.gcp.useMarketplaceImage = true" constellation-conf.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</tabItem>
|
||||||
|
</tabs>
|
||||||
|
|
||||||
Ensure that the cluster uses an official release image version (i.e., `.image=vX.Y.Z` in the `constellation-conf.yaml` file).
|
Ensure that the cluster uses an official release image version (i.e., `.image=vX.Y.Z` in the `constellation-conf.yaml` file).
|
||||||
|
|
||||||
From there, you can proceed with the [cluster creation](../workflows/create.md) as usual.
|
From there, you can proceed with the [cluster creation](../workflows/create.md) as usual.
|
||||||
|
@ -30,4 +30,4 @@ Once you have received your Enterprise License file, place it in your [Constella
|
|||||||
|
|
||||||
## CSP Marketplaces
|
## CSP Marketplaces
|
||||||
|
|
||||||
Constellation is available through the Marketplaces of Azure and GCP. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please [contact us](https://www.edgeless.systems/enterprise-support/).
|
Constellation is available through the Marketplaces of AWS, Azure, and GCP. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please [contact us](https://www.edgeless.systems/enterprise-support/).
|
||||||
|
@ -137,6 +137,9 @@ type AWSConfig struct {
|
|||||||
// description: |
|
// description: |
|
||||||
// Deploy Persistent Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage
|
// Deploy Persistent Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage
|
||||||
DeployCSIDriver *bool `yaml:"deployCSIDriver" validate:"required"`
|
DeployCSIDriver *bool `yaml:"deployCSIDriver" validate:"required"`
|
||||||
|
// description: |
|
||||||
|
// Use the specified AWS Marketplace image offering.
|
||||||
|
UseMarketplaceImage *bool `yaml:"useMarketplaceImage" validate:"omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AzureConfig are Azure specific configuration values used by the CLI.
|
// AzureConfig are Azure specific configuration values used by the CLI.
|
||||||
@ -339,6 +342,7 @@ func Default() *Config {
|
|||||||
IAMProfileControlPlane: "",
|
IAMProfileControlPlane: "",
|
||||||
IAMProfileWorkerNodes: "",
|
IAMProfileWorkerNodes: "",
|
||||||
DeployCSIDriver: toPtr(true),
|
DeployCSIDriver: toPtr(true),
|
||||||
|
UseMarketplaceImage: toPtr(false),
|
||||||
},
|
},
|
||||||
Azure: &AzureConfig{
|
Azure: &AzureConfig{
|
||||||
SubscriptionID: "",
|
SubscriptionID: "",
|
||||||
@ -715,7 +719,8 @@ func (c *Config) DeployYawolLoadBalancer() bool {
|
|||||||
// UseMarketplaceImage returns whether a marketplace image should be used.
|
// UseMarketplaceImage returns whether a marketplace image should be used.
|
||||||
func (c *Config) UseMarketplaceImage() bool {
|
func (c *Config) UseMarketplaceImage() bool {
|
||||||
return (c.Provider.Azure != nil && c.Provider.Azure.UseMarketplaceImage != nil && *c.Provider.Azure.UseMarketplaceImage) ||
|
return (c.Provider.Azure != nil && c.Provider.Azure.UseMarketplaceImage != nil && *c.Provider.Azure.UseMarketplaceImage) ||
|
||||||
(c.Provider.GCP != nil && c.Provider.GCP.UseMarketplaceImage != nil && *c.Provider.GCP.UseMarketplaceImage)
|
(c.Provider.GCP != nil && c.Provider.GCP.UseMarketplaceImage != nil && *c.Provider.GCP.UseMarketplaceImage) ||
|
||||||
|
(c.Provider.AWS != nil && c.Provider.AWS.UseMarketplaceImage != nil && *c.Provider.AWS.UseMarketplaceImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate checks the config values and returns validation errors.
|
// Validate checks the config values and returns validation errors.
|
||||||
|
@ -143,7 +143,7 @@ func init() {
|
|||||||
FieldName: "aws",
|
FieldName: "aws",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
AWSConfigDoc.Fields = make([]encoder.Doc, 5)
|
AWSConfigDoc.Fields = make([]encoder.Doc, 6)
|
||||||
AWSConfigDoc.Fields[0].Name = "region"
|
AWSConfigDoc.Fields[0].Name = "region"
|
||||||
AWSConfigDoc.Fields[0].Type = "string"
|
AWSConfigDoc.Fields[0].Type = "string"
|
||||||
AWSConfigDoc.Fields[0].Note = ""
|
AWSConfigDoc.Fields[0].Note = ""
|
||||||
@ -169,6 +169,11 @@ func init() {
|
|||||||
AWSConfigDoc.Fields[4].Note = ""
|
AWSConfigDoc.Fields[4].Note = ""
|
||||||
AWSConfigDoc.Fields[4].Description = "Deploy Persistent Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage"
|
AWSConfigDoc.Fields[4].Description = "Deploy Persistent Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage"
|
||||||
AWSConfigDoc.Fields[4].Comments[encoder.LineComment] = "Deploy Persistent Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage"
|
AWSConfigDoc.Fields[4].Comments[encoder.LineComment] = "Deploy Persistent Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage"
|
||||||
|
AWSConfigDoc.Fields[5].Name = "useMarketplaceImage"
|
||||||
|
AWSConfigDoc.Fields[5].Type = "bool"
|
||||||
|
AWSConfigDoc.Fields[5].Note = ""
|
||||||
|
AWSConfigDoc.Fields[5].Description = "Use the specified AWS Marketplace image offering."
|
||||||
|
AWSConfigDoc.Fields[5].Comments[encoder.LineComment] = "Use the specified AWS Marketplace image offering."
|
||||||
|
|
||||||
AzureConfigDoc.Type = "AzureConfig"
|
AzureConfigDoc.Type = "AzureConfig"
|
||||||
AzureConfigDoc.Comments[encoder.LineComment] = "AzureConfig are Azure specific configuration values used by the CLI."
|
AzureConfigDoc.Comments[encoder.LineComment] = "AzureConfig are Azure specific configuration values used by the CLI."
|
||||||
|
@ -128,6 +128,9 @@ func buildMarketplaceImage(payload marketplaceImagePayload) (string, error) {
|
|||||||
return "", fmt.Errorf("getting image reference: %w", err)
|
return "", fmt.Errorf("getting image reference: %w", err)
|
||||||
}
|
}
|
||||||
return strings.Replace(imageRef, "constellation-images", "mpi-edgeless-systems-public", 1), nil
|
return strings.Replace(imageRef, "constellation-images", "mpi-edgeless-systems-public", 1), nil
|
||||||
|
case cloudprovider.AWS:
|
||||||
|
// For AWS, we use the AMI alias, which just needs the version and infers the rest transparently.
|
||||||
|
return fmt.Sprintf("resolve:ssm:/aws/service/marketplace/prod-77ylkenlkgufs/%s", payload.imgInfo.Version), nil
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("marketplace images are not supported for csp %s", payload.provider.String())
|
return "", fmt.Errorf("marketplace images are not supported for csp %s", payload.provider.String())
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ See the [full list of CSPs](https://docs.edgeless.systems/constellation/overview
|
|||||||
|
|
||||||
### Optional
|
### Optional
|
||||||
|
|
||||||
- `marketplace_image` (Boolean) Whether a marketplace image should be used. Currently only supported for Azure and GCP.
|
- `marketplace_image` (Boolean) Whether a marketplace image should be used.
|
||||||
- `region` (String) Region to retrieve the image for. Only required for AWS.
|
- `region` (String) Region to retrieve the image for. Only required for AWS.
|
||||||
The Constellation OS image must be [replicated to the region](https://docs.edgeless.systems/constellation/workflows/config),and the region must [support AMD SEV-SNP](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snp-requirements.html), if it is used for Attestation.
|
The Constellation OS image must be [replicated to the region](https://docs.edgeless.systems/constellation/workflows/config),and the region must [support AMD SEV-SNP](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snp-requirements.html), if it is used for Attestation.
|
||||||
- `version` (String) Version of the Constellation OS image to use. (e.g. `v2.13.0`). If not set, the provider version value is used.
|
- `version` (String) Version of the Constellation OS image to use. (e.g. `v2.13.0`). If not set, the provider version value is used.
|
||||||
|
@ -87,8 +87,8 @@ func (d *ImageDataSource) Schema(_ context.Context, _ datasource.SchemaRequest,
|
|||||||
},
|
},
|
||||||
"csp": newCSPAttributeSchema(),
|
"csp": newCSPAttributeSchema(),
|
||||||
"marketplace_image": schema.BoolAttribute{
|
"marketplace_image": schema.BoolAttribute{
|
||||||
Description: "Whether a marketplace image should be used. Currently only supported for Azure and GCP.",
|
Description: "Whether a marketplace image should be used.",
|
||||||
MarkdownDescription: "Whether a marketplace image should be used. Currently only supported for Azure and GCP.",
|
MarkdownDescription: "Whether a marketplace image should be used.",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
},
|
},
|
||||||
"region": schema.StringAttribute{
|
"region": schema.StringAttribute{
|
||||||
@ -128,14 +128,6 @@ func (d *ImageDataSource) ValidateConfig(ctx context.Context, req datasource.Val
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marketplace image is only supported for Azure and GCP
|
|
||||||
if data.CSP.Equal(types.StringValue("aws")) && !data.MarketplaceImage.IsNull() {
|
|
||||||
resp.Diagnostics.AddAttributeError(
|
|
||||||
path.Root("marketplace_image"),
|
|
||||||
"Marketplace images are currently only supported on Azure and GCP", "When another CSP than Azure or GCP is used, marketplace images are unavailable.",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version should be a valid semver or short path, if set
|
// Version should be a valid semver or short path, if set
|
||||||
if !data.Version.IsNull() {
|
if !data.Version.IsNull() {
|
||||||
_, semverErr := semver.New(data.Version.ValueString())
|
_, semverErr := semver.New(data.Version.ValueString())
|
||||||
|
@ -72,6 +72,24 @@ func TestAccImageDataSource(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"aws marketplace success": {
|
||||||
|
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
|
||||||
|
PreCheck: bazelPreCheck,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testingConfig + `
|
||||||
|
data "constellation_image" "test" {
|
||||||
|
version = "v2.13.0"
|
||||||
|
attestation_variant = "aws-sev-snp"
|
||||||
|
csp = "aws"
|
||||||
|
marketplace_image = true
|
||||||
|
region = "eu-west-1"
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
Check: resource.TestCheckResourceAttr("data.constellation_image.test", "image.reference", "resolve:ssm:/aws/service/marketplace/prod-77ylkenlkgufs/v2.13.0"), // should be immutable,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
"azure success": {
|
"azure success": {
|
||||||
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
|
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
|
||||||
PreCheck: bazelPreCheck,
|
PreCheck: bazelPreCheck,
|
||||||
@ -171,6 +189,23 @@ func TestAccImageDataSource(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"gcp marketplace success": {
|
||||||
|
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
|
||||||
|
PreCheck: bazelPreCheck,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testingConfig + `
|
||||||
|
data "constellation_image" "test" {
|
||||||
|
version = "v2.13.0"
|
||||||
|
attestation_variant = "gcp-sev-es"
|
||||||
|
csp = "gcp"
|
||||||
|
marketplace_image = true
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
Check: resource.TestCheckResourceAttr("data.constellation_image.test", "image.reference", "projects/mpi-edgeless-systems-public/global/images/v2-13-0-gcp-sev-es-stable"), // should be immutable,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, tc := range testCases {
|
for name, tc := range testCases {
|
||||||
|
@ -32,10 +32,6 @@ variable "node_groups" {
|
|||||||
variable "image_id" {
|
variable "image_id" {
|
||||||
type = string
|
type = string
|
||||||
description = "Amazon Machine Image (AMI) ID for the cluster's nodes."
|
description = "Amazon Machine Image (AMI) ID for the cluster's nodes."
|
||||||
validation {
|
|
||||||
condition = length(var.image_id) > 4 && substr(var.image_id, 0, 4) == "ami-"
|
|
||||||
error_message = "The \"image_id\" value must be a valid AMI ID, starting with \"ami-\"."
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "debug" {
|
variable "debug" {
|
||||||
|
Loading…
Reference in New Issue
Block a user