ansible-elastic-beanstalk icon indicating copy to clipboard operation
ansible-elastic-beanstalk copied to clipboard

every run of elasticbeanstalk_env redeploys the environment, even when no changes

Open nergdron opened this issue 8 years ago • 17 comments

It'd be great if there was a way for it to diff new settings vs what's currently there in an environment, and not redeploy if there haven't been any changes. This is typically how ansible modules behave, and would save my particular workflow a lot of runtime.

nergdron avatar Jan 18 '17 00:01 nergdron

This module supports check mode. If you run your playbook with --check the module will return what options if any will be changed.

On Jan 17, 2017 7:25 PM, "Tessa Nordgren" [email protected] wrote:

It'd be great if there was a way for it to diff new settings vs what's currently there in an environment, and not redeploy if there haven't been any changes. This is typically how ansible modules behave, and would save my particular workflow a lot of runtime.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/hsingh/ansible-elastic-beanstalk/issues/24, or mute the thread https://github.com/notifications/unsubscribe-auth/AAYLHhrpEBr0YqsFI8ISMmwTh-rSynBRks5rTVwMgaJpZM4LmVW0 .

hsingh avatar Jan 18 '17 00:01 hsingh

Right. But if I'm in a playbook that loops through and creates/updates say, 10 EB environments... I don't want it to redeploy ones that haven't changed, as it adds an extra ~10m to the run for each one. --check on the whole playbook won't help me there, AFAIK.

nergdron avatar Jan 18 '17 00:01 nergdron

I think I had noticed this as well, I wasn't sure if this was the same with the boto version. Normally with Ansible modules if all settings are the same (and app version in this case as well), ansible shouldn't perform any changes.

sidewinder12s avatar Jan 18 '17 01:01 sidewinder12s

I think boto does the same thing, tbh. This is definitely a feature request, but I'd love to see the ansible module act smarter than boto does, and save me some time during deploys. :)

nergdron avatar Jan 18 '17 01:01 nergdron

If there are no changes the environment is not redeployed.

On Jan 17, 2017 7:57 PM, "Tessa Nordgren" [email protected] wrote:

Right. But if I'm in a playbook that loops through and creates/updates say, 10 EB environments... I don't want it to redeploy ones that haven't changed, as it adds an extra ~10m to the run for each one. --check on the whole playbook won't help me there, AFAIK.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/hsingh/ansible-elastic-beanstalk/issues/24#issuecomment-273350103, or mute the thread https://github.com/notifications/unsubscribe-auth/AAYLHiiDLJJYCHpj3Gy40XmdJt3kDU5Yks5rTWNagaJpZM4LmVW0 .

hsingh avatar Jan 18 '17 01:01 hsingh

Please provide an example to reproduce this scenario.

hsingh avatar Jan 18 '17 13:01 hsingh

I created a playbook that just called create twice with the same option settings & application version, with a 30 second wait between them & Ansible outputted the changed: true twice instead of changing the first run and then unchanged the second. The EB console showed an environment configuration update & an application version update

sidewinder12s avatar Jan 20 '17 21:01 sidewinder12s

If you look at the code update_environment is only called if we detect a change.

updates = update_required(ebs, env, module.params)
            if len(updates) > 0:
                ebs.update_environment(**filter_empty(...

So in your test case what updates were reported when by the second run?

hsingh avatar Jan 24 '17 14:01 hsingh

Interesting, looks like it was some of the option settings I was using that was causing it to update configuration settings ever time, this time specifically the aws:autoscaling:scheduledaction namespace.

TASK [Create environment] ******************************************************
changed: [localhost] => {"changed": true, "env": {"AbortableOperationInProgress": false, "ApplicationName": "elasticbeanstalk_env-testing", "CNAME": "elasticbeanstalk-env-testing.us-west-2.elasticbeanstalk.com", "DateCreated": "2017-01-20T20:02:03.131000+00:00", "DateUpdated": "2017-01-24T20:15:25.559000+00:00", "EndpointURL": "internal-awseb-e-7-AWSEBLoa-1H7KXPZ49YTRI-864563399.us-west-2.elb.amazonaws.com", "EnvironmentId": "e-7kgfsghi3w", "EnvironmentLinks": [], "EnvironmentName": "elasticbeanstalk-env-testing", "Health": "Green", "SolutionStackName": "64bit Amazon Linux 2016.09 v2.3.1 running Tomcat 8 Java 8", "Status": "Ready", "Tier": {"Name": "WebServer", "Type": "Standard", "Version": "1.0"}, "VersionLabel": "Testing"}, "updates": [["aws:autoscaling:scheduledaction:MinSize", "0", "1"], ["aws:autoscaling:scheduledaction:MaxSize", "0", "2"], ["aws:autoscaling:scheduledaction:Recurrence", "0 3 * * 1-5", "0 17 * * 1-5"]]}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "deploy_status": {
        "changed": true,
        "env": {
            "AbortableOperationInProgress": false,
            "ApplicationName": "elasticbeanstalk_env-testing",
            "CNAME": "elasticbeanstalk-env-testing.us-west-2.elasticbeanstalk.com",
            "DateCreated": "2017-01-20T20:02:03.131000+00:00",
            "DateUpdated": "2017-01-24T20:15:25.559000+00:00",
            "EndpointURL": "internal-awseb-e-7-AWSEBLoa-1H7KXPZ49YTRI-864563399.us-west-2.elb.amazonaws.com",
            "EnvironmentId": "e-7kgfsghi3w",
            "EnvironmentLinks": [],
            "EnvironmentName": "elasticbeanstalk-env-testing",
            "Health": "Green",
            "SolutionStackName": "64bit Amazon Linux 2016.09 v2.3.1 running Tomcat 8 Java 8",
            "Status": "Ready",
            "Tier": {
                "Name": "WebServer",
                "Type": "Standard",
                "Version": "1.0"
            },
            "VersionLabel": "Testing"
        },
        "updates": [
            [
                "aws:autoscaling:scheduledaction:MinSize",
                "0",
                "1"
            ],
            [
                "aws:autoscaling:scheduledaction:MaxSize",
                "0",
                "2"
            ],
            [
                "aws:autoscaling:scheduledaction:Recurrence",
                "0 3 * * 1-5",
                "0 17 * * 1-5"
            ]
        ]
    }
}

TASK [Wait to ensure the API doesn't return stale objects] *********************
Pausing for 30 seconds
(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)
ok: [localhost] => {"changed": false, "delta": 30, "rc": 0, "start": "2017-01-24 20:15:25.657782", "stderr": "", "stdout": "Paused for 30.0 seconds", "stop": "2017-01-24 20:15:55.657926", "user_input": ""}

TASK [Create environment (idempotent)] *****************************************
changed: [localhost] => {"changed": true, "env": {"AbortableOperationInProgress": false, "ApplicationName": "elasticbeanstalk_env-testing", "CNAME": "elasticbeanstalk-env-testing.us-west-2.elasticbeanstalk.com", "DateCreated": "2017-01-20T20:02:03.131000+00:00", "DateUpdated": "2017-01-24T20:17:14.099000+00:00", "EndpointURL": "internal-awseb-e-7-AWSEBLoa-1H7KXPZ49YTRI-864563399.us-west-2.elb.amazonaws.com", "EnvironmentId": "e-7kgfsghi3w", "EnvironmentLinks": [], "EnvironmentName": "elasticbeanstalk-env-testing", "Health": "Green", "SolutionStackName": "64bit Amazon Linux 2016.09 v2.3.1 running Tomcat 8 Java 8", "Status": "Ready", "Tier": {"Name": "WebServer", "Type": "Standard", "Version": "1.0"}, "VersionLabel": "Testing"}, "updates": [["aws:autoscaling:scheduledaction:MinSize", "0", "1"], ["aws:autoscaling:scheduledaction:MaxSize", "0", "2"], ["aws:autoscaling:scheduledaction:Recurrence", "0 3 * * 1-5", "0 17 * * 1-5"]]}

This env hadn't changed between runs but was being updated both times. Any idea if that is on the module end that is causing it to set it every time or on the API end?

sidewinder12s avatar Jan 24 '17 20:01 sidewinder12s

Hmm, not sure. According to the module the 3 options (MinSize, MaxSize, Recurrence) changed from what is currently deployed. I haven't used these options before so can't say. There is some specific code in the module to deal with options that take comma separate listed of values like subnet and security groups where we deal with transposed values. This doesn't seem to be the case here so either your initial values were not accepted by AWS, changed between the two invocations or the second invocation used a different input.

hsingh avatar Jan 24 '17 20:01 hsingh

They used the same input as I am just setting a fact at the beginning of the run with all the option_settings, I was left wondering if the module isn't properly looking at the returned input

sidewinder12s avatar Jan 25 '17 01:01 sidewinder12s

@nergdron Do you know what the module is saying gets updated when your expecting it to have done nothing?

sidewinder12s avatar Jan 25 '17 02:01 sidewinder12s

Yeah, I can repro that some time this week. Just been out with the flu, so I'm busy trying to catch up. :)

nergdron avatar Jan 25 '17 02:01 nergdron

Sorry it took so long to test this, but here's the updates field of the result when it re-applies the config:

    "updates": [
        [
            "aws:elb:policies:ConnectionDrainingEnabled", 
            "true", 
            "True"
        ], 
        [
            "aws:elb:loadbalancer:CrossZone", 
            "true", 
            "True"
        ], 
        [
            "aws:autoscaling:updatepolicy:rollingupdate:autoscaling:trigger:RollingUpdateEnabled", 
            "<NEW>", 
            "True"
        ], 
        [
            "aws:autoscaling:updatepolicy:rollingupdate:autoscaling:trigger:RollingUpdateType", 
            "<NEW>", 
            "Health"
        ]
    ]

So, the first two seem to be problems with treating booleans as strings and case differences, and the last two don't seem to be correctly reading the current values from the running EB stack, since they were correctly applied the first time 'round.

nergdron avatar Feb 08 '17 20:02 nergdron

How can I deploy new version. When I change the version_label I am getting following error An exception occurred during task execution. The full traceback is: Traceback (most recent call last): File "/var/folders/ws/z_4zkk0s2vdfxvv7x6dmv_9r0000gp/T/ansible_vH17hS/ansible_module_elasticbeanstalk_env.py", line 410, in main() File "/var/folders/ws/z_4zkk0s2vdfxvv7x6dmv_9r0000gp/T/ansible_vH17hS/ansible_module_elasticbeanstalk_env.py", line 346, in main check_env(ebs, app_name, env_name, module) File "/var/folders/ws/z_4zkk0s2vdfxvv7x6dmv_9r0000gp/T/ansible_vH17hS/ansible_module_elasticbeanstalk_env.py", line 262, in check_env updates = update_required(ebs, env, module.params) File "/var/folders/ws/z_4zkk0s2vdfxvv7x6dmv_9r0000gp/T/ansible_vH17hS/ansible_module_elasticbeanstalk_env.py", line 232, in update_required change = new_or_changed_option(options, setting) File "/var/folders/ws/z_4zkk0s2vdfxvv7x6dmv_9r0000gp/T/ansible_vH17hS/ansible_module_elasticbeanstalk_env.py", line 246, in new_or_changed_option option["Value"] == setting["Value"]: KeyError: 'Value'

fatal: [localhost]: FAILED! => { "changed": false, "failed": true, "invocation": { "module_name": "elasticbeanstalk_env" }, "module_stderr": "Traceback (most recent call last):\n File "/var/folders/ws/z_4zkk0s2vdfxvv7x6dmv_9r0000gp/T/ansible_vH17hS/ansible_module_elasticbeanstalk_env.py", line 410, in \n main()\n File "/var/folders/ws/z_4zkk0s2vdfxvv7x6dmv_9r0000gp/T/ansible_vH17hS/ansible_module_elasticbeanstalk_env.py", line 346, in main\n check_env(ebs, app_name, env_name, module)\n File "/var/folders/ws/z_4zkk0s2vdfxvv7x6dmv_9r0000gp/T/ansible_vH17hS/ansible_module_elasticbeanstalk_env.py", line 262, in check_env\n updates = update_required(ebs, env, module.params)\n File "/var/folders/ws/z_4zkk0s2vdfxvv7x6dmv_9r0000gp/T/ansible_vH17hS/ansible_module_elasticbeanstalk_env.py", line 232, in update_required\n change = new_or_changed_option(options, setting)\n File "/var/folders/ws/z_4zkk0s2vdfxvv7x6dmv_9r0000gp/T/ansible_vH17hS/ansible_module_elasticbeanstalk_env.py", line 246, in new_or_changed_option\n option["Value"] == setting["Value"]:\nKeyError: 'Value'\n", "module_stdout": "", "msg": "MODULE FAILURE" }

devarpi-zz avatar Feb 09 '17 17:02 devarpi-zz

@devarpi What does your playbook look like? It looks like it's complaining about the Option Settings your using/formatting of those option settings.

sidewinder12s avatar Feb 10 '17 01:02 sidewinder12s

Sorry for the late reply. My apologies no excuse.

Here is my option settings.

  • Namespace: aws:ec2:vpc OptionName: XXXXX Value: vpc-714f3717 - Namespace: aws:ec2:vpc OptionName: Subnets Value: XXX-XXXX,XXX-XXXX,XXXX-XXX - Namespace: aws:ec2:vpc OptionName: ELBSubnets Value: subnet-XXX,XXX-XXXX,XXXX-XXXX - Namespace: aws:ec2:vpc OptionName: AssociatePublicIpAddress Value: "false" - Namespace: aws:ec2:vpc OptionName: ELBScheme Value: "internal"

        #Deployment typeconfiguration
        - Namespace: aws:elasticbeanstalk:command
          OptionName: DeploymentPolicy
          Value: Rolling
    
        #Healthcheck related configuration
        - Namespace: aws:elasticbeanstalk:healthreporting:system
          OptionName: SystemType
          Value: "enhanced"
    
        #Loadbalancer configuration
        - Namespace: aws:elb:loadbalancer
          OptionName: CrossZone
          Value: "true"
        - Namespace: aws:elb:loadbalancer
          OptionName: LoadBalancerHTTPPort
          Value: "80"
        - Namespace: aws:elb:loadbalancer
          OptionName: LoadBalancerPortProtocol
          Value: "HTTP"
        - Namespace: aws:elb:loadbalancer
          OptionName: LoadBalancerHTTPSPort
          Value: "443"
        - Namespace: aws:elb:loadbalancer
          OptionName: LoadBalancerSSLPortProtocol
          Value: "HTTPS"
        - Namespace: aws:elb:loadbalancer
          OptionName: SSLCertificateId
          Value:
    

"arn:aws:acm:us-east-1:139179150794:certificate/2d1e3bca-d86f-4db9-afc9-63430e36de50"

      - Namespace: aws:elb:listener:80
        OptionName: ListenerProtocol
        Value: HTTP
      - Namespace: aws:elb:listener:80
        OptionName: InstanceProtocol
        Value: HTTP
      - Namespace: aws:elb:listener:80
        OptionName: InstancePort
        Value: "80"
      - Namespace: aws:elb:listener:443
        OptionName: ListenerProtocol
        Value: HTTPS
      - Namespace: aws:elb:listener:443
        OptionName: InstanceProtocol
        Value: HTTPS
      - Namespace: aws:elb:listener:443
        OptionName: InstancePort
        Value: "443"
      - Namespace: aws:elb:listener:443
        OptionName: ListenerEnabled
        Value: "true"
      - Namespace: aws:elb:listener:443
        OptionName: SSLCertificateId
        Value: "arn:aws:acm:us-east-1XXXXX:certificate/XXXXXXX"


      #ELB policy related confiruration
      - Namespace: aws:elb:policies
        OptionName: ConnectionDrainingEnabled
        Value: "true"
      - Namespace: aws:elb:policies
        OptionName: ConnectionDrainingTimeout
        Value: "30"
      - Namespace: aws:elb:policies
        OptionName: LoadBalancerPorts
        Value: 80,443
      - Namespace: aws:elb:policies
        OptionName: Stickiness Cookie Expiration
        Value: "1800"
      - Namespace: aws:elb:policies
        OptionName: Stickiness Policy
        Value: "true"

      #Lauchconfiguration related settings
      - Namespace: aws:autoscaling:launchconfiguration
        OptionName: EC2KeyName
        Value: XXX-XXXX-dev-key
      - Namespace: aws:autoscaling:launchconfiguration
        OptionName: IamInstanceProfile
        Value: bsemailcloud-dev-instance-profile
      - Namespace: aws:autoscaling:launchconfiguration
        OptionName: InstanceType
        Value: t2.small
      - Namespace: aws:autoscaling:launchconfiguration
        OptionName: SSHSourceRestriction
        Value: tcp, 22, 22,xxxx/x

      - Namespace: aws:elasticbeanstalk:environment
        OptionName: ServiceRole
        Value: aws-elasticbeanstalk-service-role



      #Autoscaling instance min max settings
      - Namespace: aws:autoscaling:asg
        OptionName: MinSize
        Value: "1"
      - Namespace: aws:autoscaling:asg
        OptionName: MaxSize
        Value: "4"
      - Namespace: aws:autoscaling:asg
        OptionName: Cooldown
        Value: "600"

      #Autoscaling trigger settings
      - Namespace: aws:autoscaling:trigger
        OptionName: MeasureName
        Value: CPUUtilization
      - Namespace: aws:autoscaling:trigger
        OptionName: Statistic
        Value: Average
      - Namespace: aws:autoscaling:trigger
        OptionName: Unit
        Value: Percent
      - Namespace: aws:autoscaling:trigger
        OptionName: UpperThreshold
        Value: "40"
      - Namespace: aws:autoscaling:trigger
        OptionName:  LowerThreshold
        Value: "20"

On Thu, Feb 9, 2017 at 8:04 PM, Geoff Webster [email protected] wrote:

@devarpi https://github.com/devarpi What does your playbook look like? It looks like it's complaining about the Option Settings your using/formatting of those option settings.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/hsingh/ansible-elastic-beanstalk/issues/24#issuecomment-278827443, or mute the thread https://github.com/notifications/unsubscribe-auth/AA9TwdCsuWQ1bW-1ZtnPkYnQK_00jpSgks5ra7e6gaJpZM4LmVW0 .

-- Thanks, Devarpi 703 508 0119

devarpi-zz avatar Mar 28 '17 18:03 devarpi-zz