Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Elastic Beanstalk Configuration Template #6601

Closed
tecnobrat opened this issue May 10, 2016 · 7 comments
Closed

Elastic Beanstalk Configuration Template #6601

tecnobrat opened this issue May 10, 2016 · 7 comments

Comments

@tecnobrat
Copy link

tecnobrat commented May 10, 2016

Perhaps I'm misunderstanding how the beanstalk environment templates are supposed to function.

I'm on Terraform 0.6.16

However, I have configuration like the following:

resource "aws_elastic_beanstalk_application" "app" {
    name = "beanstalk-app"
    description = ""
}

resource "aws_elastic_beanstalk_environment" "360_content_pass_admin" {
    name = "beanstalk-env"
    application = "${aws_elastic_beanstalk_application.app.name}"
    template_name = "${aws_elastic_beanstalk_configuration_template.template.name}"

    setting {
        namespace = "aws:elasticbeanstalk:application:environment"
        name = "NEW_RELIC_NO_CONFIG_FILE"
        value = "true"
    }
}


resource "aws_elastic_beanstalk_configuration_template" "template" {
    name = "beanstalk-config"
    application = "${aws_elastic_beanstalk_application.app.name}"
    solution_stack_name = "64bit Amazon Linux 2016.03 v2.1.0 running Multi-container Docker 1.9.1 (Generic)"

    setting {
        namespace = "aws:elasticbeanstalk:healthreporting:system"
        name = "SystemType"
        value = "enhanced"
    }

    setting {
        namespace = "aws:elasticbeanstalk:environment"
        name = "ServiceRole"
        value = "${var.service_role}"
    }
}

The first time this planned, it said it was removing the stuff I moved into the config template. But didn't say that the environment variable would be removed. But after applying, all of the aws:elasticbeanstalk:application:environment were gone. So I did another plan, it said it was going to add back the aws:elasticbeanstalk:application:environment sections, which appears to have happened.

If I make a change to the config template (tweak an autoscaling value for instance), it applies that change, but the environment doesn't ACTUALLY change. Am I misunderstanding how these are supposed to be used?

@tecnobrat
Copy link
Author

@dharrisio figured I would ping you as you seem to have a good amount of knowledge here.

@apparentlymart apparentlymart changed the title Beanstalk Configuration Template Elastic Beanstalk Configuration Template May 10, 2016
@dharrisio
Copy link
Contributor

I think there are two separate issues here.

The first sounds like a bug in how the settings are added and removed. I'm not too familiar with that piece of the code, but I should be able to look into it a bit more some time this week.

The second issue has quite a lengthy response, here's the short version and my current recommendation

From your example, I'm making the assumption that the name attribute of the updated template resource is not changing when the updates are made. If that's not accurate let me know. If the name of the template doesn't change, the elastic_beanstalk_environment resource doesn't see any changes, even if the contents of the template have changed.

My current recommendation would be to create Configuration Templates and Application Versions(GH-5770) per environment. Ideally using cd infrastructure to create new resources with new names like "mytemplate-${env}-${version}" or "myapplication-${env}-${version}", where ${version} would be changed everytime any changes are released. That way the names are unique, and you won't run into the current dependency issues.


Extended explanation

One possible way to deal with the environment not seeing changes would be to use randomly generated name or name_prefix attributes. Similar to how the launch configuration and autoscaling group resources work together. With this method any change to a elastic_beanstalk_configuration_template would force a new resource, which results in a new name. That way the elastic_beanstalk_environment resource always knows when there is a change, and to update the environment resource as well. This would be a pretty significant change and I'm not sure if it's the best option. It also demonstrates a separate issue with the Elastic Beanstalk resources.

In Terraform I think that it is best to keep environments separate from each other. For example, staging and production environments would have their own state files and in general wouldn't share resources between them. Elastic Beanstalk doesn't have that separation. There are several resources that can be shared between environments: The Elastic Beanstalk Application, Configuration Templates, and Application Versions. All of these resources could be used by multiple environments at the same time, which causes the dependencies to become more complicated.

Elastic Beanstalk Applications are fairly easy to deal with, I simply seeded the state files of new environments with the existing, shared resource. As an alternative to manually creating state files, it would probably be possible to use the terraform_remote_state resource to populate the Application name. Config Templates and Application Versions are a bit more difficult. Below are two scenarios that demonstrate the dependency issues that they can both have. Both of these scenarios assume that the name of the Config Template changes with any changes to the template resource.

Scenario 1

All of your environments are in the same Terraform document. With random template names, a new template would cause all of your environments to be updated at the same time, which probably wouldn't be the desired action. As I mentioned above, I generally wouldn't advise mixing environments because of reasons like this.

Scenario 2

Environments are in their own separate Terraform documents and state files. When Terraform creates a new resource, it deletes the old resource, either before or after the new resource is created(create_before_destroy). Take the following situation: you have two environments "stage" and "production", and two config templates "current-template" and "new-template". In the initial state, assume that "stage" and "production" were created with the "current" template. You make your changes to the template and call it "new-template", and update your "stage" environment to use "new-template". The issue is that the "production" environment is still dependent on the "current-template", which has now been deleted.

The issue with Application Versions is the same as scenario 2. This has been the piece blocking me on GH-5770. Ultimately this issue comes from dependencies that span multiple state files. Currently, Terraform doesn't have a way to handle this. So far, I haven't been too happy with the solutions that I have come up with to deal with this. I'll probably open up a separate issue exploring one of the more promising(maybe?) ideas instead of dragging this post on much further 😄 .

@tecnobrat
Copy link
Author

Thanks for your wonderful answer.

We actually have our stage and production in separate AWS account, and separate state files completely, so this separation is okay for us.

I understand about making the config template have a new name when you change it, this makes much more sense now. Not sure how we can handle this, I'll have to see if we can figure out a way, not sure why you mean by using cd infrastructure.

Having a version variable we need to set when we change the config template isn't ideal, but its not terrible.

@dharrisio
Copy link
Contributor

using cd infrastructure

Sorry, shouldn't have used an abbreviation there. Meant continuous delivery: Jenkins, Bamboo, etc. Depending on how you version manage Terraform documents(if they are included with app source control), you could just use something like the commit sha that you are deploying.

The more I think about it, adding a cname_prefix attribute to the template resource seems like a good idea. That way it takes the prefix + something random for the name. I believe that would solve the issue in your case.

@tecnobrat
Copy link
Author

tecnobrat commented May 12, 2016

@dharrisio yea if the template had name_prefix which automatically changed the name when the template was changed, this would allow the exact behavior I am looking for. We use atlas direct as our cd. So I don't think we have control over this. Also we would not want it to change with every commit to the repo. But rather just when the config template changed.

@tecnobrat
Copy link
Author

I've opened a new issue to address that apply bug I had #6636

@ghost
Copy link

ghost commented Apr 24, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 24, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants