1
votes

I created autoscaling group which launch EC2 which has ELB. My question is how to provision those EC2 instances with ansible? Before I used CNAME, but now I cant get instance dns. Please correct me if I wrong.

Should I use dynamic inventory or are there any other options?

My cloud formation template below:

```

{
  "AWSTemplateFormatVersion" : "2010-09-09",
 "Description" : "Template create autoscaling group",
  "Parameters": {
   "devKeyPair": {
  "Description": "Name of an existing EC2 KeyPair to enable SSH access to the instances",
  "Type": "AWS::EC2::KeyPair::KeyName",
  "Default" : "dev-key"

}
},
"Resources" : {
"LaunchConfig" : {
"Type" : "AWS::AutoScaling::LaunchConfiguration",
"Properties" : {
  "KeyName" : { "Ref": "devKeyPair" },
  "ImageId" : "ami-1effc703",
   "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
  "#!/bin/bash\n", "\n", "    echo 'Installing Git'\n","    yum --nogpgcheck -y install wget\n""] ]}},
  "InstanceType" : "t2.small",
  "BlockDeviceMappings" : [
     {
       "DeviceName" : "/dev/sda1",
       "Ebs" : { 
          "VolumeSize" : "10", 
          "VolumeType" : "gp2", 
          "DeleteOnTermination" : "true"
          } 
     }
  ]
 }
 },
"BackendGroup" : {
  "Type" : "AWS::AutoScaling::AutoScalingGroup",
  "Properties" : {
    "AvailabilityZones" : ["eu-central-1a"],
  "MinSize" : "1",
  "MaxSize" : "1",
  "LaunchConfigurationName" : { "Ref" : "LaunchConfig" },
  "LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ],
  "Tags": [
    {
        "ResourceType": "auto-scaling-group",
        "ResourceId": "bas-auto",
        "Value": "bas-dev",
        "Key": "Name",
        "PropagateAtLaunch" : "true"
    }
]
  }
},

"ElasticLoadBalancer": {
  "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
  "Properties": {
  "AvailabilityZones": ["eu-central-1a"],
    "Listeners": [ {
      "LoadBalancerPort": "80",
      "InstancePort": "80",
      "Protocol": "HTTP"
    } ]
  }
},
"BackendDNS" : {
  "Type" : "AWS::Route53::RecordSetGroup",
  "Properties" : {
    "HostedZoneName" : "example.com.",
    "Comment" : "Targered to Bas instance",
    "RecordSets" : [{
      "Name" : "bas-dev.example.com.",
      "Type" : "CNAME",
      "TTL" : "300",
      "ResourceRecords" :  [
        {
            "Fn::GetAtt": [ "ElasticLoadBalancer", "DNSName" ]
        }
      ]
    }]
  }
},
}
}

```

3

3 Answers

0
votes

Another solution would be to provision your VM before starting the new instance. I.e. make sure that the image you're starting the ASG instances from is already provisioned. One way to do this is to use something like packer.io to create a new AMI using Ansible as your provisioner. Then you can simply pass this new AMI ID into the ImageId attribute of the LaunchConfiguration.

Another approach could involve using the User Data to "phone home" and tell you the public IP address the instance has acquired.

0
votes

The best solution for me was install Ansible Tower with a free license, the use user_data: properties ansible have an example here. https://www.ansible.com/blog/autoscaling-infrastructures

But is necessary build a first base image because if you NOT do this extend all provisioning time delay.

0
votes

You can use Opswork with Cloudformation in order to run Ansible whenever a new instance is added to the Autoscaling group.

Though Opswork uses Chef but you can use this custom cookbook https://github.com/deepakagg/ansible-opsworks which will run desired playbook.