Skip to content

Commit ecb337e

Browse files
authored
Support custom resource tags (#271)
1 parent 1a12a7a commit ecb337e

File tree

11 files changed

+86
-13
lines changed

11 files changed

+86
-13
lines changed

cli/internal/install/cloudinstall/cloud-config-pretty.tpl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@ cloud:
88
resourceGroup: {{ .ResourceGroup }}
99
defaultLocation: {{ .DefaultLocation}}
1010

11+
# Tags to apply to all resources and resource groups
12+
{{- if not .ResourceTags }}
13+
# resourceTags:
14+
# mytag: myvalue
15+
{{- else }}
16+
resourceTags:
17+
{{- range $k, $v := .ResourceTags }}
18+
{{ $k }}: {{ $v }}
19+
{{- end }}
20+
{{- end }}
21+
1122
# Whether to use private networking. The default is false.
1223
# If true, Tyger service, storage storage accounts, and all other created resources
1324
# will not be accessible from the public internet.

cli/internal/install/cloudinstall/cloud.go

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -393,19 +393,45 @@ func (inst *Installer) ensureResourceGroupCreated(ctx context.Context, name stri
393393
return fmt.Errorf("failed to create resource groups client: %w", err)
394394
}
395395

396-
resp, err := c.CheckExistence(ctx, name, nil)
397-
if err != nil {
398-
return fmt.Errorf("failed to check resource group existence: %w", err)
396+
var existingResouceGroup *armresources.ResourceGroup
397+
if resp, err := c.Get(ctx, name, nil); err != nil {
398+
var respErr *azcore.ResponseError
399+
if !errors.As(err, &respErr) || respErr.StatusCode != http.StatusNotFound {
400+
return fmt.Errorf("failed to get resource group: %w", err)
401+
}
402+
} else {
403+
existingResouceGroup = &resp.ResourceGroup
399404
}
400405

401-
if resp.Success {
406+
var tags map[string]*string
407+
if len(inst.Config.Cloud.ResourceTags) > 0 {
408+
if existingResouceGroup != nil && existingResouceGroup.Tags != nil {
409+
tags = existingResouceGroup.Tags
410+
} else {
411+
tags = make(map[string]*string)
412+
}
413+
414+
tagsChanged := false
415+
for k, v := range inst.Config.Cloud.ResourceTags {
416+
if existingVal, ok := tags[k]; ok && existingVal != nil && *existingVal == v {
417+
continue
418+
}
419+
tagsChanged = true
420+
tags[k] = &v
421+
}
422+
423+
if !tagsChanged && existingResouceGroup != nil {
424+
return nil
425+
}
426+
} else if existingResouceGroup != nil {
402427
return nil
403428
}
404429

405-
log.Debug().Msgf("Creating resource group '%s'", name)
430+
log.Debug().Msgf("Creating or updating resource group '%s'", name)
406431
_, err = c.CreateOrUpdate(ctx, name,
407432
armresources.ResourceGroup{
408433
Location: Ptr(inst.Config.Cloud.DefaultLocation),
434+
Tags: tags,
409435
}, nil)
410436

411437
if err != nil {

cli/internal/install/cloudinstall/cloudconfig.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ type CloudConfig struct {
6868
SubscriptionID string `yaml:"subscriptionId"`
6969
DefaultLocation string `yaml:"defaultLocation"`
7070
ResourceGroup string `yaml:"resourceGroup"`
71+
ResourceTags map[string]string `yaml:"resourceTags"`
7172
PrivateNetworking bool `yaml:"privateNetworking"`
7273
Compute *ComputeConfig `yaml:"compute"`
7374
Database *DatabaseServerConfig `yaml:"database"`

cli/internal/install/cloudinstall/compute.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ func (inst *Installer) createCluster(ctx context.Context, clusterConfig *Cluster
7474
}
7575

7676
tags[TagKey] = &inst.Config.EnvironmentName
77+
for k, v := range inst.Config.Cloud.ResourceTags {
78+
tags[k] = &v
79+
}
7780

7881
clustersClient, err := armcontainerservice.NewManagedClustersClient(inst.Config.Cloud.SubscriptionID, inst.Credential, nil)
7982
if err != nil {
@@ -509,6 +512,9 @@ func (inst *Installer) createOutboundIpAddress(ctx context.Context, cluster *Clu
509512
azureTags = make(map[string]*string)
510513
}
511514
azureTags[TagKey] = &inst.Config.EnvironmentName
515+
for k, v := range inst.Config.Cloud.ResourceTags {
516+
azureTags[k] = &v
517+
}
512518

513519
ipTags := []*armnetwork.IPTag{}
514520
for _, t := range cluster.OutboundIpServiceTags {

cli/internal/install/cloudinstall/database.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import (
1010
"errors"
1111
"fmt"
1212
"net/http"
13+
"regexp"
1314
"strconv"
14-
"strings"
1515
"time"
1616

1717
"maps"
@@ -83,6 +83,9 @@ func (inst *Installer) createDatabaseServer(ctx context.Context) (any, error) {
8383
tags = make(map[string]*string)
8484
}
8585
tags[TagKey] = &inst.Config.EnvironmentName
86+
for k, v := range inst.Config.Cloud.ResourceTags {
87+
tags[k] = &v
88+
}
8689
if instanceKey := tags[dbServerInstanceTagKey]; instanceKey == nil || *instanceKey == "" {
8790
tags[dbServerInstanceTagKey] = Ptr(uuid.NewString())
8891
}
@@ -646,7 +649,7 @@ func (inst *Installer) createRoles(
646649
break
647650
}
648651

649-
if strings.Contains(err.Error(), "OID is not found in the tenant") {
652+
if regexp.MustCompile("OID (is not|isn't) found in the tenant").MatchString(err.Error()) {
650653
// It can take some time before the database is able to retrieve principals that have been recently created
651654
log.Ctx(ctx).Warn().Msgf("Database role creation failed. Attempt %d/%d", roleCreateRetryCount+1, RoleCreateMaxRetries)
652655
continue

cli/internal/install/cloudinstall/mi.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ func (inst *Installer) createManagedIdentity(ctx context.Context, name string, r
7777
}
7878

7979
tags[TagKey] = &inst.Config.EnvironmentName
80+
for k, v := range inst.Config.Cloud.ResourceTags {
81+
tags[k] = &v
82+
}
8083

8184
resp, err := identitiesClient.CreateOrUpdate(ctx, resourceGroup, name, armmsi.Identity{
8285
Location: &inst.Config.Cloud.DefaultLocation,

cli/internal/install/cloudinstall/network.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ func (inst *Installer) createPrivateEndpoints(ctx context.Context, privateEndpoi
7878
},
7979
}
8080

81+
for k, v := range inst.Config.Cloud.ResourceTags {
82+
privateEndpoint.Tags[k] = &v
83+
}
84+
8185
log.Ctx(ctx).Info().Msgf("Creating or updating private endpoint '%s' for storage account '%s' for subnet '%s' in vnet '%s'", privateEndpointName, path.Base(targetResourceId), configSubnet.SubnetName, configSubnet.VNetName)
8286

8387
privateEndpointClient, err := armnetwork.NewPrivateEndpointsClient(inst.Config.Cloud.SubscriptionID, inst.Credential, nil)
@@ -122,11 +126,17 @@ func (inst *Installer) createPrivateDnsZone(ctx context.Context, domainName stri
122126

123127
log.Ctx(ctx).Info().Msgf("Creating or updating private DNS zone '%s'", domainName)
124128

129+
tags := map[string]*string{
130+
TagKey: &inst.Config.EnvironmentName,
131+
}
132+
133+
for k, v := range inst.Config.Cloud.ResourceTags {
134+
tags[k] = &v
135+
}
136+
125137
dnsZonePoller, err := privateDNSZoneClient.BeginCreateOrUpdate(ctx, subnet.PrivateLinkResourceGroup, domainName, armprivatedns.PrivateZone{
126138
Location: Ptr("global"),
127-
Tags: map[string]*string{
128-
TagKey: &inst.Config.EnvironmentName,
129-
},
139+
Tags: tags,
130140
}, nil)
131141

132142
if err != nil {
@@ -162,9 +172,7 @@ func (inst *Installer) createPrivateDnsZone(ctx context.Context, domainName stri
162172
ID: vnetResult.ID,
163173
},
164174
},
165-
Tags: map[string]*string{
166-
TagKey: &inst.Config.EnvironmentName,
167-
},
175+
Tags: tags,
168176
}, nil)
169177

170178
if err != nil {

cli/internal/install/cloudinstall/storage.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ func (inst *Installer) CreateStorageAccount(ctx context.Context,
4242
tags = make(map[string]*string)
4343
}
4444
tags[TagKey] = &inst.Config.EnvironmentName
45+
for k, v := range inst.Config.Cloud.ResourceTags {
46+
tags[k] = &v
47+
}
4548

4649
parameters := armstorage.AccountCreateParameters{
4750
Tags: tags,

deploy/config/microsoft/cloudconfig-private-link.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ cloud:
77
resourceGroup: ${TYGER_ENVIRONMENT_NAME}
88
defaultLocation: ${TYGER_LOCATION}
99

10+
# Tags to apply to all resources and resource groups
11+
resourceTags:
12+
tyger-development: "true"
13+
1014
# Whether to use private networking. The default is false.
1115
# If true, Tyger service, storage storage accounts, and all other created resources
1216
# will not be accessible from the public internet.

deploy/config/microsoft/cloudconfig.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ cloud:
77
resourceGroup: ${TYGER_ENVIRONMENT_NAME}
88
defaultLocation: ${TYGER_LOCATION}
99

10+
# Tags to apply to all resources and resource groups
11+
resourceTags:
12+
tyger-development: "true"
13+
1014
# Whether to use private networking. The default is false.
1115
# If true, Tyger service, storage storage accounts, and all other created resources
1216
# will not be accessible from the public internet.

0 commit comments

Comments
 (0)