Skip to content
This repository was archived by the owner on Jan 29, 2026. It is now read-only.

Commit b59bf42

Browse files
authored
Merge pull request crossplane-contrib#1598 from wotolom/rdsinstane-allow-major-version-upgrade
Fixes crossplane-contrib#1330
2 parents c9ed477 + 9fc98b3 commit b59bf42

File tree

14 files changed

+243
-50
lines changed

14 files changed

+243
-50
lines changed

apis/rds/generator-config.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ operations:
77
operation_type: Delete
88

99
resources:
10+
DBInstance:
11+
fields:
12+
AllowMajorVersionUpgrade:
13+
from:
14+
operation: ModifyDBInstance
15+
path: AllowMajorVersionUpgrade
16+
DBCluster:
17+
fields:
18+
AllowMajorVersionUpgrade:
19+
from:
20+
operation: ModifyDBCluster
21+
path: AllowMajorVersionUpgrade
1022
DBInstanceRoleAssociation:
1123
exceptions:
1224
errors:

apis/rds/v1alpha1/custom_types.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ type CustomDBClusterParameters struct {
196196
// Constraints: Must contain from 8 to 41 characters. Required.
197197
MasterUserPasswordSecretRef *xpv1.SecretKeySelector `json:"masterUserPasswordSecretRef"`
198198

199-
// A list of EC2 VPC security groups to associate with this DB cluster.
199+
// A list of VPC security groups that the DB cluster will belong to.
200+
//
201+
// Valid for: Aurora DB clusters and Multi-AZ DB clusters
200202
VPCSecurityGroupIDs []string `json:"vpcSecurityGroupIDs,omitempty"`
201203

202204
// VPCSecurityGroupIDRefs are references to VPCSecurityGroups used to set
@@ -539,7 +541,17 @@ type CustomDBInstanceParameters struct {
539541
// +optional
540542
SkipFinalSnapshot bool `json:"skipFinalSnapshot,omitempty"`
541543

542-
// A list of EC2 VPC security groups to associate with this DB instance.
544+
// A list of Amazon EC2 VPC security groups to authorize on this DB instance.
545+
// This change is asynchronously applied as soon as possible.
546+
//
547+
// This setting doesn't apply to RDS Custom.
548+
//
549+
// Amazon Aurora
550+
// Not applicable. The associated list of EC2 VPC security groups is managed
551+
// by the DB cluster. For more information, see ModifyDBCluster.
552+
//
553+
// Constraints:
554+
// * If supplied, must match existing VpcSecurityGroupIds.
543555
VPCSecurityGroupIDs []string `json:"vpcSecurityGroupIDs,omitempty"`
544556

545557
// VPCSecurityGroupIDRefs are references to VPCSecurityGroups used to set

apis/rds/v1alpha1/zz_db_cluster.go

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apis/rds/v1alpha1/zz_db_instance.go

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apis/rds/v1alpha1/zz_generated.deepcopy.go

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/rds/db-aurora-cluster.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ spec:
66
forProvider:
77
region: us-east-1
88
engine: aurora-mysql
9-
masterUsername: admin
9+
allowMajorVersionUpgrade: true # unset per default (Note: dbClusterParameterGroup with correct dbParameterClusterGroupFamily may needed, before majorVersion upgrade possible)
10+
# for majorVersion upgrade via Cluster - depending on the setup - instances may need adjustments: before (e.g. supported instanceClass) or after (e.g. matching dbParameterGroup) the upgrade
11+
masterUsername: adminuser
1012
masterUserPasswordSecretRef:
1113
name: example-aurora-mysql-cluster
1214
namespace: crossplane-system

examples/rds/db-instance.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ spec:
99
autoMinorVersionUpgrade: true
1010
autogeneratePassword: true
1111
backupRetentionPeriod: 14
12-
dbInstanceClass: db.t2.micro
12+
dbInstanceClass: db.t3.micro # needs to support engine and -version (see AWS Docs: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.DBInstanceClass.html#Concepts.DBInstanceClass.Support)
1313
dbName: example
1414
engine: postgres
1515
engineVersion: "12.9"
16+
allowMajorVersionUpgrade: true # unset per default (Note: supported dbInstanceClass and dbParameterGroup with correct dbParameterGroupFamily needed, before majorVersion upgrade possible; applyImmediately matters)
1617
masterUsername: adminuser
1718
masterUserPasswordSecretRef:
1819
key: password

package/crds/rds.aws.crossplane.io_dbclusters.yaml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ spec:
6868
DB clusters only"
6969
format: int64
7070
type: integer
71+
allowMajorVersionUpgrade:
72+
description: "A value that indicates whether major version upgrades
73+
are allowed. \n Constraints: You must allow major version upgrades
74+
when specifying a value for the EngineVersion parameter that
75+
is a different major version than the DB cluster's current version.
76+
\n Valid for: Aurora DB clusters only"
77+
type: boolean
7178
applyImmediately:
7279
description: "A value that indicates whether the modifications
7380
in this request and any pending modifications are asynchronously
@@ -1075,8 +1082,9 @@ spec:
10751082
type: object
10761083
type: object
10771084
vpcSecurityGroupIDs:
1078-
description: A list of EC2 VPC security groups to associate with
1079-
this DB cluster.
1085+
description: "A list of VPC security groups that the DB cluster
1086+
will belong to. \n Valid for: Aurora DB clusters and Multi-AZ
1087+
DB clusters"
10801088
items:
10811089
type: string
10821090
type: array

package/crds/rds.aws.crossplane.io_dbinstances.yaml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,15 @@ spec:
105105
and Express editions: Must be an integer from 20 to 1024."
106106
format: int64
107107
type: integer
108+
allowMajorVersionUpgrade:
109+
description: "A value that indicates whether major version upgrades
110+
are allowed. Changing this parameter doesn't result in an outage
111+
and the change is asynchronously applied as soon as possible.
112+
\n This setting doesn't apply to RDS Custom. \n Constraints:
113+
Major version upgrades must be allowed when specifying a value
114+
for the EngineVersion parameter that is a different major version
115+
than the DB instance's current version."
116+
type: boolean
108117
applyImmediately:
109118
description: "A value that indicates whether the modifications
110119
in this request and any pending modifications are asynchronously
@@ -1284,8 +1293,13 @@ spec:
12841293
type: object
12851294
type: object
12861295
vpcSecurityGroupIDs:
1287-
description: A list of EC2 VPC security groups to associate with
1288-
this DB instance.
1296+
description: "A list of Amazon EC2 VPC security groups to authorize
1297+
on this DB instance. This change is asynchronously applied as
1298+
soon as possible. \n This setting doesn't apply to RDS Custom.
1299+
\n Amazon Aurora Not applicable. The associated list of EC2
1300+
VPC security groups is managed by the DB cluster. For more information,
1301+
see ModifyDBCluster. \n Constraints: * If supplied, must match
1302+
existing VpcSecurityGroupIds."
12891303
items:
12901304
type: string
12911305
type: array

pkg/controller/rds/dbcluster/setup.go

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,16 @@ func (e *custom) postObserve(ctx context.Context, cr *svcapitypes.DBCluster, res
9595
return managed.ExternalObservation{}, err
9696
}
9797
switch aws.StringValue(resp.DBClusters[0].Status) {
98-
case "available", "modifying":
98+
case "available", "storage-optimization", "backing-up":
9999
cr.SetConditions(xpv1.Available())
100-
case "deleting", "stopped", "stopping":
101-
cr.SetConditions(xpv1.Unavailable())
100+
case "modifying":
101+
cr.SetConditions(xpv1.Available().WithMessage("DB Cluster is " + aws.StringValue(resp.DBClusters[0].Status) + ", availability may vary"))
102+
case "deleting":
103+
cr.SetConditions(xpv1.Deleting())
102104
case "creating":
103105
cr.SetConditions(xpv1.Creating())
106+
default:
107+
cr.SetConditions(xpv1.Unavailable().WithMessage("DB Cluster is " + aws.StringValue(resp.DBClusters[0].Status)))
104108
}
105109

106110
obs.ConnectionDetails = managed.ConnectionDetails{
@@ -527,7 +531,7 @@ func generateRestoreDBClusterToPointInTimeInput(cr *svcapitypes.DBCluster) *svcs
527531

528532
func isUpToDate(cr *svcapitypes.DBCluster, out *svcsdk.DescribeDBClustersOutput) (bool, error) { // nolint:gocyclo
529533
status := aws.StringValue(out.DBClusters[0].Status)
530-
if status == "modifying" || status == "upgrading" || status == "configuring-iam-database-auth" || status == "migrating" || status == "prepairing-data-migration" {
534+
if status == "modifying" || status == "upgrading" || status == "configuring-iam-database-auth" || status == "migrating" || status == "prepairing-data-migration" || status == "creating" {
531535
return true, nil
532536
}
533537

@@ -567,7 +571,12 @@ func isUpToDate(cr *svcapitypes.DBCluster, out *svcsdk.DescribeDBClustersOutput)
567571
return false, nil
568572
}
569573

570-
if !isVPCSecurityGroupIDsUpToDate(cr, out) {
574+
if !areVPCSecurityGroupIDsUpToDate(cr, out) {
575+
return false, nil
576+
}
577+
578+
if cr.Spec.ForProvider.DBClusterParameterGroupName != nil &&
579+
aws.StringValue(cr.Spec.ForProvider.DBClusterParameterGroupName) != aws.StringValue(out.DBClusters[0].DBClusterParameterGroup) {
571580
return false, nil
572581
}
573582

@@ -653,14 +662,20 @@ func isPortUpToDate(cr *svcapitypes.DBCluster, out *svcsdk.DescribeDBClustersOut
653662
return true
654663
}
655664

656-
func isVPCSecurityGroupIDsUpToDate(cr *svcapitypes.DBCluster, out *svcsdk.DescribeDBClustersOutput) bool {
657-
// AWS uses "sg-563ab33d" which ich really restrictive as the default, and it seems to use it even when it is
658-
// patched (with "required") - might be race condition. Anyway with checking if there is a diff we can rectify and
659-
// even make it configurable after creation.
665+
func areVPCSecurityGroupIDsUpToDate(cr *svcapitypes.DBCluster, out *svcsdk.DescribeDBClustersOutput) bool {
666+
// AWS uses the default SG which is really restrictive, and it seems to use it even when it is
667+
// patched (with "required") - might be race condition. Anyway with checking if there is a diff
668+
// we can rectify and even make it configurable after creation.
660669

661-
actualGroups := out.DBClusters[0].VpcSecurityGroups
662670
desiredIDs := cr.Spec.ForProvider.VPCSecurityGroupIDs
663671

672+
// if user is fine with default SG (removing all SGs is not possible, AWS will keep last set SGs)
673+
if len(desiredIDs) == 0 {
674+
return true
675+
}
676+
677+
actualGroups := out.DBClusters[0].VpcSecurityGroups
678+
664679
if len(desiredIDs) != len(actualGroups) {
665680
return false
666681
}
@@ -680,6 +695,20 @@ func preUpdate(_ context.Context, cr *svcapitypes.DBCluster, obj *svcsdk.ModifyD
680695
obj.DBClusterIdentifier = aws.String(meta.GetExternalName(cr))
681696
obj.ApplyImmediately = cr.Spec.ForProvider.ApplyImmediately
682697

698+
if cr.Spec.ForProvider.VPCSecurityGroupIDs != nil {
699+
obj.VpcSecurityGroupIds = make([]*string, len(cr.Spec.ForProvider.VPCSecurityGroupIDs))
700+
for i, v := range cr.Spec.ForProvider.VPCSecurityGroupIDs {
701+
obj.VpcSecurityGroupIds[i] = aws.String(v)
702+
}
703+
}
704+
705+
// ModifyDBCluster() returns error, when trying to upgrade major (minor is fine) EngineVersion:
706+
// "Cannot change VPC security group while doing a major version upgrade."
707+
// even when the provided VPCSecurityGroupIDs are upToDate...
708+
// therefore EngineVersion update is entirely done separately in postUpdate
709+
// Note: strangely ModifyDBInstance does not seem to behave this way
710+
obj.EngineVersion = nil
711+
683712
return nil
684713
}
685714

@@ -688,6 +717,24 @@ func (u *updater) postUpdate(ctx context.Context, cr *svcapitypes.DBCluster, obj
688717

689718
input := GenerateDescribeDBClustersInput(cr)
690719
resp, err := u.client.DescribeDBClustersWithContext(ctx, input)
720+
if err != nil {
721+
return managed.ExternalUpdate{}, aws.Wrap(cpresource.Ignore(IsNotFound, err), errDescribe)
722+
}
723+
724+
if !isEngineVersionUpToDate(cr, resp) {
725+
// AWS does not want major EngineVersion upgrades in a ModifyDBCluster()-request
726+
// that contains any value in VPCSecurityGroupIDs.
727+
// Therefore doing here a separate call for EngineVersion changes only
728+
_, err := u.client.ModifyDBClusterWithContext(ctx, &svcsdk.ModifyDBClusterInput{
729+
DBClusterIdentifier: aws.String(meta.GetExternalName(cr)),
730+
EngineVersion: cr.Spec.ForProvider.EngineVersion,
731+
AllowMajorVersionUpgrade: cr.Spec.ForProvider.AllowMajorVersionUpgrade,
732+
ApplyImmediately: cr.Spec.ForProvider.ApplyImmediately,
733+
})
734+
if err != nil {
735+
return managed.ExternalUpdate{}, err
736+
}
737+
}
691738

692739
tags := resp.DBClusters[0].TagList
693740

@@ -699,11 +746,7 @@ func (u *updater) postUpdate(ctx context.Context, cr *svcapitypes.DBCluster, obj
699746
return managed.ExternalUpdate{}, err
700747
}
701748
}
702-
if err != nil {
703-
if err != nil {
704-
return managed.ExternalUpdate{}, aws.Wrap(cpresource.Ignore(IsNotFound, err), errDescribe)
705-
}
706-
}
749+
707750
if !isPreferredMaintenanceWindowUpToDate(cr, resp) {
708751
return upd, errors.New("PreferredMaintenanceWindow not matching aws data")
709752
}

0 commit comments

Comments
 (0)