diff --git a/grails-app/controllers/com/netflix/asgard/AutoScalingController.groovy b/grails-app/controllers/com/netflix/asgard/AutoScalingController.groovy
index 5649ad61..503600bd 100644
--- a/grails-app/controllers/com/netflix/asgard/AutoScalingController.groovy
+++ b/grails-app/controllers/com/netflix/asgard/AutoScalingController.groovy
@@ -294,7 +294,7 @@ class AutoScalingController {
String groupName = Relationships.buildGroupName(params)
Subnets subnets = awsEc2Service.getSubnets(userContext)
String subnetPurpose = params.subnetPurpose ?: null
- String vpcId = subnets.getVpcIdForSubnetPurpose(subnetPurpose) ?: ''
+ String vpcId = subnets.getVpcIdForSubnetPurpose(subnetPurpose) ?: ''
// Auto Scaling Group
Integer minSize = (params.min ?: 0) as Integer
@@ -336,10 +336,11 @@ class AutoScalingController {
String ramdiskId = params.ramdiskId ?: null
String iamInstanceProfile = params.iamInstanceProfile ?: configService.defaultIamRole
boolean ebsOptimized = params.ebsOptimized?.toBoolean()
+ boolean associatePublicIpAddress = params.associatePublicIpAddress ?: false
LaunchConfiguration launchConfigTemplate = new LaunchConfiguration().withImageId(imageId).
withKernelId(kernelId).withInstanceType(instType).withKeyName(keyName).withRamdiskId(ramdiskId).
withSecurityGroups(securityGroups).withIamInstanceProfile(iamInstanceProfile).
- withEbsOptimized(ebsOptimized)
+ withEbsOptimized(ebsOptimized).withAssociatePublicIpAddress(associatePublicIpAddress)
if (params.pricing == InstancePriceType.SPOT.name()) {
launchConfigTemplate.spotPrice = spotInstanceRequestService.recommendSpotPrice(userContext, instType)
}
diff --git a/grails-app/controllers/com/netflix/asgard/ClusterController.groovy b/grails-app/controllers/com/netflix/asgard/ClusterController.groovy
index 03099278..10036167 100644
--- a/grails-app/controllers/com/netflix/asgard/ClusterController.groovy
+++ b/grails-app/controllers/com/netflix/asgard/ClusterController.groovy
@@ -116,6 +116,12 @@ class ClusterController {
withFormat {
html {
AutoScalingGroupData lastGroup = cluster.last()
+ LaunchConfiguration lastLaunchConfig = awsAutoScalingService.
+ getLaunchConfiguration(userContext, lastGroup.launchConfigurationName, From.CACHE)
+ boolean associatePublicIpAddress = false
+ if (lastLaunchConfig) {
+ associatePublicIpAddress = lastLaunchConfig.isAssociatePublicIpAddress()
+ }
String nextGroupName = Relationships.buildNextAutoScalingGroupName(lastGroup.autoScalingGroupName)
Boolean okayToCreateGroup = cluster.size() < Relationships.CLUSTER_MAX_GROUPS
String recommendedNextStep = cluster.size() >= Relationships.CLUSTER_MAX_GROUPS ?
@@ -161,7 +167,9 @@ ${lastGroup.loadBalancerNames}"""
loadBalancersGroupedByVpcId: loadBalancers.groupBy { it.VPCId },
selectedLoadBalancers: selectedLoadBalancers,
spotUrl: configService.spotUrl,
- pricing: params.pricing ?: attributes.pricing
+ associatePublicIpAddress: lastLaunchConfig.getAssociatePublicIpAddress(),
+ pricing: params.pricing ?: attributes.pricing,
+
])
attributes
}
@@ -430,6 +438,8 @@ ${loadBalancerNames}"""
Group: ${lastGroup.loadBalancerNames}"""
boolean ebsOptimized = params.containsKey('ebsOptimized') ? params.ebsOptimized?.toBoolean() :
lastLaunchConfig.ebsOptimized
+ boolean associatePublicIpAddress = params.containsKey('associatePublicIpAddress') ? params.associatePublicIpAddress?.toBoolean() :
+ lastLaunchConfig.associatePublicIpAddress
if (params.noOptionalDefaults != 'true') {
securityGroups = securityGroups ?: lastLaunchConfig.securityGroups
termPolicies = termPolicies ?: lastGroup.terminationPolicies
@@ -440,7 +450,7 @@ Group: ${lastGroup.loadBalancerNames}"""
log.debug """ClusterController.createNextGroup for Cluster '${cluster.name}' Load Balancers for next \
Group: ${loadBalancerNames}"""
GroupCreateOptions options = new GroupCreateOptions(
- common: new CommonPushOptions(
+ common: new CommonPushOptions(
userContext: userContext,
checkHealth: checkHealth,
afterBootWait: convertToIntOrUseDefault(params.afterBootWait, 30),
@@ -450,7 +460,7 @@ Group: ${loadBalancerNames}"""
instanceType: instanceType,
groupName: nextGroupName,
securityGroups: securityGroups,
- maxStartupRetries: convertToIntOrUseDefault(params.maxStartupRetries, 5)
+ maxStartupRetries: convertToIntOrUseDefault(params.maxStartupRetries, 5)
),
initialTraffic: initialTraffic,
minSize: minSize,
@@ -470,7 +480,8 @@ Group: ${loadBalancerNames}"""
scheduledActions: newScheduledActions,
vpcZoneIdentifier: vpcZoneIdentifier,
spotPrice: spotPrice,
- ebsOptimized: ebsOptimized
+ ebsOptimized: ebsOptimized,
+ associatePublicIpAddress: associatePublicIpAddress
)
def operation = pushService.startGroupCreate(options)
flash.message = "${operation.task.name} has been started."
diff --git a/grails-app/views/launchConfiguration/_launchConfigOptions.gsp b/grails-app/views/launchConfiguration/_launchConfigOptions.gsp
index 6a6c8f03..a28f986d 100644
--- a/grails-app/views/launchConfiguration/_launchConfigOptions.gsp
+++ b/grails-app/views/launchConfiguration/_launchConfigOptions.gsp
@@ -75,6 +75,14 @@
+
+
+
+ |
+
+ checked />
+ |
+
diff --git a/grails-app/views/launchConfiguration/_launchTemplateFields.gsp b/grails-app/views/launchConfiguration/_launchTemplateFields.gsp
index 70a10d77..e902fbe3 100644
--- a/grails-app/views/launchConfiguration/_launchTemplateFields.gsp
+++ b/grails-app/views/launchConfiguration/_launchTemplateFields.gsp
@@ -44,6 +44,10 @@
| Instance Type: |
${launchTemplate.instanceType} |
+
+ VPC Associate Public IP's: |
+ ${launchTemplate.associatePublicIpAddress} |
+
Kernel ID: |
diff --git a/src/groovy/com/netflix/asgard/model/LaunchConfigurationBeanOptions.groovy b/src/groovy/com/netflix/asgard/model/LaunchConfigurationBeanOptions.groovy
index a08111c5..2caede99 100644
--- a/src/groovy/com/netflix/asgard/model/LaunchConfigurationBeanOptions.groovy
+++ b/src/groovy/com/netflix/asgard/model/LaunchConfigurationBeanOptions.groovy
@@ -68,6 +68,9 @@ import groovy.transform.Canonical
/** @see LaunchConfiguration#ebsOptimized */
Boolean ebsOptimized
+
+ /** @see LaunchConfiguration#associatePublicIpAddress */
+ Boolean associatePublicIpAddress
void setSecurityGroups(Collection securityGroups) {
this.securityGroups = copyNonNullToSet(securityGroups)
@@ -95,6 +98,7 @@ import groovy.transform.Canonical
static LaunchConfigurationBeanOptions from(LaunchConfigurationBeanOptions source) {
new LaunchConfigurationBeanOptions(
launchConfigurationName: source.launchConfigurationName,
+ associatePublicIpAddress: source.associatePublicIpAddress,
imageId: source.imageId,
keyName: source.keyName,
securityGroups: copyNonNullToSet(source.securityGroups),
@@ -120,6 +124,7 @@ import groovy.transform.Canonical
launchConfiguration.with {
new LaunchConfigurationBeanOptions(
launchConfigurationName: launchConfigurationName,
+ associatePublicIpAddress: associatePublicIpAddress,
imageId: imageId,
keyName: keyName,
securityGroups: copyNonNullToSet(securityGroups),
@@ -151,6 +156,7 @@ import groovy.transform.Canonical
}
new CreateLaunchConfigurationRequest(
launchConfigurationName: launchConfigurationName,
+ associatePublicIpAddress: associatePublicIpAddress,
imageId: imageId,
keyName: keyName,
securityGroups: copyNonNullToSet(securityGroups),
diff --git a/src/groovy/com/netflix/asgard/push/GroupCreateOperation.groovy b/src/groovy/com/netflix/asgard/push/GroupCreateOperation.groovy
index 748423ac..39ab77b0 100644
--- a/src/groovy/com/netflix/asgard/push/GroupCreateOperation.groovy
+++ b/src/groovy/com/netflix/asgard/push/GroupCreateOperation.groovy
@@ -81,7 +81,8 @@ class GroupCreateOperation extends AbstractPushOperation {
withKeyName(options.keyName).withRamdiskId(options.ramdiskId).
withSecurityGroups(options.common.securityGroups).
withIamInstanceProfile(options.iamInstanceProfile).
- withSpotPrice(options.spotPrice).withEbsOptimized(options.ebsOptimized)
+ withSpotPrice(options.spotPrice).withEbsOptimized(options.ebsOptimized).
+ withAssociatePublicIpAddress(options.associatePublicIpAddress)
final Collection suspendedProcesses = Sets.newHashSet()
if (options.zoneRebalancingSuspended) {
diff --git a/src/groovy/com/netflix/asgard/push/GroupCreateOptions.groovy b/src/groovy/com/netflix/asgard/push/GroupCreateOptions.groovy
index 1ba5fa21..7f8b647e 100644
--- a/src/groovy/com/netflix/asgard/push/GroupCreateOptions.groovy
+++ b/src/groovy/com/netflix/asgard/push/GroupCreateOptions.groovy
@@ -36,6 +36,7 @@ import groovy.transform.Immutable
Collection scalingPolicies
Collection scheduledActions
String spotPrice
+ boolean associatePublicIpAddress
boolean ebsOptimized
/** The number of instances to create at a time while inflating the auto scaling group. */
diff --git a/test/unit/com/netflix/asgard/AwsAutoScalingServiceIntegrationSpec.groovy b/test/unit/com/netflix/asgard/AwsAutoScalingServiceIntegrationSpec.groovy
index 6e8c52a9..e862fa7e 100644
--- a/test/unit/com/netflix/asgard/AwsAutoScalingServiceIntegrationSpec.groovy
+++ b/test/unit/com/netflix/asgard/AwsAutoScalingServiceIntegrationSpec.groovy
@@ -142,7 +142,7 @@ class AwsAutoScalingServiceIntegrationSpec extends Specification {
withMaxSize(0).withMinSize(0).withDefaultCooldown(0)
final LaunchConfiguration launchConfigTemplate = new LaunchConfiguration().withImageId('ami-deadbeef').
withInstanceType('m1.small').withKeyName('keyName').withSecurityGroups([]).withUserData('').
- withEbsOptimized(false)
+ withEbsOptimized(false).withAssociatePublicIpAddress(true)
when:
final CreateAutoScalingGroupResult result = awsAutoScalingService.createLaunchConfigAndAutoScalingGroup(
@@ -155,7 +155,7 @@ class AwsAutoScalingServiceIntegrationSpec extends Specification {
'helloworld-example' == result.autoScalingGroupName
result.launchConfigName =~ /helloworld-example-20[0-9]{12}/
!result.launchConfigDeleted
- result.launchConfigCreated
+ result.launchConfigCreated
result.autoScalingGroupCreated
result.toString() =~ "Launch Config 'helloworld-example-20[0-9]{12}' has been created. Auto Scaling Group" +
" 'helloworld-example' has been created. "
diff --git a/test/unit/com/netflix/asgard/model/LaunchConfigurationBeanOptionsSpec.groovy b/test/unit/com/netflix/asgard/model/LaunchConfigurationBeanOptionsSpec.groovy
index a5dbedb3..c1d84bc9 100644
--- a/test/unit/com/netflix/asgard/model/LaunchConfigurationBeanOptionsSpec.groovy
+++ b/test/unit/com/netflix/asgard/model/LaunchConfigurationBeanOptionsSpec.groovy
@@ -37,7 +37,8 @@ class LaunchConfigurationBeanOptionsSpec extends Specification {
instanceMonitoring: null,
instancePriceType: InstancePriceType.ON_DEMAND,
iamInstanceProfile: 'iamInstanceProfile1',
- ebsOptimized: false
+ ebsOptimized: false,
+ associatePublicIpAddress: true
)
LaunchConfiguration awsLaunchConfiguration = new LaunchConfiguration(
@@ -52,7 +53,8 @@ class LaunchConfigurationBeanOptionsSpec extends Specification {
blockDeviceMappings: [new BlockDeviceMapping(deviceName: 'deviceName1', ebs: new Ebs(volumeSize: 256))],
instanceMonitoring: null,
iamInstanceProfile: 'iamInstanceProfile1',
- ebsOptimized: false
+ ebsOptimized: false,
+ associatePublicIpAddress: true
)
CreateLaunchConfigurationRequest createLaunchConfigurationRequest = new CreateLaunchConfigurationRequest(
launchConfigurationName: 'launchConfigurationName1',
@@ -66,7 +68,8 @@ class LaunchConfigurationBeanOptionsSpec extends Specification {
blockDeviceMappings: [new BlockDeviceMapping(deviceName: 'deviceName1', ebs: new Ebs(volumeSize: 256))],
instanceMonitoring: null,
iamInstanceProfile: 'iamInstanceProfile1',
- ebsOptimized: false
+ ebsOptimized: false,
+ associatePublicIpAddress: true
)
def 'should deep copy'() {