Nil pointer for existing parameter value
pnc opened this issue · comments
Approximate steps to reproduce:
- Deploy the following stack, setting a value like
arn:aws:iam::xxx:role/phil-axle-ReplicationRole-VwMQmmcofdJ
for the single parameter, which works normally. - Attempt to update the stack (I changed the lifecycle duration) using rain:
› ./rain --version
Rain v1.8.3 darwin/arm64
› rain deploy backup-bucket.yml phil-axle-backup
Enter a value for parameter 'SourceRoleArn' "The ARN of the IAM role from the source account that will perform the replication." (existing value: arn:aws:iam::xxx:role/phil-axle-ReplicationRole-VwMQmmcofdJ)
At this point I press enter without entering a value, intending to make it use the current value.
Rain shows some progess information and then exits with this error:
runtime error: invalid memory address or nil pointer dereference
Expected results: Rain uses the existing value (in parens) as the value (common UNIX tool UX, see adduser
for example), or deploys the stack with the value blanked out, but either way doesn't crash.
here's the backtrace lldb gives:
› lldb rain deploy backup-bucket.yml phil-axle-backup
(lldb) target create "rain"
Current executable set to '/opt/homebrew/bin/rain' (arm64).
(lldb) settings set -- target.run-args "deploy" "backup-bucket.yml" "phil-axle-backup"
(lldb) run
Process 86583 launched: '/opt/homebrew/bin/rain' (arm64)
Enter a value for parameter 'SourceRoleArn' "The ARN of the IAM role from the source account that will perform the replication." (existing value: arn:aws:iam::403345046096:role/phil-axle-ReplicationRole-VwMQmmcofdJj):
Creating change set .· Creating change set .· Creating change set .˙Creating change set ˙ ·Creating change set ·˙.Process 86583 stopped
* thread #14, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00000001007ce324 rain`github.com/aws-cloudformation/rain/internal/aws/cfn.CreateChangeSet + 2308
rain`github.com/aws-cloudformation/rain/internal/aws/cfn.CreateChangeSet:
-> 0x1007ce324 <+2308>: ldr x0, [x3]
0x1007ce328 <+2312>: ldr x1, [x3, #0x8]
0x1007ce32c <+2316>: bl 0x10000dd50 ; runtime.convTstring
0x1007ce330 <+2320>: adrp x2, 2978
Target 0: (rain) stopped.
This advice from https://go.dev/doc/gdb also appears to apply to lldb on macos:
As of Go 1.11, debug information is compressed by default. Older versions of gdb, such as the one available by default on MacOS, do not understand the compression. You can generate uncompressed debug information by using go build -ldflags=-compressdwarf=false. (For convenience you can put the -ldflags option in the GOFLAGS environment variable so that you don't have to specify it each time.)
I cloned 2fe3ddc and ran:
phil@Neutrino ~/rain on main› go build -ldflags=-compressdwarf=false ./cmd/rain
› lldb -- ./rain deploy ../infrastructure/backup-bucket.yml phil-axle-backup
(lldb) target create "./rain"
Current executable set to '/Users/phil/rain/rain' (arm64).
(lldb) settings set -- target.run-args "deploy" "../infrastructure/backup-bucket.yml" "phil-axle-backup"
(lldb) run
Process 89594 launched: '/Users/phil/rain/rain' (arm64)
Enter a value for parameter 'SourceRoleArn' "The ARN of the IAM role from the source account that will perform the replication." (existing value: arn:aws:iam::403345046096:role/phil-axle-ReplicationRole-VwMQmmcofdJj):
Creating change set ˙ ·Creating change set ˙ ·Creating change set ·˙.Process 89594 stopped
* thread #11, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00000001007ce1b4 rain`github.com/aws-cloudformation/rain/internal/aws/cfn.CreateChangeSet at cfn.go:472
469 config.Debugf("About to create changeset with body:\n%s", templateBody)
470 for _, param := range params {
471 config.Debugf("Parameter Key: %s, Value: %s",
-> 472 *param.ParameterKey, *param.ParameterValue)
473 }
474 }
475
Target 0: (rain) stopped.
Template:
AWSTemplateFormatVersion: '2010-09-09'
Description: description
Parameters:
SourceRoleArn:
Description: The ARN of the IAM role from the source account that will perform the replication.
Type: String
ObjectLockMode:
Description: |
Set this to `GOVERNANCE` initially to allow overriding the object lock in case something goes wrong.
Once you set this to `COMPLIANCE`, the S3 object lock mode is changed to compliance mode and
locked objects will be retained for their full duration. This cannot be overridden or changed
by anyone, including AWS, so make sure the retention isn't something undesirable like 7 years.
See https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html#object-lock-retention-modes
Type: String
Default: GOVERNANCE
AllowedValues:
- GOVERNANCE
- COMPLIANCE
Resources:
Bucket:
Type: 'AWS::S3::Bucket'
DeletionPolicy: Retain
Properties:
AccessControl: Private
# Versioning is best practice, and also required for replication to work
VersioningConfiguration:
Status: Enabled
ObjectLockEnabled: true
ObjectLockConfiguration:
ObjectLockEnabled: "Enabled"
Rule:
DefaultRetention:
# Governance mode can be overridden by authorized users, compliance mode cannot
Mode: !Ref ObjectLockMode
Days: 7
LifecycleConfiguration:
Rules:
# Delete markers will be replicated from the source bucket, but in case of malicious
# or accidental deletes, we want to keep the original objects for a period of time
# so they can be manually restored.
- Id: Keep deleted versions for 14 days and delete tombstones
NoncurrentVersionExpirationInDays: 14
ExpiredObjectDeleteMarker: true
AbortIncompleteMultipartUpload:
DaysAfterInitiation: 7
Status: Enabled
OwnershipControls:
Rules:
- ObjectOwnership: BucketOwnerEnforced
ReplicaBucketPolicy:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref Bucket
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: 'AllowReplicationFromSourceBucket'
Effect: 'Allow'
Principal:
AWS: !Ref SourceRoleArn
Action:
- s3:ReplicateObject
- s3:ReplicateDelete
- s3:ReplicateTags
- s3:List*
- s3:PutBucketVersioning
- s3:GetBucketVersioning
Resource:
- !Sub '${Bucket.Arn}'
- !Sub '${Bucket.Arn}/*'
For others, I'm able to work around the crash by providing the same value (arn:aws:iam::xxx:role/phil-axle-ReplicationRole-VwMQmmcofdJ
) for the parameter rather than pressing Enter.
I can reproduce this with a simple test case. Will work on a fix today.