mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-07-22 06:50:43 -04:00
gcp: support projects with no default permissions (#3656)
* helm/gcp: use service account in operator and joinservice * helm: format operator testdata * terraform/iam: create additional service account for VMs This service account is used in the following commits and is attached to the VMs * config: pass VM service account from iam create to cluster create via config * cli/iamcreate: limit name prefix length * docs: add minimal gcp IAM permissions
This commit is contained in:
parent
83e08e3e37
commit
66815a4a47
42 changed files with 771 additions and 466 deletions
|
@ -102,6 +102,7 @@ runs:
|
||||||
--tf-log=DEBUG \
|
--tf-log=DEBUG \
|
||||||
--yes ${extraFlags}
|
--yes ${extraFlags}
|
||||||
|
|
||||||
|
# TODO(@3u13r): Replace deprecated --serviceAccountID with --prefix
|
||||||
- name: Constellation iam create gcp
|
- name: Constellation iam create gcp
|
||||||
shell: bash
|
shell: bash
|
||||||
if: inputs.cloudProvider == 'gcp'
|
if: inputs.cloudProvider == 'gcp'
|
||||||
|
|
6
.github/actions/e2e_test/action.yml
vendored
6
.github/actions/e2e_test/action.yml
vendored
|
@ -258,6 +258,12 @@ runs:
|
||||||
run: |
|
run: |
|
||||||
uuid=$(uuidgen | tr "[:upper:]" "[:lower:]")
|
uuid=$(uuidgen | tr "[:upper:]" "[:lower:]")
|
||||||
uuid=${uuid%%-*}
|
uuid=${uuid%%-*}
|
||||||
|
|
||||||
|
# GCP has a 6 character limit the additional uuid prefix since the full prefix length has a maximum of 24
|
||||||
|
if [[ ${{ inputs.cloudProvider }} == 'gcp' ]]; then
|
||||||
|
uuid=${uuid:0:6}
|
||||||
|
fi
|
||||||
|
|
||||||
echo "uuid=${uuid}" | tee -a $GITHUB_OUTPUT
|
echo "uuid=${uuid}" | tee -a $GITHUB_OUTPUT
|
||||||
echo "prefix=e2e-${{ github.run_id }}-${{ github.run_attempt }}-${uuid}" | tee -a $GITHUB_OUTPUT
|
echo "prefix=e2e-${{ github.run_id }}-${{ github.run_attempt }}-${uuid}" | tee -a $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,7 @@ type GCPIAMConfig struct {
|
||||||
Zone string
|
Zone string
|
||||||
ProjectID string
|
ProjectID string
|
||||||
ServiceAccountID string
|
ServiceAccountID string
|
||||||
|
NamePrefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
// AzureIAMConfig holds the necessary values for Azure IAM configuration.
|
// AzureIAMConfig holds the necessary values for Azure IAM configuration.
|
||||||
|
@ -141,6 +142,7 @@ func (c *IAMCreator) createGCP(ctx context.Context, cl tfIAMClient, opts *IAMCon
|
||||||
|
|
||||||
vars := terraform.GCPIAMVariables{
|
vars := terraform.GCPIAMVariables{
|
||||||
ServiceAccountID: opts.GCP.ServiceAccountID,
|
ServiceAccountID: opts.GCP.ServiceAccountID,
|
||||||
|
NamePrefix: opts.GCP.NamePrefix,
|
||||||
Project: opts.GCP.ProjectID,
|
Project: opts.GCP.ProjectID,
|
||||||
Region: opts.GCP.Region,
|
Region: opts.GCP.Region,
|
||||||
Zone: opts.GCP.Zone,
|
Zone: opts.GCP.Zone,
|
||||||
|
@ -159,6 +161,7 @@ func (c *IAMCreator) createGCP(ctx context.Context, cl tfIAMClient, opts *IAMCon
|
||||||
CloudProvider: cloudprovider.GCP,
|
CloudProvider: cloudprovider.GCP,
|
||||||
GCPOutput: GCPIAMOutput{
|
GCPOutput: GCPIAMOutput{
|
||||||
ServiceAccountKey: iamOutput.GCP.SaKey,
|
ServiceAccountKey: iamOutput.GCP.SaKey,
|
||||||
|
IAMServiceAccountVM: iamOutput.GCP.ServiceAccountVMMailAddress,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -233,6 +236,7 @@ type IAMOutput struct {
|
||||||
// GCPIAMOutput contains the output information of a GCP IAM configuration.
|
// GCPIAMOutput contains the output information of a GCP IAM configuration.
|
||||||
type GCPIAMOutput struct {
|
type GCPIAMOutput struct {
|
||||||
ServiceAccountKey string `json:"serviceAccountID,omitempty"`
|
ServiceAccountKey string `json:"serviceAccountID,omitempty"`
|
||||||
|
IAMServiceAccountVM string `json:"iamServiceAccountVM,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AzureIAMOutput contains the output information of a Microsoft Azure IAM configuration.
|
// AzureIAMOutput contains the output information of a Microsoft Azure IAM configuration.
|
||||||
|
|
|
@ -22,6 +22,9 @@ import (
|
||||||
// UpgradeRequiresIAMMigration returns true if the given cloud provider requires an IAM migration.
|
// UpgradeRequiresIAMMigration returns true if the given cloud provider requires an IAM migration.
|
||||||
func UpgradeRequiresIAMMigration(provider cloudprovider.Provider) bool {
|
func UpgradeRequiresIAMMigration(provider cloudprovider.Provider) bool {
|
||||||
switch provider {
|
switch provider {
|
||||||
|
case cloudprovider.GCP:
|
||||||
|
// TODO(@3u13r): remove this case after the v2.22.0 release
|
||||||
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,6 +231,7 @@ func gcpTerraformVars(conf *config.Config, imageRef string) *terraform.GCPCluste
|
||||||
InternalLoadBalancer: conf.InternalLoadBalancer,
|
InternalLoadBalancer: conf.InternalLoadBalancer,
|
||||||
CCTechnology: ccTech,
|
CCTechnology: ccTech,
|
||||||
AdditionalLabels: conf.Tags,
|
AdditionalLabels: conf.Tags,
|
||||||
|
IAMServiceAccountVM: conf.Provider.GCP.IAMServiceAccountVM,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,6 +241,7 @@ func gcpTerraformIAMVars(conf *config.Config, oldVars terraform.GCPIAMVariables)
|
||||||
Region: conf.Provider.GCP.Region,
|
Region: conf.Provider.GCP.Region,
|
||||||
Zone: conf.Provider.GCP.Zone,
|
Zone: conf.Provider.GCP.Zone,
|
||||||
ServiceAccountID: oldVars.ServiceAccountID,
|
ServiceAccountID: oldVars.ServiceAccountID,
|
||||||
|
NamePrefix: oldVars.NamePrefix,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -256,6 +256,7 @@ func TestValidateInputs(t *testing.T) {
|
||||||
ClientX509CertURL: "client_cert",
|
ClientX509CertURL: "client_cert",
|
||||||
}))
|
}))
|
||||||
cfg.Provider.GCP.ServiceAccountKeyPath = "saKey.json"
|
cfg.Provider.GCP.ServiceAccountKeyPath = "saKey.json"
|
||||||
|
cfg.Provider.GCP.IAMServiceAccountVM = "example@example.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(fh.WriteYAML(constants.ConfigFilename, cfg))
|
require.NoError(fh.WriteYAML(constants.ConfigFilename, cfg))
|
||||||
|
|
|
@ -29,6 +29,9 @@ var (
|
||||||
regionRegex = regexp.MustCompile(`^\w+-\w+[0-9]$`)
|
regionRegex = regexp.MustCompile(`^\w+-\w+[0-9]$`)
|
||||||
// Source: https://cloud.google.com/resource-manager/reference/rest/v1/projects.
|
// Source: https://cloud.google.com/resource-manager/reference/rest/v1/projects.
|
||||||
gcpIDRegex = regexp.MustCompile(`^[a-z][-a-z0-9]{4,28}[a-z0-9]$`)
|
gcpIDRegex = regexp.MustCompile(`^[a-z][-a-z0-9]{4,28}[a-z0-9]$`)
|
||||||
|
|
||||||
|
// We currently append 6 characters to the prefix, therefore we remove 6 characters from the gcpIDRegex.
|
||||||
|
gcpPrefixRegex = regexp.MustCompile(`^[a-z][-a-z0-9]{4,22}[a-z0-9]$`)
|
||||||
)
|
)
|
||||||
|
|
||||||
// newIAMCreateCmd returns a new cobra.Command for the iam create parent command. It needs another verb, and does nothing on its own.
|
// newIAMCreateCmd returns a new cobra.Command for the iam create parent command. It needs another verb, and does nothing on its own.
|
||||||
|
|
|
@ -456,6 +456,7 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
creator *stubIAMCreator
|
creator *stubIAMCreator
|
||||||
zoneFlag string
|
zoneFlag string
|
||||||
serviceAccountIDFlag string
|
serviceAccountIDFlag string
|
||||||
|
namePrefixFlag string
|
||||||
projectIDFlag string
|
projectIDFlag string
|
||||||
yesFlag bool
|
yesFlag bool
|
||||||
updateConfigFlag bool
|
updateConfigFlag bool
|
||||||
|
@ -466,6 +467,14 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
"iam create gcp": {
|
"iam create gcp": {
|
||||||
|
setupFs: defaultFs,
|
||||||
|
creator: &stubIAMCreator{id: validIAMIDFile},
|
||||||
|
zoneFlag: "europe-west1-a",
|
||||||
|
namePrefixFlag: "constell-test",
|
||||||
|
projectIDFlag: "constell-1234",
|
||||||
|
yesFlag: true,
|
||||||
|
},
|
||||||
|
"iam create gcp with deprecated serice account flag": {
|
||||||
setupFs: defaultFs,
|
setupFs: defaultFs,
|
||||||
creator: &stubIAMCreator{id: validIAMIDFile},
|
creator: &stubIAMCreator{id: validIAMIDFile},
|
||||||
zoneFlag: "europe-west1-a",
|
zoneFlag: "europe-west1-a",
|
||||||
|
@ -477,7 +486,7 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
setupFs: defaultFs,
|
setupFs: defaultFs,
|
||||||
creator: &stubIAMCreator{id: validIAMIDFile},
|
creator: &stubIAMCreator{id: validIAMIDFile},
|
||||||
zoneFlag: "europe-west1-a",
|
zoneFlag: "europe-west1-a",
|
||||||
serviceAccountIDFlag: "constell-test",
|
namePrefixFlag: "constell-test",
|
||||||
projectIDFlag: "constell-1234",
|
projectIDFlag: "constell-1234",
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
existingConfigFiles: []string{constants.ConfigFilename},
|
existingConfigFiles: []string{constants.ConfigFilename},
|
||||||
|
@ -486,7 +495,7 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
setupFs: defaultFs,
|
setupFs: defaultFs,
|
||||||
creator: &stubIAMCreator{id: validIAMIDFile},
|
creator: &stubIAMCreator{id: validIAMIDFile},
|
||||||
zoneFlag: "europe-west1-a",
|
zoneFlag: "europe-west1-a",
|
||||||
serviceAccountIDFlag: "constell-test",
|
namePrefixFlag: "constell-test",
|
||||||
projectIDFlag: "constell-1234",
|
projectIDFlag: "constell-1234",
|
||||||
updateConfigFlag: true,
|
updateConfigFlag: true,
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
|
@ -496,7 +505,7 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
setupFs: defaultFs,
|
setupFs: defaultFs,
|
||||||
creator: &stubIAMCreator{id: validIAMIDFile},
|
creator: &stubIAMCreator{id: validIAMIDFile},
|
||||||
zoneFlag: "europe-west1-a",
|
zoneFlag: "europe-west1-a",
|
||||||
serviceAccountIDFlag: "constell-test",
|
namePrefixFlag: "constell-test",
|
||||||
projectIDFlag: "constell-1234",
|
projectIDFlag: "constell-1234",
|
||||||
|
|
||||||
existingDirs: []string{constants.TerraformIAMWorkingDir},
|
existingDirs: []string{constants.TerraformIAMWorkingDir},
|
||||||
|
@ -507,7 +516,7 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
setupFs: defaultFs,
|
setupFs: defaultFs,
|
||||||
creator: &stubIAMCreator{id: invalidIAMIDFile},
|
creator: &stubIAMCreator{id: invalidIAMIDFile},
|
||||||
zoneFlag: "europe-west1-a",
|
zoneFlag: "europe-west1-a",
|
||||||
serviceAccountIDFlag: "constell-test",
|
namePrefixFlag: "constell-test",
|
||||||
projectIDFlag: "constell-1234",
|
projectIDFlag: "constell-1234",
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
|
@ -516,7 +525,7 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
setupFs: defaultFs,
|
setupFs: defaultFs,
|
||||||
creator: &stubIAMCreator{id: validIAMIDFile},
|
creator: &stubIAMCreator{id: validIAMIDFile},
|
||||||
zoneFlag: "europe-west1-a",
|
zoneFlag: "europe-west1-a",
|
||||||
serviceAccountIDFlag: "constell-test",
|
namePrefixFlag: "constell-test",
|
||||||
projectIDFlag: "constell-1234",
|
projectIDFlag: "constell-1234",
|
||||||
stdin: "yes\n",
|
stdin: "yes\n",
|
||||||
},
|
},
|
||||||
|
@ -524,7 +533,7 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
setupFs: defaultFs,
|
setupFs: defaultFs,
|
||||||
creator: &stubIAMCreator{id: validIAMIDFile},
|
creator: &stubIAMCreator{id: validIAMIDFile},
|
||||||
zoneFlag: "europe-west1-a",
|
zoneFlag: "europe-west1-a",
|
||||||
serviceAccountIDFlag: "constell-test",
|
namePrefixFlag: "constell-test",
|
||||||
projectIDFlag: "constell-1234",
|
projectIDFlag: "constell-1234",
|
||||||
stdin: "yes\n",
|
stdin: "yes\n",
|
||||||
updateConfigFlag: true,
|
updateConfigFlag: true,
|
||||||
|
@ -534,7 +543,7 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
setupFs: defaultFs,
|
setupFs: defaultFs,
|
||||||
creator: &stubIAMCreator{id: validIAMIDFile},
|
creator: &stubIAMCreator{id: validIAMIDFile},
|
||||||
zoneFlag: "europe-west1-a",
|
zoneFlag: "europe-west1-a",
|
||||||
serviceAccountIDFlag: "constell-test",
|
namePrefixFlag: "constell-test",
|
||||||
projectIDFlag: "constell-1234",
|
projectIDFlag: "constell-1234",
|
||||||
stdin: "no\n",
|
stdin: "no\n",
|
||||||
wantAbort: true,
|
wantAbort: true,
|
||||||
|
@ -543,7 +552,7 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
setupFs: defaultFs,
|
setupFs: defaultFs,
|
||||||
creator: &stubIAMCreator{id: validIAMIDFile},
|
creator: &stubIAMCreator{id: validIAMIDFile},
|
||||||
zoneFlag: "europe-west1-a",
|
zoneFlag: "europe-west1-a",
|
||||||
serviceAccountIDFlag: "constell-test",
|
namePrefixFlag: "constell-test",
|
||||||
projectIDFlag: "constell-1234",
|
projectIDFlag: "constell-1234",
|
||||||
stdin: "no\n",
|
stdin: "no\n",
|
||||||
wantAbort: true,
|
wantAbort: true,
|
||||||
|
@ -554,7 +563,7 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
setupFs: readOnlyFs,
|
setupFs: readOnlyFs,
|
||||||
creator: &stubIAMCreator{id: validIAMIDFile},
|
creator: &stubIAMCreator{id: validIAMIDFile},
|
||||||
zoneFlag: "europe-west1-a",
|
zoneFlag: "europe-west1-a",
|
||||||
serviceAccountIDFlag: "constell-test",
|
namePrefixFlag: "constell-test",
|
||||||
projectIDFlag: "constell-1234",
|
projectIDFlag: "constell-1234",
|
||||||
yesFlag: true,
|
yesFlag: true,
|
||||||
updateConfigFlag: true,
|
updateConfigFlag: true,
|
||||||
|
@ -590,6 +599,7 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||||
flags: gcpIAMCreateFlags{
|
flags: gcpIAMCreateFlags{
|
||||||
zone: tc.zoneFlag,
|
zone: tc.zoneFlag,
|
||||||
serviceAccountID: tc.serviceAccountIDFlag,
|
serviceAccountID: tc.serviceAccountIDFlag,
|
||||||
|
namePrefix: tc.serviceAccountIDFlag,
|
||||||
projectID: tc.projectIDFlag,
|
projectID: tc.projectIDFlag,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -31,13 +31,19 @@ func newIAMCreateGCPCmd() *cobra.Command {
|
||||||
cmd.Flags().String("zone", "", "GCP zone the cluster will be deployed in (required)\n"+
|
cmd.Flags().String("zone", "", "GCP zone the cluster will be deployed in (required)\n"+
|
||||||
"Find a list of available zones here: https://cloud.google.com/compute/docs/regions-zones#available")
|
"Find a list of available zones here: https://cloud.google.com/compute/docs/regions-zones#available")
|
||||||
must(cobra.MarkFlagRequired(cmd.Flags(), "zone"))
|
must(cobra.MarkFlagRequired(cmd.Flags(), "zone"))
|
||||||
cmd.Flags().String("serviceAccountID", "", "ID for the service account that will be created (required)\n"+
|
|
||||||
"Must be 6 to 30 lowercase letters, digits, or hyphens.")
|
cmd.Flags().String("serviceAccountID", "", "[Deprecated use \"--prefix\"]ID for the service account that will be created (required)\n"+
|
||||||
must(cobra.MarkFlagRequired(cmd.Flags(), "serviceAccountID"))
|
"Must be 6 to 30 lowercase letters, digits, or hyphens. This flag is mutually exclusive with --prefix.")
|
||||||
|
cmd.Flags().String("prefix", "", "Prefix for the service account ID and VM ID that will be created (required)\n"+
|
||||||
|
"Must be letters, digits, or hyphens.")
|
||||||
|
|
||||||
cmd.Flags().String("projectID", "", "ID of the GCP project the configuration will be created in (required)\n"+
|
cmd.Flags().String("projectID", "", "ID of the GCP project the configuration will be created in (required)\n"+
|
||||||
"Find it on the welcome screen of your project: https://console.cloud.google.com/welcome")
|
"Find it on the welcome screen of your project: https://console.cloud.google.com/welcome")
|
||||||
must(cobra.MarkFlagRequired(cmd.Flags(), "projectID"))
|
must(cobra.MarkFlagRequired(cmd.Flags(), "projectID"))
|
||||||
|
|
||||||
|
cmd.MarkFlagsMutuallyExclusive([]string{"prefix", "serviceAccountID"}...)
|
||||||
|
must(cmd.Flags().MarkDeprecated("serviceAccountID", "use --prefix instead"))
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +59,7 @@ func runIAMCreateGCP(cmd *cobra.Command, _ []string) error {
|
||||||
type gcpIAMCreateFlags struct {
|
type gcpIAMCreateFlags struct {
|
||||||
rootFlags
|
rootFlags
|
||||||
serviceAccountID string
|
serviceAccountID string
|
||||||
|
namePrefix string
|
||||||
zone string
|
zone string
|
||||||
region string
|
region string
|
||||||
projectID string
|
projectID string
|
||||||
|
@ -91,9 +98,18 @@ func (f *gcpIAMCreateFlags) parse(flags *pflag.FlagSet) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getting 'serviceAccountID' flag: %w", err)
|
return fmt.Errorf("getting 'serviceAccountID' flag: %w", err)
|
||||||
}
|
}
|
||||||
if !gcpIDRegex.MatchString(f.serviceAccountID) {
|
if f.serviceAccountID != "" && !gcpIDRegex.MatchString(f.serviceAccountID) {
|
||||||
return fmt.Errorf("serviceAccountID %q doesn't match %s", f.serviceAccountID, gcpIDRegex)
|
return fmt.Errorf("serviceAccountID %q doesn't match %s", f.serviceAccountID, gcpIDRegex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f.namePrefix, err = flags.GetString("prefix")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("getting 'prefix' flag: %w", err)
|
||||||
|
}
|
||||||
|
if f.namePrefix != "" && !gcpPrefixRegex.MatchString(f.namePrefix) {
|
||||||
|
return fmt.Errorf("prefix %q doesn't match %s", f.namePrefix, gcpIDRegex)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,13 +125,19 @@ func (c *gcpIAMCreator) getIAMConfigOptions() *cloudcmd.IAMConfigOptions {
|
||||||
Region: c.flags.region,
|
Region: c.flags.region,
|
||||||
ProjectID: c.flags.projectID,
|
ProjectID: c.flags.projectID,
|
||||||
ServiceAccountID: c.flags.serviceAccountID,
|
ServiceAccountID: c.flags.serviceAccountID,
|
||||||
|
NamePrefix: c.flags.namePrefix,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gcpIAMCreator) printConfirmValues(cmd *cobra.Command) {
|
func (c *gcpIAMCreator) printConfirmValues(cmd *cobra.Command) {
|
||||||
cmd.Printf("Project ID:\t\t%s\n", c.flags.projectID)
|
cmd.Printf("Project ID:\t\t%s\n", c.flags.projectID)
|
||||||
|
if c.flags.namePrefix != "" {
|
||||||
|
cmd.Printf("Name Prefix:\t\t%s\n", c.flags.namePrefix)
|
||||||
|
}
|
||||||
|
if c.flags.serviceAccountID != "" {
|
||||||
cmd.Printf("Service Account ID:\t%s\n", c.flags.serviceAccountID)
|
cmd.Printf("Service Account ID:\t%s\n", c.flags.serviceAccountID)
|
||||||
|
}
|
||||||
cmd.Printf("Region:\t\t\t%s\n", c.flags.region)
|
cmd.Printf("Region:\t\t\t%s\n", c.flags.region)
|
||||||
cmd.Printf("Zone:\t\t\t%s\n\n", c.flags.zone)
|
cmd.Printf("Zone:\t\t\t%s\n\n", c.flags.zone)
|
||||||
}
|
}
|
||||||
|
@ -127,11 +149,12 @@ func (c *gcpIAMCreator) printOutputValues(cmd *cobra.Command, _ cloudcmd.IAMOutp
|
||||||
cmd.Printf("serviceAccountKeyPath:\t%s\n\n", c.flags.pathPrefixer.PrefixPrintablePath(constants.GCPServiceAccountKeyFilename))
|
cmd.Printf("serviceAccountKeyPath:\t%s\n\n", c.flags.pathPrefixer.PrefixPrintablePath(constants.GCPServiceAccountKeyFilename))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gcpIAMCreator) writeOutputValuesToConfig(conf *config.Config, _ cloudcmd.IAMOutput) {
|
func (c *gcpIAMCreator) writeOutputValuesToConfig(conf *config.Config, out cloudcmd.IAMOutput) {
|
||||||
conf.Provider.GCP.Project = c.flags.projectID
|
conf.Provider.GCP.Project = c.flags.projectID
|
||||||
conf.Provider.GCP.ServiceAccountKeyPath = constants.GCPServiceAccountKeyFilename // File was created in workspace, so only the filename is needed.
|
conf.Provider.GCP.ServiceAccountKeyPath = constants.GCPServiceAccountKeyFilename // File was created in workspace, so only the filename is needed.
|
||||||
conf.Provider.GCP.Region = c.flags.region
|
conf.Provider.GCP.Region = c.flags.region
|
||||||
conf.Provider.GCP.Zone = c.flags.zone
|
conf.Provider.GCP.Zone = c.flags.zone
|
||||||
|
conf.Provider.GCP.IAMServiceAccountVM = out.GCPOutput.IAMServiceAccountVM
|
||||||
for groupName, group := range conf.NodeGroups {
|
for groupName, group := range conf.NodeGroups {
|
||||||
group.Zone = c.flags.zone
|
group.Zone = c.flags.zone
|
||||||
conf.NodeGroups[groupName] = group
|
conf.NodeGroups[groupName] = group
|
||||||
|
|
|
@ -539,6 +539,7 @@ func defaultConfigWithExpectedMeasurements(t *testing.T, conf *config.Config, cs
|
||||||
conf.Provider.GCP.Project = "test-project"
|
conf.Provider.GCP.Project = "test-project"
|
||||||
conf.Provider.GCP.Zone = "test-zone"
|
conf.Provider.GCP.Zone = "test-zone"
|
||||||
conf.Provider.GCP.ServiceAccountKeyPath = "test-key-path"
|
conf.Provider.GCP.ServiceAccountKeyPath = "test-key-path"
|
||||||
|
conf.Provider.GCP.IAMServiceAccountVM = "example@example.com"
|
||||||
conf.Attestation.GCPSEVSNP.Measurements[4] = measurements.WithAllBytes(0x44, measurements.Enforce, measurements.PCRMeasurementLength)
|
conf.Attestation.GCPSEVSNP.Measurements[4] = measurements.WithAllBytes(0x44, measurements.Enforce, measurements.PCRMeasurementLength)
|
||||||
conf.Attestation.GCPSEVSNP.Measurements[9] = measurements.WithAllBytes(0x11, measurements.Enforce, measurements.PCRMeasurementLength)
|
conf.Attestation.GCPSEVSNP.Measurements[9] = measurements.WithAllBytes(0x11, measurements.Enforce, measurements.PCRMeasurementLength)
|
||||||
conf.Attestation.GCPSEVSNP.Measurements[12] = measurements.WithAllBytes(0xcc, measurements.Enforce, measurements.PCRMeasurementLength)
|
conf.Attestation.GCPSEVSNP.Measurements[12] = measurements.WithAllBytes(0xcc, measurements.Enforce, measurements.PCRMeasurementLength)
|
||||||
|
|
|
@ -103,9 +103,18 @@ func (c *Client) ShowIAM(ctx context.Context, provider cloudprovider.Provider) (
|
||||||
if !ok {
|
if !ok {
|
||||||
return IAMOutput{}, errors.New("invalid type in service_account_key output: not a string")
|
return IAMOutput{}, errors.New("invalid type in service_account_key output: not a string")
|
||||||
}
|
}
|
||||||
|
IAMServiceAccountVMOutputRaw, ok := tfState.Values.Outputs["service_account_mail_vm"]
|
||||||
|
if !ok {
|
||||||
|
return IAMOutput{}, errors.New("no service_account_mail_vm output found")
|
||||||
|
}
|
||||||
|
IAMServiceAccountVMOutput, ok := IAMServiceAccountVMOutputRaw.Value.(string)
|
||||||
|
if !ok {
|
||||||
|
return IAMOutput{}, errors.New("invalid type in service_account_mail_vm output: not a string")
|
||||||
|
}
|
||||||
return IAMOutput{
|
return IAMOutput{
|
||||||
GCP: GCPIAMOutput{
|
GCP: GCPIAMOutput{
|
||||||
SaKey: saKeyOutput,
|
SaKey: saKeyOutput,
|
||||||
|
ServiceAccountVMMailAddress: IAMServiceAccountVMOutput,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
case cloudprovider.Azure:
|
case cloudprovider.Azure:
|
||||||
|
@ -540,6 +549,7 @@ type IAMOutput struct {
|
||||||
// GCPIAMOutput contains the output information of the Terraform IAM operation on GCP.
|
// GCPIAMOutput contains the output information of the Terraform IAM operation on GCP.
|
||||||
type GCPIAMOutput struct {
|
type GCPIAMOutput struct {
|
||||||
SaKey string
|
SaKey string
|
||||||
|
ServiceAccountVMMailAddress string
|
||||||
}
|
}
|
||||||
|
|
||||||
// AzureIAMOutput contains the output information of the Terraform IAM operation on Microsoft Azure.
|
// AzureIAMOutput contains the output information of the Terraform IAM operation on Microsoft Azure.
|
||||||
|
|
|
@ -120,6 +120,7 @@ func TestPrepareIAM(t *testing.T) {
|
||||||
Region: "europe-west1",
|
Region: "europe-west1",
|
||||||
Zone: "europe-west1-a",
|
Zone: "europe-west1-a",
|
||||||
ServiceAccountID: "const-test-case",
|
ServiceAccountID: "const-test-case",
|
||||||
|
NamePrefix: "test_iam",
|
||||||
}
|
}
|
||||||
azureVars := &AzureIAMVariables{
|
azureVars := &AzureIAMVariables{
|
||||||
Location: "westus",
|
Location: "westus",
|
||||||
|
@ -509,6 +510,9 @@ func TestCreateIAM(t *testing.T) {
|
||||||
"service_account_key": {
|
"service_account_key": {
|
||||||
Value: "12345678_abcdefg",
|
Value: "12345678_abcdefg",
|
||||||
},
|
},
|
||||||
|
"service_account_mail_vm": {
|
||||||
|
Value: "test_iam_service_account_vm",
|
||||||
|
},
|
||||||
"subscription_id": {
|
"subscription_id": {
|
||||||
Value: "test_subscription_id",
|
Value: "test_subscription_id",
|
||||||
},
|
},
|
||||||
|
@ -581,7 +585,7 @@ func TestCreateIAM(t *testing.T) {
|
||||||
vars: gcpVars,
|
vars: gcpVars,
|
||||||
tf: &stubTerraform{showState: newTestState()},
|
tf: &stubTerraform{showState: newTestState()},
|
||||||
fs: afero.NewMemMapFs(),
|
fs: afero.NewMemMapFs(),
|
||||||
want: IAMOutput{GCP: GCPIAMOutput{SaKey: "12345678_abcdefg"}},
|
want: IAMOutput{GCP: GCPIAMOutput{SaKey: "12345678_abcdefg", ServiceAccountVMMailAddress: "test_iam_service_account_vm"}},
|
||||||
},
|
},
|
||||||
"gcp init fails": {
|
"gcp init fails": {
|
||||||
pathBase: path.Join(constants.TerraformEmbeddedDir, "iam"),
|
pathBase: path.Join(constants.TerraformEmbeddedDir, "iam"),
|
||||||
|
@ -614,7 +618,25 @@ func TestCreateIAM(t *testing.T) {
|
||||||
tf: &stubTerraform{
|
tf: &stubTerraform{
|
||||||
showState: &tfjson.State{
|
showState: &tfjson.State{
|
||||||
Values: &tfjson.StateValues{
|
Values: &tfjson.StateValues{
|
||||||
Outputs: map[string]*tfjson.StateOutput{},
|
Outputs: map[string]*tfjson.StateOutput{
|
||||||
|
"service_account_mail_vm": {Value: "test_iam_service_account_vm"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fs: afero.NewMemMapFs(),
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
"gcp no service_account_mail_vm": {
|
||||||
|
pathBase: path.Join(constants.TerraformEmbeddedDir, "iam"),
|
||||||
|
provider: cloudprovider.GCP,
|
||||||
|
vars: gcpVars,
|
||||||
|
tf: &stubTerraform{
|
||||||
|
showState: &tfjson.State{
|
||||||
|
Values: &tfjson.StateValues{
|
||||||
|
Outputs: map[string]*tfjson.StateOutput{
|
||||||
|
"service_account_key": {Value: "12345678_abcdefg"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1130,6 +1152,7 @@ func TestShowIAM(t *testing.T) {
|
||||||
tf: &stubTerraform{
|
tf: &stubTerraform{
|
||||||
showState: getTfjsonState(map[string]any{
|
showState: getTfjsonState(map[string]any{
|
||||||
"service_account_key": "key",
|
"service_account_key": "key",
|
||||||
|
"service_account_mail_vm": "example@example.com",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
csp: cloudprovider.GCP,
|
csp: cloudprovider.GCP,
|
||||||
|
@ -1138,6 +1161,7 @@ func TestShowIAM(t *testing.T) {
|
||||||
tf: &stubTerraform{
|
tf: &stubTerraform{
|
||||||
showState: getTfjsonState(map[string]any{
|
showState: getTfjsonState(map[string]any{
|
||||||
"service_account_key": map[string]any{},
|
"service_account_key": map[string]any{},
|
||||||
|
"service_account_mail_vm": "example@example.com",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
csp: cloudprovider.GCP,
|
csp: cloudprovider.GCP,
|
||||||
|
@ -1145,7 +1169,9 @@ func TestShowIAM(t *testing.T) {
|
||||||
},
|
},
|
||||||
"GCP missing key": {
|
"GCP missing key": {
|
||||||
tf: &stubTerraform{
|
tf: &stubTerraform{
|
||||||
showState: getTfjsonState(map[string]any{}),
|
showState: getTfjsonState(map[string]any{
|
||||||
|
"service_account_mail_vm": "example@example.com",
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
csp: cloudprovider.GCP,
|
csp: cloudprovider.GCP,
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
|
|
|
@ -141,6 +141,8 @@ type GCPClusterVariables struct {
|
||||||
InternalLoadBalancer bool `hcl:"internal_load_balancer" cty:"internal_load_balancer"`
|
InternalLoadBalancer bool `hcl:"internal_load_balancer" cty:"internal_load_balancer"`
|
||||||
// CCTechnology is the confidential computing technology to use on the VMs. (`SEV` or `SEV_SNP`)
|
// CCTechnology is the confidential computing technology to use on the VMs. (`SEV` or `SEV_SNP`)
|
||||||
CCTechnology string `hcl:"cc_technology" cty:"cc_technology"`
|
CCTechnology string `hcl:"cc_technology" cty:"cc_technology"`
|
||||||
|
// IAMServiceAccountControlPlane is the IAM service account mail address to attach to VMs.
|
||||||
|
IAMServiceAccountVM string `hcl:"iam_service_account_vm" cty:"iam_service_account_vm"`
|
||||||
// AdditionalLables are (optional) additional labels that should be applied to created resources.
|
// AdditionalLables are (optional) additional labels that should be applied to created resources.
|
||||||
AdditionalLabels cloudprovider.Tags `hcl:"additional_labels" cty:"additional_labels"`
|
AdditionalLabels cloudprovider.Tags `hcl:"additional_labels" cty:"additional_labels"`
|
||||||
}
|
}
|
||||||
|
@ -182,6 +184,9 @@ type GCPIAMVariables struct {
|
||||||
Zone string `hcl:"zone" cty:"zone"`
|
Zone string `hcl:"zone" cty:"zone"`
|
||||||
// ServiceAccountID is the ID of the service account to use.
|
// ServiceAccountID is the ID of the service account to use.
|
||||||
ServiceAccountID string `hcl:"service_account_id" cty:"service_account_id"`
|
ServiceAccountID string `hcl:"service_account_id" cty:"service_account_id"`
|
||||||
|
// IAMServiceAccountVM is the ID of the service account to attach to VMs.
|
||||||
|
// TODO(@3u13r): Eventually remove this field after v2.22 has been released.
|
||||||
|
NamePrefix string `hcl:"name_prefix,optional" cty:"name_prefix"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a string representation of the IAM-specific variables, formatted as Terraform variables.
|
// String returns a string representation of the IAM-specific variables, formatted as Terraform variables.
|
||||||
|
|
|
@ -124,6 +124,7 @@ func TestGCPClusterVariables(t *testing.T) {
|
||||||
},
|
},
|
||||||
CustomEndpoint: "example.com",
|
CustomEndpoint: "example.com",
|
||||||
CCTechnology: "SEV_SNP",
|
CCTechnology: "SEV_SNP",
|
||||||
|
IAMServiceAccountVM: "example@example.com",
|
||||||
}
|
}
|
||||||
|
|
||||||
// test that the variables are correctly rendered
|
// test that the variables are correctly rendered
|
||||||
|
@ -154,6 +155,7 @@ node_groups = {
|
||||||
custom_endpoint = "example.com"
|
custom_endpoint = "example.com"
|
||||||
internal_load_balancer = false
|
internal_load_balancer = false
|
||||||
cc_technology = "SEV_SNP"
|
cc_technology = "SEV_SNP"
|
||||||
|
iam_service_account_vm = "example@example.com"
|
||||||
additional_labels = null
|
additional_labels = null
|
||||||
`
|
`
|
||||||
got := vars.String()
|
got := vars.String()
|
||||||
|
@ -173,9 +175,27 @@ func TestGCPIAMVariables(t *testing.T) {
|
||||||
region = "eu-central-1"
|
region = "eu-central-1"
|
||||||
zone = "eu-central-1a"
|
zone = "eu-central-1a"
|
||||||
service_account_id = "my-service-account"
|
service_account_id = "my-service-account"
|
||||||
|
name_prefix = ""
|
||||||
`
|
`
|
||||||
got := vars.String()
|
got := vars.String()
|
||||||
assert.Equal(t, strings.Fields(want), strings.Fields(got)) // to ignore whitespace differences
|
assert.Equal(t, strings.Fields(want), strings.Fields(got)) // to ignore whitespace differences
|
||||||
|
|
||||||
|
vars = GCPIAMVariables{
|
||||||
|
Project: "my-project",
|
||||||
|
Region: "eu-central-1",
|
||||||
|
Zone: "eu-central-1a",
|
||||||
|
NamePrefix: "my-prefix",
|
||||||
|
}
|
||||||
|
|
||||||
|
// test that the variables are correctly rendered
|
||||||
|
want = `project_id = "my-project"
|
||||||
|
region = "eu-central-1"
|
||||||
|
zone = "eu-central-1a"
|
||||||
|
service_account_id = ""
|
||||||
|
name_prefix = "my-prefix"
|
||||||
|
`
|
||||||
|
got = vars.String()
|
||||||
|
assert.Equal(t, strings.Fields(want), strings.Fields(got)) // to ignore whitespace differences
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAzureClusterVariables(t *testing.T) {
|
func TestAzureClusterVariables(t *testing.T) {
|
||||||
|
|
|
@ -102,7 +102,7 @@ If you encounter any problem with the following steps, make sure to use the [lat
|
||||||
<TabItem value="gcp" label="GCP">
|
<TabItem value="gcp" label="GCP">
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
constellation iam create gcp --projectID=yourproject-12345 --zone=europe-west2-a --serviceAccountID=constell-test --update-config
|
constellation iam create gcp --projectID=yourproject-12345 --zone=europe-west2-a --prefix=constell-test --update-config
|
||||||
```
|
```
|
||||||
|
|
||||||
This command creates IAM configuration in the GCP project `yourproject-12345` on the GCP zone `europe-west2-a` creating a new service account `constell-test`. It also updates the configuration file `constellation-conf.yaml` in your current directory with the IAM values filled in.
|
This command creates IAM configuration in the GCP project `yourproject-12345` on the GCP zone `europe-west2-a` creating a new service account `constell-test`. It also updates the configuration file `constellation-conf.yaml` in your current directory with the IAM values filled in.
|
||||||
|
|
|
@ -234,6 +234,9 @@ Enable the [Compute Engine API](https://console.cloud.google.com/apis/library/co
|
||||||
|
|
||||||
To [create the IAM configuration](../workflows/config.md#creating-an-iam-configuration) for Constellation, you need the following permissions:
|
To [create the IAM configuration](../workflows/config.md#creating-an-iam-configuration) for Constellation, you need the following permissions:
|
||||||
|
|
||||||
|
* `iam.roles.create`
|
||||||
|
* `iam.roles.delete`
|
||||||
|
* `iam.roles.get`
|
||||||
* `iam.serviceAccountKeys.create`
|
* `iam.serviceAccountKeys.create`
|
||||||
* `iam.serviceAccountKeys.delete`
|
* `iam.serviceAccountKeys.delete`
|
||||||
* `iam.serviceAccountKeys.get`
|
* `iam.serviceAccountKeys.get`
|
||||||
|
|
|
@ -686,10 +686,10 @@ constellation iam create gcp [flags]
|
||||||
|
|
||||||
```
|
```
|
||||||
-h, --help help for gcp
|
-h, --help help for gcp
|
||||||
|
--prefix string Prefix for the service account ID and VM ID that will be created (required)
|
||||||
|
Must be letters, digits, or hyphens.
|
||||||
--projectID string ID of the GCP project the configuration will be created in (required)
|
--projectID string ID of the GCP project the configuration will be created in (required)
|
||||||
Find it on the welcome screen of your project: https://console.cloud.google.com/welcome
|
Find it on the welcome screen of your project: https://console.cloud.google.com/welcome
|
||||||
--serviceAccountID string ID for the service account that will be created (required)
|
|
||||||
Must be 6 to 30 lowercase letters, digits, or hyphens.
|
|
||||||
--zone string GCP zone the cluster will be deployed in (required)
|
--zone string GCP zone the cluster will be deployed in (required)
|
||||||
Find a list of available zones here: https://cloud.google.com/compute/docs/regions-zones#available
|
Find a list of available zones here: https://cloud.google.com/compute/docs/regions-zones#available
|
||||||
```
|
```
|
||||||
|
|
|
@ -210,7 +210,7 @@ Paste the output into the corresponding fields of the `constellation-conf.yaml`
|
||||||
You must be authenticated with the [GCP CLI](https://cloud.google.com/sdk/gcloud) in the shell session with a user that has the [required permissions for IAM creation](../getting-started/install.md#set-up-cloud-credentials).
|
You must be authenticated with the [GCP CLI](https://cloud.google.com/sdk/gcloud) in the shell session with a user that has the [required permissions for IAM creation](../getting-started/install.md#set-up-cloud-credentials).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
constellation iam create gcp --projectID=yourproject-12345 --zone=europe-west2-a --serviceAccountID=constell-test
|
constellation iam create gcp --projectID=yourproject-12345 --zone=europe-west2-a --prefix=constell-test
|
||||||
```
|
```
|
||||||
|
|
||||||
This command creates IAM configuration in the GCP project `yourproject-12345` on the GCP zone `europe-west2-a` creating a new service account `constell-test`.
|
This command creates IAM configuration in the GCP project `yourproject-12345` on the GCP zone `europe-west2-a` creating a new service account `constell-test`.
|
||||||
|
|
|
@ -188,6 +188,9 @@ type GCPConfig struct {
|
||||||
// Path of service account key file. For required service account roles, see https://docs.edgeless.systems/constellation/getting-started/install#authorization
|
// Path of service account key file. For required service account roles, see https://docs.edgeless.systems/constellation/getting-started/install#authorization
|
||||||
ServiceAccountKeyPath string `yaml:"serviceAccountKeyPath" validate:"required"`
|
ServiceAccountKeyPath string `yaml:"serviceAccountKeyPath" validate:"required"`
|
||||||
// description: |
|
// description: |
|
||||||
|
// GCP service account mail address. This is being attached to the VMs for authorization.
|
||||||
|
IAMServiceAccountVM string `yaml:"IAMServiceAccountVM"`
|
||||||
|
// 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: |
|
// description: |
|
||||||
|
@ -349,6 +352,7 @@ func Default() *Config {
|
||||||
Region: "",
|
Region: "",
|
||||||
Zone: "",
|
Zone: "",
|
||||||
ServiceAccountKeyPath: "",
|
ServiceAccountKeyPath: "",
|
||||||
|
IAMServiceAccountVM: "",
|
||||||
DeployCSIDriver: toPtr(true),
|
DeployCSIDriver: toPtr(true),
|
||||||
UseMarketplaceImage: toPtr(false),
|
UseMarketplaceImage: toPtr(false),
|
||||||
},
|
},
|
||||||
|
|
|
@ -241,7 +241,7 @@ func init() {
|
||||||
FieldName: "gcp",
|
FieldName: "gcp",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
GCPConfigDoc.Fields = make([]encoder.Doc, 6)
|
GCPConfigDoc.Fields = make([]encoder.Doc, 7)
|
||||||
GCPConfigDoc.Fields[0].Name = "project"
|
GCPConfigDoc.Fields[0].Name = "project"
|
||||||
GCPConfigDoc.Fields[0].Type = "string"
|
GCPConfigDoc.Fields[0].Type = "string"
|
||||||
GCPConfigDoc.Fields[0].Note = ""
|
GCPConfigDoc.Fields[0].Note = ""
|
||||||
|
@ -262,16 +262,21 @@ func init() {
|
||||||
GCPConfigDoc.Fields[3].Note = ""
|
GCPConfigDoc.Fields[3].Note = ""
|
||||||
GCPConfigDoc.Fields[3].Description = "Path of service account key file. For required service account roles, see https://docs.edgeless.systems/constellation/getting-started/install#authorization"
|
GCPConfigDoc.Fields[3].Description = "Path of service account key file. For required service account roles, see https://docs.edgeless.systems/constellation/getting-started/install#authorization"
|
||||||
GCPConfigDoc.Fields[3].Comments[encoder.LineComment] = "Path of service account key file. For required service account roles, see https://docs.edgeless.systems/constellation/getting-started/install#authorization"
|
GCPConfigDoc.Fields[3].Comments[encoder.LineComment] = "Path of service account key file. For required service account roles, see https://docs.edgeless.systems/constellation/getting-started/install#authorization"
|
||||||
GCPConfigDoc.Fields[4].Name = "deployCSIDriver"
|
GCPConfigDoc.Fields[4].Name = "IAMServiceAccountVM"
|
||||||
GCPConfigDoc.Fields[4].Type = "bool"
|
GCPConfigDoc.Fields[4].Type = "string"
|
||||||
GCPConfigDoc.Fields[4].Note = ""
|
GCPConfigDoc.Fields[4].Note = ""
|
||||||
GCPConfigDoc.Fields[4].Description = "Deploy Persistent Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage"
|
GCPConfigDoc.Fields[4].Description = "GCP service account mail address. This is being attached to the VMs for authorization."
|
||||||
GCPConfigDoc.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"
|
GCPConfigDoc.Fields[4].Comments[encoder.LineComment] = "GCP service account mail address. This is being attached to the VMs for authorization."
|
||||||
GCPConfigDoc.Fields[5].Name = "useMarketplaceImage"
|
GCPConfigDoc.Fields[5].Name = "deployCSIDriver"
|
||||||
GCPConfigDoc.Fields[5].Type = "bool"
|
GCPConfigDoc.Fields[5].Type = "bool"
|
||||||
GCPConfigDoc.Fields[5].Note = ""
|
GCPConfigDoc.Fields[5].Note = ""
|
||||||
GCPConfigDoc.Fields[5].Description = "Use the specified GCP Marketplace image offering."
|
GCPConfigDoc.Fields[5].Description = "Deploy Persistent Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage"
|
||||||
GCPConfigDoc.Fields[5].Comments[encoder.LineComment] = "Use the specified GCP Marketplace image offering."
|
GCPConfigDoc.Fields[5].Comments[encoder.LineComment] = "Deploy Persistent Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage"
|
||||||
|
GCPConfigDoc.Fields[6].Name = "useMarketplaceImage"
|
||||||
|
GCPConfigDoc.Fields[6].Type = "bool"
|
||||||
|
GCPConfigDoc.Fields[6].Note = ""
|
||||||
|
GCPConfigDoc.Fields[6].Description = "Use the specified GCP Marketplace image offering."
|
||||||
|
GCPConfigDoc.Fields[6].Comments[encoder.LineComment] = "Use the specified GCP Marketplace image offering."
|
||||||
|
|
||||||
OpenStackConfigDoc.Type = "OpenStackConfig"
|
OpenStackConfigDoc.Type = "OpenStackConfig"
|
||||||
OpenStackConfigDoc.Comments[encoder.LineComment] = "OpenStackConfig holds config information for OpenStack based Constellation deployments."
|
OpenStackConfigDoc.Comments[encoder.LineComment] = "OpenStackConfig holds config information for OpenStack based Constellation deployments."
|
||||||
|
|
|
@ -464,6 +464,7 @@ func TestValidate(t *testing.T) {
|
||||||
gcp.Project = "test-project"
|
gcp.Project = "test-project"
|
||||||
gcp.Zone = "test-zone"
|
gcp.Zone = "test-zone"
|
||||||
gcp.ServiceAccountKeyPath = "test-key-path"
|
gcp.ServiceAccountKeyPath = "test-key-path"
|
||||||
|
gcp.IAMServiceAccountVM = "example@example.com"
|
||||||
cnf.Provider = ProviderConfig{}
|
cnf.Provider = ProviderConfig{}
|
||||||
cnf.Provider.GCP = gcp
|
cnf.Provider.GCP = gcp
|
||||||
cnf.Attestation.GCPSEVSNP.Measurements = measurements.M{
|
cnf.Attestation.GCPSEVSNP.Measurements = measurements.M{
|
||||||
|
|
|
@ -40,6 +40,9 @@ spec:
|
||||||
- --cloud-provider={{ .Values.csp }}
|
- --cloud-provider={{ .Values.csp }}
|
||||||
- --key-service-endpoint=key-service.{{ .Release.Namespace }}:{{ .Values.global.keyServicePort }}
|
- --key-service-endpoint=key-service.{{ .Release.Namespace }}:{{ .Values.global.keyServicePort }}
|
||||||
- --attestation-variant={{ .Values.attestationVariant }}
|
- --attestation-variant={{ .Values.attestationVariant }}
|
||||||
|
env:
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: /var/secrets/google/key.json
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: {{ .Values.global.serviceBasePath | quote }}
|
- mountPath: {{ .Values.global.serviceBasePath | quote }}
|
||||||
name: config
|
name: config
|
||||||
|
@ -47,6 +50,9 @@ spec:
|
||||||
- mountPath: /etc/kubernetes
|
- mountPath: /etc/kubernetes
|
||||||
name: kubeadm
|
name: kubeadm
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: /var/secrets/google
|
||||||
|
name: gcekey
|
||||||
|
readOnly: true
|
||||||
ports:
|
ports:
|
||||||
- containerPort: {{ .Values.joinServicePort }}
|
- containerPort: {{ .Values.joinServicePort }}
|
||||||
name: tcp
|
name: tcp
|
||||||
|
@ -54,6 +60,10 @@ spec:
|
||||||
securityContext:
|
securityContext:
|
||||||
privileged: true
|
privileged: true
|
||||||
volumes:
|
volumes:
|
||||||
|
- name: gcekey
|
||||||
|
secret:
|
||||||
|
secretName: gcekey
|
||||||
|
optional: true
|
||||||
- name: config
|
- name: config
|
||||||
projected:
|
projected:
|
||||||
sources:
|
sources:
|
||||||
|
|
|
@ -42,6 +42,8 @@ spec:
|
||||||
value: {{ .Values.csp | quote }}
|
value: {{ .Values.csp | quote }}
|
||||||
- name: constellation-uid
|
- name: constellation-uid
|
||||||
value: {{ .Values.constellationUID | quote }}
|
value: {{ .Values.constellationUID | quote }}
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: /var/secrets/google/key.json
|
||||||
image: {{ .Values.controllerManager.manager.image | quote }}
|
image: {{ .Values.controllerManager.manager.image | quote }}
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
|
@ -72,6 +74,9 @@ spec:
|
||||||
- mountPath: /etc/gce
|
- mountPath: /etc/gce
|
||||||
name: gceconf
|
name: gceconf
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: /var/secrets/google
|
||||||
|
name: gcekey
|
||||||
|
readOnly: true
|
||||||
- mountPath: /etc/constellation-upgrade-agent.sock
|
- mountPath: /etc/constellation-upgrade-agent.sock
|
||||||
name: upgrade-agent-socket
|
name: upgrade-agent-socket
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
@ -109,6 +114,10 @@ spec:
|
||||||
name: gceconf
|
name: gceconf
|
||||||
optional: true
|
optional: true
|
||||||
name: gceconf
|
name: gceconf
|
||||||
|
- name: gcekey
|
||||||
|
secret:
|
||||||
|
secretName: gcekey
|
||||||
|
optional: true
|
||||||
- name: upgrade-agent-socket
|
- name: upgrade-agent-socket
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /run/constellation-upgrade-agent.sock
|
path: /run/constellation-upgrade-agent.sock
|
||||||
|
|
|
@ -50,6 +50,8 @@ spec:
|
||||||
value: GCP
|
value: GCP
|
||||||
- name: constellation-uid
|
- name: constellation-uid
|
||||||
value: "42424242424242"
|
value: "42424242424242"
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: /var/secrets/google/key.json
|
||||||
image: constellationOperatorImage
|
image: constellationOperatorImage
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
|
@ -86,6 +88,9 @@ spec:
|
||||||
- mountPath: /etc/gce
|
- mountPath: /etc/gce
|
||||||
name: gceconf
|
name: gceconf
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: /var/secrets/google
|
||||||
|
name: gcekey
|
||||||
|
readOnly: true
|
||||||
- mountPath: /etc/constellation-upgrade-agent.sock
|
- mountPath: /etc/constellation-upgrade-agent.sock
|
||||||
name: upgrade-agent-socket
|
name: upgrade-agent-socket
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
@ -123,6 +128,10 @@ spec:
|
||||||
name: gceconf
|
name: gceconf
|
||||||
optional: true
|
optional: true
|
||||||
name: gceconf
|
name: gceconf
|
||||||
|
- name: gcekey
|
||||||
|
secret:
|
||||||
|
secretName: gcekey
|
||||||
|
optional: true
|
||||||
- name: upgrade-agent-socket
|
- name: upgrade-agent-socket
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /run/constellation-upgrade-agent.sock
|
path: /run/constellation-upgrade-agent.sock
|
||||||
|
|
|
@ -40,6 +40,9 @@ spec:
|
||||||
- --cloud-provider=AWS
|
- --cloud-provider=AWS
|
||||||
- --key-service-endpoint=key-service.testNamespace:9000
|
- --key-service-endpoint=key-service.testNamespace:9000
|
||||||
- --attestation-variant=aws-nitro-tpm
|
- --attestation-variant=aws-nitro-tpm
|
||||||
|
env:
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: /var/secrets/google/key.json
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /var/config
|
- mountPath: /var/config
|
||||||
name: config
|
name: config
|
||||||
|
@ -47,6 +50,9 @@ spec:
|
||||||
- mountPath: /etc/kubernetes
|
- mountPath: /etc/kubernetes
|
||||||
name: kubeadm
|
name: kubeadm
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: /var/secrets/google
|
||||||
|
name: gcekey
|
||||||
|
readOnly: true
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 9090
|
- containerPort: 9090
|
||||||
name: tcp
|
name: tcp
|
||||||
|
@ -54,6 +60,10 @@ spec:
|
||||||
securityContext:
|
securityContext:
|
||||||
privileged: true
|
privileged: true
|
||||||
volumes:
|
volumes:
|
||||||
|
- name: gcekey
|
||||||
|
secret:
|
||||||
|
secretName: gcekey
|
||||||
|
optional: true
|
||||||
- name: config
|
- name: config
|
||||||
projected:
|
projected:
|
||||||
sources:
|
sources:
|
||||||
|
|
|
@ -50,6 +50,8 @@ spec:
|
||||||
value: Azure
|
value: Azure
|
||||||
- name: constellation-uid
|
- name: constellation-uid
|
||||||
value: "42424242424242"
|
value: "42424242424242"
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: /var/secrets/google/key.json
|
||||||
image: constellationOperatorImage
|
image: constellationOperatorImage
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
|
@ -86,6 +88,9 @@ spec:
|
||||||
- mountPath: /etc/gce
|
- mountPath: /etc/gce
|
||||||
name: gceconf
|
name: gceconf
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: /var/secrets/google
|
||||||
|
name: gcekey
|
||||||
|
readOnly: true
|
||||||
- mountPath: /etc/constellation-upgrade-agent.sock
|
- mountPath: /etc/constellation-upgrade-agent.sock
|
||||||
name: upgrade-agent-socket
|
name: upgrade-agent-socket
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
@ -123,6 +128,10 @@ spec:
|
||||||
name: gceconf
|
name: gceconf
|
||||||
optional: true
|
optional: true
|
||||||
name: gceconf
|
name: gceconf
|
||||||
|
- name: gcekey
|
||||||
|
secret:
|
||||||
|
secretName: gcekey
|
||||||
|
optional: true
|
||||||
- name: upgrade-agent-socket
|
- name: upgrade-agent-socket
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /run/constellation-upgrade-agent.sock
|
path: /run/constellation-upgrade-agent.sock
|
||||||
|
|
|
@ -40,6 +40,9 @@ spec:
|
||||||
- --cloud-provider=Azure
|
- --cloud-provider=Azure
|
||||||
- --key-service-endpoint=key-service.testNamespace:9000
|
- --key-service-endpoint=key-service.testNamespace:9000
|
||||||
- --attestation-variant=azure-sev-snp
|
- --attestation-variant=azure-sev-snp
|
||||||
|
env:
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: /var/secrets/google/key.json
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /var/config
|
- mountPath: /var/config
|
||||||
name: config
|
name: config
|
||||||
|
@ -47,6 +50,9 @@ spec:
|
||||||
- mountPath: /etc/kubernetes
|
- mountPath: /etc/kubernetes
|
||||||
name: kubeadm
|
name: kubeadm
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: /var/secrets/google
|
||||||
|
name: gcekey
|
||||||
|
readOnly: true
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 9090
|
- containerPort: 9090
|
||||||
name: tcp
|
name: tcp
|
||||||
|
@ -54,6 +60,10 @@ spec:
|
||||||
securityContext:
|
securityContext:
|
||||||
privileged: true
|
privileged: true
|
||||||
volumes:
|
volumes:
|
||||||
|
- name: gcekey
|
||||||
|
secret:
|
||||||
|
secretName: gcekey
|
||||||
|
optional: true
|
||||||
- name: config
|
- name: config
|
||||||
projected:
|
projected:
|
||||||
sources:
|
sources:
|
||||||
|
|
|
@ -50,6 +50,8 @@ spec:
|
||||||
value: GCP
|
value: GCP
|
||||||
- name: constellation-uid
|
- name: constellation-uid
|
||||||
value: "42424242424242"
|
value: "42424242424242"
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: /var/secrets/google/key.json
|
||||||
image: constellationOperatorImage
|
image: constellationOperatorImage
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
|
@ -86,6 +88,9 @@ spec:
|
||||||
- mountPath: /etc/gce
|
- mountPath: /etc/gce
|
||||||
name: gceconf
|
name: gceconf
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: /var/secrets/google
|
||||||
|
name: gcekey
|
||||||
|
readOnly: true
|
||||||
- mountPath: /etc/constellation-upgrade-agent.sock
|
- mountPath: /etc/constellation-upgrade-agent.sock
|
||||||
name: upgrade-agent-socket
|
name: upgrade-agent-socket
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
@ -123,6 +128,10 @@ spec:
|
||||||
name: gceconf
|
name: gceconf
|
||||||
optional: true
|
optional: true
|
||||||
name: gceconf
|
name: gceconf
|
||||||
|
- name: gcekey
|
||||||
|
secret:
|
||||||
|
secretName: gcekey
|
||||||
|
optional: true
|
||||||
- name: upgrade-agent-socket
|
- name: upgrade-agent-socket
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /run/constellation-upgrade-agent.sock
|
path: /run/constellation-upgrade-agent.sock
|
||||||
|
|
|
@ -40,6 +40,9 @@ spec:
|
||||||
- --cloud-provider=GCP
|
- --cloud-provider=GCP
|
||||||
- --key-service-endpoint=key-service.testNamespace:9000
|
- --key-service-endpoint=key-service.testNamespace:9000
|
||||||
- --attestation-variant=gcp-sev-es
|
- --attestation-variant=gcp-sev-es
|
||||||
|
env:
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: /var/secrets/google/key.json
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /var/config
|
- mountPath: /var/config
|
||||||
name: config
|
name: config
|
||||||
|
@ -47,6 +50,9 @@ spec:
|
||||||
- mountPath: /etc/kubernetes
|
- mountPath: /etc/kubernetes
|
||||||
name: kubeadm
|
name: kubeadm
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: /var/secrets/google
|
||||||
|
name: gcekey
|
||||||
|
readOnly: true
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 9090
|
- containerPort: 9090
|
||||||
name: tcp
|
name: tcp
|
||||||
|
@ -54,6 +60,10 @@ spec:
|
||||||
securityContext:
|
securityContext:
|
||||||
privileged: true
|
privileged: true
|
||||||
volumes:
|
volumes:
|
||||||
|
- name: gcekey
|
||||||
|
secret:
|
||||||
|
secretName: gcekey
|
||||||
|
optional: true
|
||||||
- name: config
|
- name: config
|
||||||
projected:
|
projected:
|
||||||
sources:
|
sources:
|
||||||
|
|
|
@ -50,6 +50,8 @@ spec:
|
||||||
value: GCP
|
value: GCP
|
||||||
- name: constellation-uid
|
- name: constellation-uid
|
||||||
value: "42424242424242"
|
value: "42424242424242"
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: /var/secrets/google/key.json
|
||||||
image: constellationOperatorImage
|
image: constellationOperatorImage
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
|
@ -86,6 +88,9 @@ spec:
|
||||||
- mountPath: /etc/gce
|
- mountPath: /etc/gce
|
||||||
name: gceconf
|
name: gceconf
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: /var/secrets/google
|
||||||
|
name: gcekey
|
||||||
|
readOnly: true
|
||||||
- mountPath: /etc/constellation-upgrade-agent.sock
|
- mountPath: /etc/constellation-upgrade-agent.sock
|
||||||
name: upgrade-agent-socket
|
name: upgrade-agent-socket
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
@ -123,6 +128,10 @@ spec:
|
||||||
name: gceconf
|
name: gceconf
|
||||||
optional: true
|
optional: true
|
||||||
name: gceconf
|
name: gceconf
|
||||||
|
- name: gcekey
|
||||||
|
secret:
|
||||||
|
secretName: gcekey
|
||||||
|
optional: true
|
||||||
- name: upgrade-agent-socket
|
- name: upgrade-agent-socket
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /run/constellation-upgrade-agent.sock
|
path: /run/constellation-upgrade-agent.sock
|
||||||
|
|
|
@ -40,6 +40,9 @@ spec:
|
||||||
- --cloud-provider=OpenStack
|
- --cloud-provider=OpenStack
|
||||||
- --key-service-endpoint=key-service.testNamespace:9000
|
- --key-service-endpoint=key-service.testNamespace:9000
|
||||||
- --attestation-variant=qemu-vtpm
|
- --attestation-variant=qemu-vtpm
|
||||||
|
env:
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: /var/secrets/google/key.json
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /var/config
|
- mountPath: /var/config
|
||||||
name: config
|
name: config
|
||||||
|
@ -47,6 +50,9 @@ spec:
|
||||||
- mountPath: /etc/kubernetes
|
- mountPath: /etc/kubernetes
|
||||||
name: kubeadm
|
name: kubeadm
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: /var/secrets/google
|
||||||
|
name: gcekey
|
||||||
|
readOnly: true
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 9090
|
- containerPort: 9090
|
||||||
name: tcp
|
name: tcp
|
||||||
|
@ -54,6 +60,10 @@ spec:
|
||||||
securityContext:
|
securityContext:
|
||||||
privileged: true
|
privileged: true
|
||||||
volumes:
|
volumes:
|
||||||
|
- name: gcekey
|
||||||
|
secret:
|
||||||
|
secretName: gcekey
|
||||||
|
optional: true
|
||||||
- name: config
|
- name: config
|
||||||
projected:
|
projected:
|
||||||
sources:
|
sources:
|
||||||
|
|
|
@ -50,6 +50,8 @@ spec:
|
||||||
value: QEMU
|
value: QEMU
|
||||||
- name: constellation-uid
|
- name: constellation-uid
|
||||||
value: "42424242424242"
|
value: "42424242424242"
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: /var/secrets/google/key.json
|
||||||
image: constellationOperatorImage
|
image: constellationOperatorImage
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
|
@ -86,6 +88,9 @@ spec:
|
||||||
- mountPath: /etc/gce
|
- mountPath: /etc/gce
|
||||||
name: gceconf
|
name: gceconf
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: /var/secrets/google
|
||||||
|
name: gcekey
|
||||||
|
readOnly: true
|
||||||
- mountPath: /etc/constellation-upgrade-agent.sock
|
- mountPath: /etc/constellation-upgrade-agent.sock
|
||||||
name: upgrade-agent-socket
|
name: upgrade-agent-socket
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
@ -123,6 +128,10 @@ spec:
|
||||||
name: gceconf
|
name: gceconf
|
||||||
optional: true
|
optional: true
|
||||||
name: gceconf
|
name: gceconf
|
||||||
|
- name: gcekey
|
||||||
|
secret:
|
||||||
|
secretName: gcekey
|
||||||
|
optional: true
|
||||||
- name: upgrade-agent-socket
|
- name: upgrade-agent-socket
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /run/constellation-upgrade-agent.sock
|
path: /run/constellation-upgrade-agent.sock
|
||||||
|
|
|
@ -40,6 +40,9 @@ spec:
|
||||||
- --cloud-provider=QEMU
|
- --cloud-provider=QEMU
|
||||||
- --key-service-endpoint=key-service.testNamespace:9000
|
- --key-service-endpoint=key-service.testNamespace:9000
|
||||||
- --attestation-variant=qemu-vtpm
|
- --attestation-variant=qemu-vtpm
|
||||||
|
env:
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: /var/secrets/google/key.json
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /var/config
|
- mountPath: /var/config
|
||||||
name: config
|
name: config
|
||||||
|
@ -47,6 +50,9 @@ spec:
|
||||||
- mountPath: /etc/kubernetes
|
- mountPath: /etc/kubernetes
|
||||||
name: kubeadm
|
name: kubeadm
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: /var/secrets/google
|
||||||
|
name: gcekey
|
||||||
|
readOnly: true
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 9090
|
- containerPort: 9090
|
||||||
name: tcp
|
name: tcp
|
||||||
|
@ -54,6 +60,10 @@ spec:
|
||||||
securityContext:
|
securityContext:
|
||||||
privileged: true
|
privileged: true
|
||||||
volumes:
|
volumes:
|
||||||
|
- name: gcekey
|
||||||
|
secret:
|
||||||
|
secretName: gcekey
|
||||||
|
optional: true
|
||||||
- name: config
|
- name: config
|
||||||
projected:
|
projected:
|
||||||
sources:
|
sources:
|
||||||
|
|
|
@ -31,6 +31,9 @@ spec:
|
||||||
- /manager
|
- /manager
|
||||||
args:
|
args:
|
||||||
- --leader-elect
|
- --leader-elect
|
||||||
|
env:
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: /var/secrets/google/key.json
|
||||||
image: controller:latest
|
image: controller:latest
|
||||||
name: manager
|
name: manager
|
||||||
securityContext:
|
securityContext:
|
||||||
|
@ -60,6 +63,9 @@ spec:
|
||||||
- mountPath: /etc/gce
|
- mountPath: /etc/gce
|
||||||
name: gceconf
|
name: gceconf
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: /var/secrets/google
|
||||||
|
name: gcekey
|
||||||
|
readOnly: true
|
||||||
- mountPath: /etc/constellation-upgrade-agent.sock
|
- mountPath: /etc/constellation-upgrade-agent.sock
|
||||||
name: upgrade-agent-socket
|
name: upgrade-agent-socket
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
@ -91,6 +97,10 @@ spec:
|
||||||
configMap:
|
configMap:
|
||||||
name: gceconf
|
name: gceconf
|
||||||
optional: true
|
optional: true
|
||||||
|
- name: gcekey
|
||||||
|
secret:
|
||||||
|
secretName: gcekey
|
||||||
|
optional: true
|
||||||
- name: upgrade-agent-socket
|
- name: upgrade-agent-socket
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /run/constellation-upgrade-agent.sock
|
path: /run/constellation-upgrade-agent.sock
|
||||||
|
|
|
@ -47,7 +47,7 @@ module "gcp_iam" {
|
||||||
// replace $VERSION with the Constellation version you want to use, e.g., v2.14.0
|
// replace $VERSION with the Constellation version you want to use, e.g., v2.14.0
|
||||||
source = "https://github.com/edgelesssys/constellation/releases/download/$VERSION/terraform-module.zip//terraform-module/iam/gcp"
|
source = "https://github.com/edgelesssys/constellation/releases/download/$VERSION/terraform-module.zip//terraform-module/iam/gcp"
|
||||||
project_id = local.project_id
|
project_id = local.project_id
|
||||||
service_account_id = "${local.name}-sa"
|
name_prefix = local.name
|
||||||
zone = local.zone
|
zone = local.zone
|
||||||
region = local.region
|
region = local.region
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,7 @@ module "gcp_infrastructure" {
|
||||||
project = local.project_id
|
project = local.project_id
|
||||||
internal_load_balancer = false
|
internal_load_balancer = false
|
||||||
cc_technology = local.cc_technology
|
cc_technology = local.cc_technology
|
||||||
|
iam_service_account_vm = module.gcp_iam.service_account_mail_vm
|
||||||
}
|
}
|
||||||
|
|
||||||
data "constellation_attestation" "foo" {
|
data "constellation_attestation" "foo" {
|
||||||
|
|
|
@ -183,6 +183,7 @@ module "instance_group" {
|
||||||
init_secret_hash = local.init_secret_hash
|
init_secret_hash = local.init_secret_hash
|
||||||
custom_endpoint = var.custom_endpoint
|
custom_endpoint = var.custom_endpoint
|
||||||
cc_technology = var.cc_technology
|
cc_technology = var.cc_technology
|
||||||
|
iam_service_account_vm = var.iam_service_account_vm
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_compute_address" "loadbalancer_ip_internal" {
|
resource "google_compute_address" "loadbalancer_ip_internal" {
|
||||||
|
|
|
@ -77,17 +77,11 @@ resource "google_compute_instance_template" "template" {
|
||||||
on_host_maintenance = "TERMINATE"
|
on_host_maintenance = "TERMINATE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Define all IAM access via the service account and not via scopes:
|
||||||
|
# See: https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance_template#nested_service_account
|
||||||
service_account {
|
service_account {
|
||||||
scopes = [
|
email = var.iam_service_account_vm
|
||||||
"https://www.googleapis.com/auth/compute",
|
scopes = ["cloud-platform"]
|
||||||
"https://www.googleapis.com/auth/servicecontrol",
|
|
||||||
"https://www.googleapis.com/auth/service.management.readonly",
|
|
||||||
"https://www.googleapis.com/auth/devstorage.read_only",
|
|
||||||
"https://www.googleapis.com/auth/logging.write",
|
|
||||||
"https://www.googleapis.com/auth/monitoring.write",
|
|
||||||
"https://www.googleapis.com/auth/trace.append",
|
|
||||||
"https://www.googleapis.com/auth/cloud-platform",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shielded_instance_config {
|
shielded_instance_config {
|
||||||
|
|
|
@ -108,3 +108,9 @@ variable "cc_technology" {
|
||||||
error_message = "The confidential computing technology has to be 'SEV' or 'SEV_SNP'."
|
error_message = "The confidential computing technology has to be 'SEV' or 'SEV_SNP'."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "iam_service_account_vm" {
|
||||||
|
type = string
|
||||||
|
default = ""
|
||||||
|
description = "IAM service account used for the VMs"
|
||||||
|
}
|
||||||
|
|
|
@ -76,6 +76,11 @@ variable "additional_labels" {
|
||||||
description = "Additional labels that should be given to created recources."
|
description = "Additional labels that should be given to created recources."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "iam_service_account_vm" {
|
||||||
|
type = string
|
||||||
|
default = ""
|
||||||
|
description = "IAM service account used for the VMs"
|
||||||
|
}
|
||||||
variable "emergency_ssh" {
|
variable "emergency_ssh" {
|
||||||
type = bool
|
type = bool
|
||||||
default = false
|
default = false
|
||||||
|
|
|
@ -13,8 +13,19 @@ provider "google" {
|
||||||
zone = var.zone
|
zone = var.zone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
sa_name = var.name_prefix == "" ? var.service_account_id : "${var.name_prefix}-sa"
|
||||||
|
sa_vm_name = var.name_prefix == "" ? "${var.service_account_id}-vm" : "${var.name_prefix}-sa-vm"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_service_account" "vm" {
|
||||||
|
account_id = local.sa_vm_name
|
||||||
|
display_name = "Constellation service account for VMs"
|
||||||
|
description = "Service account used by the VMs"
|
||||||
|
}
|
||||||
|
|
||||||
resource "google_service_account" "service_account" {
|
resource "google_service_account" "service_account" {
|
||||||
account_id = var.service_account_id
|
account_id = local.sa_name
|
||||||
display_name = "Constellation service account"
|
display_name = "Constellation service account"
|
||||||
description = "Service account used inside Constellation"
|
description = "Service account used inside Constellation"
|
||||||
}
|
}
|
||||||
|
@ -65,6 +76,30 @@ resource "google_project_iam_member" "iam_service_account_user_role" {
|
||||||
depends_on = [null_resource.delay]
|
depends_on = [null_resource.delay]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "google_project_iam_custom_role" "vm" {
|
||||||
|
# role_id must not contain dashes
|
||||||
|
role_id = replace("${local.sa_vm_name}-role", "-", "_")
|
||||||
|
title = "Constellation IAM role for VMs"
|
||||||
|
description = "Constellation IAM role for VMs"
|
||||||
|
permissions = [
|
||||||
|
"compute.instances.get",
|
||||||
|
"compute.instances.list",
|
||||||
|
"compute.subnetworks.get",
|
||||||
|
"compute.globalForwardingRules.list",
|
||||||
|
"compute.zones.list",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_project_iam_binding" "custom_role_vm_to_service_account_vm" {
|
||||||
|
project = var.project_id
|
||||||
|
role = "projects/${var.project_id}/roles/${google_project_iam_custom_role.vm.role_id}"
|
||||||
|
|
||||||
|
members = [
|
||||||
|
"serviceAccount:${google_service_account.vm.email}",
|
||||||
|
]
|
||||||
|
depends_on = [null_resource.delay]
|
||||||
|
}
|
||||||
|
|
||||||
resource "google_service_account_key" "service_account_key" {
|
resource "google_service_account_key" "service_account_key" {
|
||||||
service_account_id = google_service_account.service_account.name
|
service_account_id = google_service_account.service_account.name
|
||||||
depends_on = [null_resource.delay]
|
depends_on = [null_resource.delay]
|
||||||
|
|
|
@ -3,3 +3,9 @@ output "service_account_key" {
|
||||||
description = "Private key of the service account."
|
description = "Private key of the service account."
|
||||||
sensitive = true
|
sensitive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "service_account_mail_vm" {
|
||||||
|
value = google_service_account.vm.email
|
||||||
|
description = "Mail address of the service account to be attached to the VMs"
|
||||||
|
sensitive = false
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,12 @@ variable "project_id" {
|
||||||
|
|
||||||
variable "service_account_id" {
|
variable "service_account_id" {
|
||||||
type = string
|
type = string
|
||||||
description = "ID for the service account being created. Must match ^[a-z](?:[-a-z0-9]{4,28}[a-z0-9])$."
|
description = "[DEPRECATED use var.name_prefix] ID for the service account being created. Must match ^[a-z](?:[-a-z0-9]{4,28}[a-z0-9])$."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "name_prefix" {
|
||||||
|
type = string
|
||||||
|
description = "Prefix to be used for all resources created by this module."
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "region" {
|
variable "region" {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue