awslabs / goformation

GoFormation is a Go library for working with CloudFormation templates.
Apache License 2.0
841 stars 197 forks source link

BREAKING CHANGE: Unable to use Intrinsic Functions on non string fields #678

Open henriqueleite42 opened 5 days ago

henriqueleite42 commented 5 days ago

I'm creating this topic with the maximum amount of keywords that I can, because I noticed that this is a problem that is generating lots of duplicated issues. So if you have the same issue, please leave a comment here to explain the urgency to fix it.

The problem

Most of the structs in goformation have types other than string, like ecs.Service.DesiredCount that has an *int type. This makes it impossible to use Intrinsic Functions like Ref, FindInMap, ImportValue, Sub and others.

Examples:

From #215:

template.Resources["autoscalingGroup"] = &resources.AWSAutoScalingAutoScalingGroup{
  AvailabilityZones: cloudformation.GetAZs(cloudformation.Ref("AWS::Region")),
  VPCZoneIdentifier: cloudformation.Ref("Subnets"),
}

From #252:

rootTemplate.Resources["DynamoDb"] = &dynamodb.Table{
    PointInTimeRecoverySpecification: &dynamodb.Table_PointInTimeRecoverySpecification{
        PointInTimeRecoveryEnabled: cloudformation.If("CreateDynamoBackUp", true, false),
   },
}

From #282:

Subnets: cloudformation.Ref("SubnetIds")

From #304:

resources["Server"] = &ec2.Instance{
    BlockDeviceMappings: []ec2.Instance_BlockDeviceMapping{
        {
            DeviceName: "/dev/xvda",
            Ebs:        &ec2.Instance_Ebs{
            VolumeSize: cloudformation.Ref("Ec2InstanceRootVolumeSize"), // cannot assign string as int
            },
        },
    },
}

From #306:

rds.DBSubnetGroup{
        DBSubnetGroupDescription: "Subnet Group for Aurora Cluster",
        SubnetIds:                cloudformation.Ref("SubnetIds"),
    }

rds.DBCluster{
        Engine:              "aurora-mysql",
                ....
        VpcSecurityGroupIds: cloudformation.Ref("SecurityGroupIds"),
    }

lambda.Function{
                ....
        VpcConfig: lambda.Function_VpcConfig{
            SubnetIds: cloudformation.Ref("SubnetIds"),
            SecurityGroupIds: [cloudformation.Ref("SecurityGroupIds"),
        }
    }

Proposed solutions

  1. Make all intrinsic functions return generic types
  2. Make all struct fields accept only string
  3. Create different functions to make each one of them have the specific type that we need
  4. Maybe the @drmmarsunited fork mentioned on #600 can help with this problem too

I do not know the implications of these solutions, so please, let's discuss them, so we can create a PR to fix this recurring issue.

Duplicated issues and related people

Issues: #215 #252 #282 #304 #306 #467 People: @romanolux @prometherion @RafRabenda @Envek @efekarakus @ndeloof @xrn @jomast @mheffner @ipmb

henriqueleite42 commented 3 days ago

@rubenfonseca can you give a look at this, please?