#terraform (2018-07)
Discussions related to Terraform or Terraform Modules
Archive: https://archive.sweetops.com/terraform/
2018-07-02
@ag4ve.us has joined the channel
@zerocoolback has joined the channel
2018-07-05
@jonathan.olson has joined the channel
2018-07-10
@achrstl has joined the channel
2018-07-20
@jamie here’s the TF channel
@jamie has joined the channel
Oh hi! I can keep my terraform troubleshooting to here without disturbing your geodesic users :)
We can try - just sensitive to splintering off eyeballs until we have more critical mass
but it is nice to keep the threads separated
yea, perhaps it’s time. just like we started using #random <— nice
@Andriy Knysh (Cloud Posse) has joined the channel
@tamsky has joined the channel
@Cristin has joined the channel
@Cristin which module are you having trouble with?
(i’m about to jump on a call - so may be delayed in following up)
@Andriy Knysh (Cloud Posse) can also help
I’m using elastic-beanstalk-environment
and I’m getting some error related to aws_iam
@Cristin uploaded a file: Untitled
I took a look over the parameters and the code of the module, but I don’t see a way of passing a aws_iam_role_policy_attachment
or profile
@Cristin i’ll look into the error (little bit later), but for now you can look at this repo where we use elastic-beanstalk-environment
: https://github.com/cloudposse/terraform-aws-jenkins/blob/master/main.tf
terraform-aws-jenkins - Terraform module to build Docker image with Jenkins, save it to an ECR repo, and deploy to Elastic Beanstalk running Docker stack
terraform-aws-jenkins - Terraform module to build Docker image with Jenkins, save it to an ECR repo, and deploy to Elastic Beanstalk running Docker stack
I took a look over the example and how you are attaching a policy to the ec2 instances. I tried doing the same thing but I still get the above errors
@Cristin can you share your code? If not public, you can message me or send email to [email protected], I’ll take a look
2018-07-22
@Cristin uploaded a file: Untitled
@Andriy Knysh (Cloud Posse) Here it is
Thank you!
2018-07-23
@maarten has joined the channel
@Andriy Knysh (Cloud Posse) I managed to make it work by using the configuration you used in the Jenkins example
Thank you for you help!
@Cristin sorry I did not help you yet, just wanted to look at your code in more details (from what I saw briefly, you mixed a lot of concepts)
glad the jenkins
examples hepled
@Andriy Knysh (Cloud Posse) I still have one question. How is the best way of connecting the elasticbeanstalk envirment to a RDS database? Just create the database and inject in env vars the database connection details?
we have https://github.com/cloudposse/terraform-aws-rds to create an RDS database (no Aurora)
terraform-aws-rds - Terraform module to provision AWS RDS instances
also https://github.com/cloudposse/terraform-aws-rds-cluster to create an Aurora cluster
terraform-aws-rds-cluster - Terraform module to provision an RDS Aurora cluster for MySQL or Postgres
usage example is here https://github.com/cloudposse/terraform-root-modules/blob/master/aws/backing-services/aurora-postgres.tf
terraform-root-modules - Collection of Terraform root module invocations for provisioning reference architectures
yes, the best way is to put the RDS credentials (username, password, etc.) in ENV vars, and then in Elastic Beanstalk environment add those ENV vars to the environment. Then read them in your app
like we do here https://github.com/cloudposse/terraform-aws-jenkins/blob/master/examples/new_vpc_new_subnets/main.tf#L41
terraform-aws-jenkins - Terraform module to build Docker image with Jenkins, save it to an ECR repo, and deploy to Elastic Beanstalk running Docker stack
(you can add any number of ENVs)
we try to follow 12-factor
https://12factor.net/
A methodology for building modern, scalable, maintainable software-as-a-service apps.
III. Config
Store config in the environment
so first create an RDS cluster https://github.com/cloudposse/terraform-aws-rds-cluster
it will output the credentials
add the ENVs here https://github.com/cloudposse/terraform-aws-elastic-beanstalk-environment/blob/master/variables.tf#L248
terraform-aws-elastic-beanstalk-environment - Terraform module to provision an AWS Elastic Beanstalk Environment
at Cloud Posse, we use chamber
to securily work with ENV vars and secrets
chamber - CLI for managing secrets
Awesome information, thanks a lot!
geodesic
supports chamber
natively https://github.com/cloudposse/geodesic
Geodesic is the fastest way to get up and running with a rock solid, production grade cloud platform built on strictly Open Source tools. https://docs.cloudposse.com/geodesic/
when you provision an RDS cluster from geodesic
, you add the ENVs to chamber
terraform-root-modules - Collection of Terraform root module invocations for provisioning reference architectures
then you provision terraform-aws-elastic-beanstalk-environment
from geodesic
, you read the ENVs from chamber
@krogebry has joined the channel
@Andriy Knysh (Cloud Posse) Thank you for all the help! For now I setup a simple RDS postgress db an injected the env variables in a ebs env
I still have a question, related to setting up multiple envs like “develop” and “production”
I noticed that I can create one ebs
application and create multiple environments for it
But in this situation I don’t understand what’s the role of the stage
attribute for the elastic_beanstalk_application
module
stage
is to separate the resources b/w diff stages
- see the latest discussing in #announcements
also, by using diff stage
, e.g. dev
and prod
, you can deploy the same environment two times for development and production
you need to deploy it two times obviously
Yes, I know this. But if I have 1 application and 2 environments for it, what’s the role of having stage
setup on the application itself?
We generally do not prescribe using a single beanstalk for multiple stages even though it is supported
stage
is used in all resource names by using the label
module. So (almost) all resources will be names like namespace-stage-name
so, if you use the same AWS account and the same EB application to deploy two environments into it, then stage
could be anything you like - but as @Erik Osterman (Cloud Posse) mentioned, we don’t usually do it
we try to completely separate stages
Ok, I understand. So is a best practive to have 1 app = 1 env
even using diff AWS accounts for more security and control
Yes - that way they share nothing so making changes to one can never impact the other
and much easier to control IAM
Also, have you seen our modules for ECS
?
Sorry, which one? I looked over a lot of your modules, they are really helpful
Since you are starting from scratch, I would consider using ECS rather than Beanstalk.
terraform-aws-ecs-web-app - Terraform module that implements a web app on ECS and supporting AWS resources.
Well, the Beanstalk is actually a requirment on the project I’m doing, so I will try ecs on the next one
Ok, so if I will create seperate resources (security group, vpc, db, app, env) for each stage what would be the best way to run this twice and not having to duplicate the code? Should I create a module around your modules ?
@Cristin we still recommend to separate all resources into at lest two stages (dev
and prod
) and don’t mix anything b/w/ them
take a look how it’s separated here https://github.com/cloudposse/staging.cloudposse.co
staging.cloudposse.co - Example Terraform Reference Architecture for Geodesic Module Staging Organization in AWS.
staging.cloudposse.co - Example Terraform Reference Architecture for Geodesic Module Staging Organization in AWS.
we use ENV vars for stage
too
prod.cloudposse.co - Example Terraform/Kubernetes Reference Infrastructure for Cloud Posse Production Organization in AWS
Ok, I will look into this. Thanks a lot again for your time and availability to help
no problem
the container + env vars
pattern is our approach to DevOps orchestration and env separation (there could be other ways of doing it)
geodesic
is that container, with much more tools inside
2018-07-24
@Yoann has joined the channel
we just released https://github.com/cloudposse/terraform-aws-elasticsearch
Contribute to terraform-aws-elasticsearch development by creating an account on GitHub.
@Erik Osterman (Cloud Posse) are we going to release that null-label branch we made together that adds context as a variable?
what Support passing a label's context between label modules why DRY demo module "label1" { source = "../../" namespace = "Namespace" stage = &…
yea, i was just holding off since it was “complicated”
but we can merge
@jamie do you want to add environment
?
(in a follow up PR)
I did yeah :)
Is his change by @dennybaa
in that commit not needed?
He pushed his change through…. its in now
whoot!
so, one more test and then approve?
(i can’t approve, since I opened the PR)
I have just pushed the changes
I have updated the readme to include the new features too
tested and working?
yeah, using the example
./examples/complete
cool
ok, you can approve, merge, and tag a new minor release
terraform apply [ruby-2.5.1p57]
data.null_data_source.tags_as_list_of_maps[5]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[1]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[0]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[4]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[3]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[2]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[0]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[4]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[1]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[2]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[3]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[0]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[2]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[1]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[3]: Refreshing state...
data.null_data_source.tags_as_list_of_maps[4]: Refreshing state...
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
label1 = {
attributes = fire-water-earth-air
id = cloudposse-uat-build-winstonchurchroom-fire-water-earth-air
name = winstonchurchroom
namespace = cloudposse
stage = build
}
label1_context = {
attributes = [fire-water-earth-air]
delimiter = [-]
environment = [uat]
name = [winstonchurchroom]
namespace = [cloudposse]
stage = [build]
tags_keys = [City Environment Name Namespace Stage]
tags_values = [Dublin Private cloudposse-uat-build-winstonchurchroom-fire-water-earth-air cloudposse build]
}
label1_tags = {
City = Dublin
Environment = Private
Name = cloudposse-uat-build-winstonchurchroom-fire-water-earth-air
Namespace = cloudposse
Stage = build
}
label2 = {
attributes = fire-water-earth-air
id = cloudposse-uat-build-charlie-fire-water-earth-air
name = charlie
namespace = cloudposse
stage = build
}
label2_context = {
attributes = [fire-water-earth-air]
delimiter = [-]
environment = [uat]
name = [charlie]
namespace = [cloudposse]
stage = [build]
tags_keys = [City Environment Name Namespace Stage]
tags_values = [London Public cloudposse-uat-build-charlie-fire-water-earth-air cloudposse build]
}
label2_tags = {
City = London
Environment = Public
Name = cloudposse-uat-build-charlie-fire-water-earth-air
Namespace = cloudposse
Stage = build
}
label3 = {
attributes =
id = release-starfish
name = starfish
namespace =
stage = release
}
label3_context = {
attributes = []
delimiter = [-]
environment = []
name = [starfish]
namespace = []
stage = [release]
tags_keys = [Animal Eat Environment Name Namespace Stage]
tags_values = [Rabbit Carrot release-starfish release]
}
label3_tags = {
Animal = Rabbit
Eat = Carrot
Environment =
Name = release-starfish
Namespace =
Stage = release
}
Minor?
What constitues a major?
haha, i know…
just i don’t want to go to 1.0.0
yet
thats like… only got the same variables as the original
so, we say pre 1.0
okay
so we are at 0.3.8
now, this should be 0.4.0
i am not yet sure what constitutes a 1.0.0
release - we don’t yet have any
probably a topic for another day… but some considerations are “stable interface”
so if we plan on adding a bunch more parameters, feels like the interface is not yet stable
You need a new “Definition of done”
even terraform is pre 1.0
https://github.com/cloudposse/terraform-null-label/releases/tag/0.4.0 @Erik Osterman (Cloud Posse)
terraform-null-label - Terraform Module to define a consistent naming convention by (namespace, stage, name, [attributes])
@jamie I missed something maybe in that release… or at least let’s discuss
local.namespace, local.environment, local.stage
Seems to me that stage is more broad than environments
So it should come before environment
No?
@tamsky have any insights
I strongly agree with the rationale in the release notes; some organizations have existing mental models and terminology.
Hrmm I guess I can see pros and cons both ways
What would be a real-life example of using both at the same time?
@sarkis has joined the channel
the challenge here is what we do with our 100 terraform modules that don’t yet support environment
@tamsky any insights on ordering? namespace-stage-environment
or namespace-environment-stage
2018-07-25
In your terraform modules you can just leave it out
It can be either. But other companies may use both when stage is being referred to as the disposable type of stage. Like source, build, deploy. Or extract, transform, load. Or raw, resized, thumbnail.
https://github.com/firmstep-public/trainingdayfour in progress…
trainingdayfour - Training Day Four: Review how to use Terraform Variables, and look at how to lay out a Terraform Directory Structure.
@jamie @tamsky I understand the thinking about having stage
and environment
at the same time. But IMO it just complicates everything. You are saying that stage
could refer to source, build, deploy, extract, transform, load. raw, resized, thumbnail. Those seem to be stages in an CI/CD pipeline or some other process of transforming data or building/deploying some artifacts. As I see it, they don’t relate to infrastructure environments that we deploy with Terraform. Are you saying that we need to deploy some TF resources with names like cp-prod-deploy-myapp
, cp-prod-load-myapp
? Sounds like parts of a pipeline, not a separate set of AWS resources
I’m saying that by having both, people who use the module can keep the it close to their own naming system, without breaking the cloudposse naming system.
what would be a real example of using names like these in a real infrastructure having separate stages/environments
like dev
, prod
?
Outside of Cloudposse: If one was making a codepipeline pipeline for example, and you had two parts to it, all using the dockerised codebuild system, one of the codebuild stages might be called stage:build attributes: [“java”], another might be stage:build attributes: [“golang”], another might be stage:deploy attributes: [“s3-assets”]
Hmm I see your point. But are those Terraform resources? The label module is used to name TF resources
And we already have attributes in the module to add more parts to the names
I realise, but when I introduce the label to my company and my clients, they have said they have a naming convention that includes environment. By having Environment optional, it also allows us to name items using the word environment in the same way we have been doing on the cloudposse modules.
i agree, we can use the module in many ways now
just did not want to over-complicate things that could be simple
One nice thing though, is in the future of the cloudposse modules, the modules all the modules can contain a “context” map variables too.
@Arkadiy has joined the channel
thanks @jamie
looks like all of that stage
vs. environment
stuff is used mostly for tagging, not for naming
which are diff things
ya
2018-07-27
@loren has joined the channel
@Ruslan has joined the channel
Hi Everyone! First of all - big thanks for Terraform scripts on Github! It was invaluable source of knowledge and easy to use as is too.
Come to talk about terraform-null-label and name sequence
any insights on ordering? namespace-stage-environment
or namespace-environment-stage
In my opinion this should be configurable, because on the projects I am on right now we have namespace-app-stage
.
I`ve created issue on GitHub for that: https://github.com/cloudposse/terraform-null-label/issues/35
Currently, this repo supports only namespace-stage-name sequence. In some organizations, there is a different standard for example namespace-name-stage. Please consider and explore whether it is po…
@Ruslan I have been considering this as well
To me, it’s most natural to move the environment after the stage
But allowing order to be overridden would be also a nice feature
@jamie
No problem
I’ll give it a pattern variable
Personally I believe namespace-stage-app
is proper way (because stage/env is the isolated space in which all the apps are working). But on the current project it is done as namespace-app-stage
.
hey folks! does anyone know of tooling that helps create a terraform state file, based on a given terraform configuration, by importing existing resources?
we have a number of accounts with resources we can’t recreate, but we’re just getting started with terraform (switching from cloudformation). we’ve written terraform modules to manage everything, and it works great for new accounts, and now we’re looking into how we can extend it to prior accounts…
terraform state list
gives all the resource names, which seems to work with terraform import
. however, it also outputs all the data source names (with no differentiation between resources and data sources), which don’t need to be imported
ahh thanks, i looked at that earlier, but it didn’t seem like quite what i needed… i’ll give it a try and see how it goes
i don’t want to import all resources of a particular type, and i don’t want the resources in the root module, which is what the examples look to be doing
but perhaps it has more options
seems not, unfortunately. any other tools?
We had to do this a year ago for another customer, but we went the tedious route of defining all the resources by hand and importing the state. It took a lot of effort to get a clean plan.
that’s what i’m going through now… i have the output of state list
, so i’m using that as a known good starting point to define an configuration map of resource: id
and a simple wrapper to import all resources with a defined id
then the tedious process of populating the config file for each account
Yea, it sucks. Fortunately I had some help from offshore contractors. I can make an intro if you’d like.
PM me
other option i suppose would be to take the state file from a known good account and template that
offshore contractor not an option for this customer, unfortunately. we pretty much are the hired help. thanks for the offer though
You can use it to import everything, and then just manually edit the state file to only include the ones you want.
Its about all we have at the moment
@Ruslan @Erik Osterman (Cloud Posse) I’ve created a pull request that adds that feature you were after https://github.com/cloudposse/terraform-null-label/pull/36
A new variable that allows for providing a label_order as a list to specify which variables and in what order they go into the id output and Name tag. The list can include all or none of the a vari…
I will take a look as soon as I get into the office
Yes, it works, Ive tried it. <https://github.com/cloudposse/terraform-null-label/pull/36#issuecomment-408472191> However I am using label through
terraform-aws-cicd and
terraform-aws-codebuild` projects and need support in them for label_order.
Should I add issue (or even better, PR) to these projects as well?
Yes we will accept PRs
Issue not needed
Regarding label module, I have an idea I want to test before I comment
But currently afk
For the label module, it looks now it would be better to just add a few parameters, p1, p2, p3, p4, p5, etc. and use them as we want. Instead of assigning a meaning to all of them and then decide on the order?
No
100% want meaning
I was just reflecting on this point
The thing is we need to standardize nomenclature
This is what I love about @jamie document for this
Even if I disagree with ‘environment’
However I have an idea based on what you say @Andriy Knysh (Cloud Posse)
Will whip up prototype to express how this should be working
I think it will satisfy everyone but might belong in a new module
Ok
@Ruslan once the guys have reviewed the pull request and its good to add, we can start updating the other modules to be compatible with context.
which will allow you to pass in a label modules context and use that for formatting.
2018-07-30
@johntellsall has joined the channel
@fernando thanks for adding the test case to https://github.com/cloudposse/terraform-aws-ecs-container-definition/pull/9
What Adjust the regexp used to overcome Terraform's type conversions for integer and boolean parameters in the JSON container definition. The new regexp preservers the string type for environme…
Travis build timed out for some reason, no explanations given
What Adjust the regexp used to overcome Terraform's type conversions for integer and boolean parameters in the JSON container definition. The new regexp preservers the string type for environme…
Could be intermittent failure on their end
Just getting up :) will take a look in a couple of hours.
I’m just about to step out the door for the evening, so will take a look tomorrow.
Sure thing, let me know what you think, and enjoy the rest of the evening!
2018-07-31
Okay! I took a look. Looks good, almost exactly what we needed. Let’s add test case for quoted numbers and booleans as well.
@i5okie thanks for joining! Saw your comment on the issue here: https://github.com/cloudposse/terraform-aws-elastic-beanstalk-environment/issues/42
terraform-aws-elastic-beanstalk-environment - Terraform module to provision an AWS Elastic Beanstalk Environment
Let me know if I can be of assistance.
yeah we had an older release of the module. i just copied the lifestyle block there
Is it working now with the latest release?
i didn’t update to latest release (long story short, cant lol) but i copied the fix across. and its working now. thanks
ok, great!
what Do not allow MFA device deletion without MFA present why I think this allows an attacker to create a new MFA device without MFA authentication references <https://github.com/cloudposse/terr…
Would like feedback on this. Am I missing something here?
@pmuller has joined the channel
one thing i’d like to do here is to restrict aws account usage by source ip address
if your users all work in the same office
you could restrict mfa management to your office ip address
yea, that could be an enhancement
that way an attacker should steal api keys or password + be physically close to your office and hack your wifi to abuse your aws account
one thing I’ve loved about Duo is the ability to do geofencing
did not try this yet but i’d like to do this here
Duo ?
yea, they are a MFA saas
(and now also do SSO)
Duo’s Trusted Access platform verifies the identity of your users with two-factor authentication and security health of their devices before they connect to the apps you want them to access.
We have support for this in our bastion container: https://github.com/cloudposse/bastion
bastion - Secure Bastion implemented as Docker Container running Alpine Linux with Google Authenticator & DUO MFA support
so basically Duo will store your users secret mfa keys?
yep
and offer multiple forms of 2FA
you can choose which ones you allow
interesting ! (i dropped the google authenticator idea precisely because i was afraid of storing those mfa secrets)
you can also require, for example, that their MFA device is up to date
that their OS is current
etc..
so policy management at a higher level
yea, GA is a nice contribution by google, but seriously difficult to truly secure.
Also, are you familiar with Teleport for SSH?
their current os ? is it using TNC ?
their = ?
This “their”
how Duo is checking for OS version ?
since one factor is mobile push notifications
they can get a lot of metadata
including gps location
OS version
authenticator version
device os
etc
very interesting
about teleport, i would like to use it and log everything with it, but haven’t taken time to try it yet
my current compromise is logging a lot with auditd and pam_audit_tty
Yea, we used to do something similar.
sudosh - Shell wrapper to run a login shell with sudo
as the current user for the purpose of audit logging
does pam_audit_tty work without ttys?
nope
that’s from Duo ?
yea
nice!
maybe i am a bit too paranoid for the cloud era … i grew up in datacenters, and started using aws in 2016 … but i still have too much of the data center / oss guy thinking: DIY ! so at first i even had a hard time trusting AWS (then I realized how absurd it was..) let alone talking about a 3rd party for authentication
but yeah, i sometimes feel like i am wasting my time
[override.tf](http://override.tf)
appears to have no impact/influence over terraform { ... }
block
too bad
cannot terragrunt be helpful with your sed hack? (haven’t tried it yet)
i am not well versed in terragrunt
i know terragrunt can do what our module does out of the box
but i like that we’re defining the infrastructure for bucket/dynamodb with terraform rather than another tool
i like ideas terragrunt brings on the table, but i know from experience it’s better to use vanilla tools in the long term … wrappers comes and go … and creates debt!
yes - agree
i would consider using it for specific cases such as this
small in scope
i’d be happy to hear about your feedback
btw, do you test your tf modules ? if so, how ? (doing so with all the code i write… except tf, so it’s frustrating)
we’re not quite there yet. right now, we do lint testing only.
same here
not even that … we just run “terraform fmt” and check if there is a change in the repo
i feel poor with just this
See our plan of attack here: https://sweetops.slack.com/archives/CB84E9V54/p1532332704000172
Can we automate geodesic terraform to build and destroy a cluster in a CI env ?
in the #geodesic channel
basically, we package all infrastructure in a container along with terraform
thus, it’s an app like everything else
our strategy is to use our testing account to run: plan
, apply
, plan
, destroy
, plan
I am less enthused by atlantis and terratest
haven’t heard about atlantis
terratest requires to write tests in go, which is rather unpleasant
wants a nice test runner/framework like pytest ;)
lunch time, bbl
cool, ttyl!
ior have a good night
(yea, I’m in Los Angeles)
tflint - TFLint is a Terraform linter for detecting errors that can not be detected by terraform plan
Contribute to terraform-provider-generic development by creating an account on GitHub.
this is an interesting concept. it reminds me of the “porcelain” plugin module used in helm
, but applied to terraform providers
using this, it’s possible to define a “basic” provider in any language, and then accept targets like apply
, destroy
, etc
the implementation above seems like a POC, but if anyone else has seen one, lmk
note, this is very different from the data external provider which does not distinguish between phases
oh nice!
Related to the earlier question of terraform cicd, this looks interesting
tfnotify - A CLI command to parse Terraform execution result and notify it to GitHub
This will take the output of terraform plan/apply and post it back to GitHub or Slack.
@Andriy Knysh (Cloud Posse) wrote a generic tool for this, not specialized for terraform called ‘github-commenter’