Gruntwork Newsletter, September 2019
Once a month, we send out a newsletter to all Gruntwork customers that describes all the updates we’ve made in the last month, news in the…

Once a month, we send out a newsletter to all Gruntwork customers that describes all the updates we’ve made in the last month, news in the DevOps industry, and important security updates. Note that many of the links below go to private repos in the Gruntwork Infrastructure as Code Library and Reference Architecture that are only accessible to customers.
Hello Grunts,
In the last month, we released a collection of detailed, hands-on, step-by-step deployment guides that show you how to go to production on top of AWS and GCP, added support for fine-grained IAM Roles for Kubernetes Service Accounts support in EKS, added a new module to create and manage IAM users as code, updated all our modules to be compatible with Ubuntu 18.04, and made many other improvements and fixes. In other news, HashiCorp has released Terraform Cloud, a web UI for Terraform that’s free for teams of up to 5 users, AWS has released a number of improvements to EKS, and Python 2 will be sunset on January 1, 2020.
As always, if you have any questions or need help, email us at support@gruntwork.io!
Gruntwork Updates
Introducing the Gruntwork Production Deployment Guides
Motivation: We’ve often said that DevOps is a bit like death by a thousand cuts. There are just so many little details to get right, across so many different disciplines: network configuration, Docker orchestration, CI, CD, monitoring, alerting, log aggregation, TLS certificates, DNS settings, secrets management, SSH access, VPN connectivity, data backup, performance testing, high availability, scalability, compliance, and so much more. The most common feeling we hear from DevOps newcomers is: “I’m overwhelmed.”
Solution: I’m excited to announce the next step in our battle against feeling overwhelmed: the Gruntwork Production Deployment Guides. This is a collection of detailed, hands-on, step-by-step guides that show you how to go to production on top of AWS and GCP. There are guides that show you how to deploy a production-grade Kuberneter cluster, set up your AWS account structure (landing zone), configure your VPCs, and many more coming soon. These are not surface-level, 5-minute “Hello, World” tutorials, but in-depth guides that walk you through everything you need to do to build, deploy, and manage a piece of infrastructure in production.
What to do about it: Check out Introducing the Gruntwork Production Deployment Guides announcement blog post for an introduction and then dive into the Production Deployment Guides themselves!
Fine-grained IAM Roles for Kubernetes Service Accounts support in EKS
Motivation: This month, AWS announced support for fine-grained IAM Roles for Kubernetes Service Accounts. Up until now there was no sane way to assign IAM roles to individual Pods so that only those Pods had access to the IAM credentials in EKS. You either had to deploy a complex application that translates Pod annotations to IAM credentials by hijacking the metadata endpoint (such as kiam), or you had to manually generate and rotate credentials as Kubernetes Secrets injected into the container. With the new IAM Roles for Service Accounts (IRSA for short) feature, there is a EKS native way to set up and assign IAM Roles to individual Kubernetes Service Accounts.
Solution: We’ve updated our EKS module, terraform-aws-eks/eks-cluster-control-plane, to add support for setting up IRSA! Our module will automatically provision the necessary OpenID Connect Provider for IAM that EKS can use to exchange the Kubernetes Service Account credentials for IAM credentials as part of deploying the cluster.
We also created a new module, terraform-aws-eks/eks-iam-role-assume-role-policy-for-service-account, which simplifies the set up of IAM roles such that they can be assumed by the Kubernetes Service Account. For example, suppose you want to create a new IAM role application-iam-role
for your application, and only want it to be assumable by the Kubernetes Service Account application-sa
in the application
Namespace of your EKS cluster. You can do so with the following:
module "eks_cluster" { # args omitted for brevity }
module "assume_role_policy" { source = "git::git@github.com:gruntwork-io/terraform-aws-eks.git//modules/eks-iam-role-assume-role-policy-for-service-account?ref=v0.8.0" eks_openid_connect_provider_arn = module.eks_cluster.eks_iam_openid_connect_provider_arn eks_openid_connect_provider_url = module.eks_cluster.eks_iam_openid_connect_provider_url namespaces = [] service_accounts = [{ name = "application-sa" namespace = "application" }] } resource "aws_iam_role" "example" { name = "application-iam-role" assume_role_policy = module.assume_role_policy.assume_role_policy_json }
Note that IRSA is only supported on EKS clusters running Kubernetes version 1.13 and above. Be sure to upgrade your cluster to Kubernetes 1.13 before attempting to use IRSA!
Other EKS updates:
- terraform-aws-eks, v0.7.0:
eks-cluster-control-plane
module now supports upgrading Kubernetes components to the expected version for the Kubernetes version deployed on EKS. This is handled using a python script that is run everytime the kubernetes version is updated on the cluster. The deployed versions of each component follows what is described in the official upgrade guide. - terraform-aws-eks, v0.7.1: The cluster upgrade script that runs to update the Kubernetes plugins installed in the EKS cluster now only updates the components when the versions mismatch. In addition, the cluster upgrade script can now be turned off by setting the
use_upgrade_cluster_script
input variable tofalse
. - terraform-aws-eks, v0.8.0: Introduces support for IRSA.
- terraform-aws-eks, v0.8.1: Improves module stability. Specifically, IAM resources now have a 30 second wait to avoid propagation errors.
- terraform-aws-eks, v0.8.2: Fix a bug in the
upgrade_cluster
script used in theeks-cluster-control-plane
module where the script incorrectly redeployed the plugins when using a region other thanus-west-2
, even though the versions were already up to date.
What to do about it: Update to the latest terraform-aws-eks
release (v0.8.2) and give the new IRSA features a try!
New module to create and manage IAM Users
Motivation: Customers have been asking for a way to define and manage IAM users as code for a long time, but due to a Terraform limitation, we couldn’t build a generic module to do this. That’s because an IAM users module would need to take in a list of users and loop over them, and in Terraform, the only way to loop over resources used to be the count
meta parameter. Unfortunately, [count
had a significant limitation](https://blog.gruntwork.io/terraform-tips-tricks-loops-if-statements-and-gotchas-f739bbae55f9) where if you removed something from the middle of the list, it would end up deleting and recreating everything after it: e.g., if someone left your company and you deleted their IAM user from the middle of the list, Terraform would delete and recreate all the IAM users that came after that item in the list.
Solution: Terraform 0.12.6 added the ability to use for_each
on resources, which does not have this limitation, so we’ve created a new [iam-users module](https://github.com/gruntwork-io/module-security/tree/master/modules/iam-users)
! This module can create IAM users, add them to IAM groups, and generate a console password and access keys for the user, encrypting these secrets with the user’s PGP key (which can be fetched automatically from Keybase). Here’s an example usage:
module "iam_users" { source = "git::git@github.com:gruntwork-io/module-security.git//modules/iam-users?ref=v0.18.3" users = { alice = { groups = ["ops"] }
bob = { groups = ["developers"] pgp_key = "keybase:bob" create_login_profile = true create_access_keys = true }
cindy = { groups = ["admin"] pgp_key = "keybase:cindy" create_login_profile = true path = "/foo" tags { foo = "bar" } } } }
output "user_arns" { value = module.iam_users.user_arns }
output "user_access_keys_encrypted" { value = module.iam_users.user_access_keys }
output "user_passwords_encrypted" { value = module.iam_users.user_passwords }
When you deploy the code above, it’ll create three IAM users, alice
, bob
, and cindy
, and output each user’s ARN, access key (encrypted with that user’s PGP key), and password (encrypted with that user’s PGP key).
What to do about it: Give the iam-users
module a try in module-security, v0.18.3, and let us know what you think!
All the modules have been updated to be compatible with Ubuntu 18.04!
Motivation: Ubuntu 18.04, the latest LTS version was originally released in April of 2018. Since then, there has been 3 additional releases to the 18.04 line and it should now be considered stable. Up until now all the modules in the Gruntwork Infrastructure as Code Library have defaulted to version 16.04, which has been out for a while. While it is still supported (end of standard support for 16.04 is April 2021), there has been increasing demand for using Ubuntu 18.04 with our modules.
Solution: We’ve updated all our modules to test against Ubuntu 18.04! For most modules, there is no change necessary to use with Ubuntu 18.04 and you can safely bump to Ubuntu 18.04. The following modules have additional steps that are necessary:
- package-elk, v0.5.0: Refer to the release notes for instructions on updating to Ubuntu 18.04.
- terraform-aws-consul, v0.7.2:
systemd-resolved
no longer works when usingdnsmasq
, which is not available on Ubuntu 18.04. We have released a new module that you can use as a replacement. Refer to the release notes for more info.
What to do about it: Upgrade each module that you want to use with Ubuntu 18.04 to the latest release. Be sure to take a look at the release notes for information on what to do when crossing backwards incompatible releases! In general, any release that bumps the minor version (X
in 0.X.Y
) has backwards incompatible changes. Refer to the release notes for the .0
(0.X.0
) version for information on what to do to migrate to that version.
Open source updates
- helm-kubernetes-services, v0.0.4: You can now specify
imagePullSecrets
on thek8s-service
chart to specify whichSecret
to use when pulling down container images. This is useful when authenticating the container engine to a private registry. You can now directly append to theIngress
paths, using theadditionalPaths
andadditionalPathsHigherPriority
input values. See the README for more information. - helm-kubernetes-services, v0.0.5: You can now specify
google.managedCertificate
to deploy a Google Managed SSL Certificate. - helm-kubernetes-services, v0.0.6: You can now specify the container command to run when deploying the app, using the
containerCommand
input value. Also, the google managed certificate name is now configurable, using thegoogle.managedCertificate.name
input value. - helm-kubernetes-services, v0.0.7: Fixed
Ingress
tls
configuration issue that prevented chart from deploying. Security Context is now configurable, using thesecurityContext
input map. - helm-kubernetes-services, v0.0.8: The
k8s-service
chart now supports injecting the projected Service Account token and environment variables into the Pod for the IAM Roles for Service Account feature in AWS EKS. - terraform-google-gke, v0.3.3: This release exposes a variable
alternative_default_service_account
which can be used to specify a Service Account that should be used by the default node pool during cluster creation, that is alternative to the default Service Account. This should be used if the default Service Account is deleted from the Project. - terraform-google-gke, v0.3.4: This release exposes a variable
service_account_roles
on thegke-service-account
module, which can be used to add extra roles to the service account. - terraform-google-gke, v0.3.7: This release adds ability to configure G Suite security-group when creating a cluster.
- terratest, v0.18.5: Added
http-helper
methods to add HTTP header(s), set a HTTP method and return a response body. Also fixed broken builds (disabled Azure tests). - terratest, v0.18.6: Introduces
GetVpcById
andGetVpcByIdE
, which allows you to look up a VPC by ID, andGetVpcsE
, a general purpose helper function to look up VPCs using provided filters. - terratest, v0.19.0: This release updates the
HTTPDo
,HTTPDoE
,HTTPDoWithRetry
,HTTPDoWithRetryE
,HTTPDoWithValidationRetry
, andHTTPDoWithValidationRetryE
functions to use[]byte
for the request body instead ofio.Reader
. This change fixes a bug in the retry flavors of the functions that allow for reusing the body multiple times when making the HTTP request. - terratest, v0.19.1: When passing variables to Terraform, always wrap map keys in quotes. This allows passing in maps with keys that contain non alphanumeric characters, such as dots.
- cloud-nuke, v0.1.8: This release adds a new subcommand:
cloud-nuke defaults-aws
, which can be used to remove the default VPC and default security groups from existing VPCs. - terragrunt, v0.19.22:
hclfmt
now runs before anything is decoded in the terragrunt config. This avoids interpolating blocks that can’t be interpolated until the module is applied (e.gdependency
blocks). - terragrunt, v0.19.23: Implements better error handling of
dependency
blocks, specifically checking for cyclic dependencies and unapplied dependencies. Additionally, this release implementsmock_outputs
fordependency
blocks, which can be used to runvalidate
on a module before the dependencies are applied. See the updated README for more information. - terragrunt, v0.19.24: Fix bug where
dependency
blockconfig_path
that were relative were not resolved from the right directory when detecting cycles in the dependency graph, causing Terragrunt to incorrectly crash. - terragrunt, v0.19.25: Fixes bug where the dependency logic did not update the terragrunt cache dir. This causes problems if you were using local state, where the state file is stored in the terragrunt cache.
- terraform-google-network, v0.2.7: Introduced new network
tag
public-restricted
for restricting inbound traffic from public internet. - terraform-aws-vault, v0.13.3: Adds a
--s3-bucket-path
option for therun-vault
script. It is useful when you configure S3 as a storage backend and want to store vault data at a specific path in the S3 bucket. - kubergrunt, v0.5.3: This release introduces a new command
kubergrunt eks oidc-thumbprint
which can be used to compute the root CA thumbprint for a given OpenID Connect Issuer. This thumbprint is necessary when setting up an OpenID Connect Provider for use with the IAM Roles for Service Accounts feature provided by EKS. - kubergrunt, v0.5.4: The
eks deploy
command will now cordon all the old nodes before starting to drain them so that the evicted pods get scheduled on the new nodes in the cluster. - package-terraform-utilities, v0.1.3: The
run-pex-as-resource
andrun-pex-as-data-source
modules now exposes a variable (enabled
) that can be used to conditionally decide whether or not to execute the pex resource. This is helpful when you want to support disabling script execution in your modules.
Other updates
- module-data-storage, v0.9.2: Added the
cluster_resource_id
output to the Aurora module. - module-data-storage, v0.9.3: Add support for Aurora Global Clusters and include an example.
- module-security, v0.18.4: This release adds multiple improvements to the CloudTrail module. The CloudTrail S3 Bucket now has public access disabled. It’s now possible to enable S3 Bucket Access Logging, also to integrate with CloudWatch Logs.
- module-security, v0.18.5: This release adds a new module, aws-config, to enable the AWS Config service. AWS Config is a service that allows you to assess, audit, and evaluate the configurations of your AWS resources.
- module-security, v0.18.6: This release adds new IAM policies, groups, and introduces a new module
custom-iam-group
to create an IAM group and attach a set of policies, optionally with MFA required. - module-security, v0.19.0: This backwards-incompatible release fixes an issue with SNS topics in the aws-config module. Additionally, the aws-config IAM role permissions have been updated.
- module-security, v0.19.1: Add state machine permissions to
read_only
policy iniam-policies
module. - package-zookeeper, v0.6.4:
install-open-jdk
now supports installing OpenJDK 11 for CentOS and Ubuntu 18.04. See the compatibility information for more info. - module-ecs, v0.14.2: The
ecs-fargate
module has been updated to only enable ecs deployment check when desired tasks > 0. This allows you to setdesired_tasks
to 0 to scale down your service. Additionally, theecs-fargate
module has been updated to add task definition ARN as an output, under the nameaws_ecs_task_definition_arn
. - module-ecs, v0.14.3: Switch the
ecs-service-with-alb
module from usingtemplate_file
data sources tolocal
variables for intermediate variables. This fixes an issue whereterraform plan
was incorrectly reporting ECS services being recreated. - module-ecs, v0.14.4: Fix a bug in the
run-ecs-task
script where it was not forcing theaws
CLI output to be JSON, so the script would fail if a user had overridden the default on their systems to have text output. - module-load-balancer, v0.14.2: Update how the
alb
module calculates the ALB ARN to uselocals
instead of atemplate_file
. This fixes an issue whereterraform plan
was incorrectly reporting load balancers being recreated. - module-load-balancer, v0.15.0: The
nlb
module has been deprecated and removed. When #61 was fixed, thenlb
module reduced to being a thin wrapper over theaws_lb
resource and thus it no longer made sense to maintain the module. Instead, users of the module should update to using theaws_lb
resource directly. Refer to the provided migration guide for information on how to replace your usage of thenlb
module with theaws_lb
resource, including migrating the state to avoid downtime. - module-vpc, v0.7.4: The
vpc-mgmt
module now adds aName
tag to its NAT Gateway(s) and allows you to specify custom tags via the optionalnat_gateway_custom_tags
input variable. - module-data-storage, v0.10.0: The
rds
module now supports storage auto scaling by allowing you to set a new optional input variable calledmax_allocated_storage
. - package-static-assets, v0.5.4: The
s3-cloudfront
module now supports specifying multiple origin groups, which allows you to specify one or more S3 buckets to use as failovers in case the primary one fails. You can specify the failover buckets using the new input variablesfailover_buckets
andfailover_bucket_website_endpoints
. - package-openvpn, v0.9.6: Fix bug where the
install-openvpn
script was ignoring all command-line args passed to it! Add documentation on how to connect to multiple VPN servers at the same time.
DevOps News
Terraform Cloud
What happened: HashiCorp has announced the release of Terraform Cloud, a new web UI for Terraform.
Why it matters: Before Terraform Cloud, if you wanted to run Terraform from a web UI, your only options were Terraform Enterprise, which had a very high start price point that was only accessible to massive organizations, or Atlantis, which was an open source tool that was limited to executing a few commands via comments on GitHub PRs. Now you can give Terraform Cloud a shot, which is free for teams up to 5 users, and includes a number of features, such as remote plans & applies, VCS integration and webhooks, state management, and a provide module registry.
What to do about it: We’ll be trying out Terraform Cloud the next few months to see if it would be a good fit within our tech stack. In the meantime, check out the announcement blog post for the details, give Terraform Cloud a try, and let us know what you think!
Cost estimation in Terraform Cloud and Terraform Enterprise
What happened: HashiCorp has announced a new cost estimation feature for Terraform Cloud and Terraform Enterprise.
Why it matters: The Terraform Cloud and Terraform Enterprise UIs will now give you an estimate of the cost impact of your Terraform code changes: e.g., if you increase the number of servers in your cluster from X to Y, the monthly cost will go up by ~$Z. This allows you to see roughly how much a Terraform module will cost you before you deploy it, and even enforce rules and policies around pricing using HashiCorp Sentinel (which is only available in Terraform Enterprise).
What to do about it: Check out the announcement blog post for details.
Amazon EKS improvements
What happened: AWS has announced a number of improvements to EKS, including support for Kubernetes 1.14, fine-grained IAM roles for service accounts, cluster tagging, and support for the EBS CSI Driver.
Why it matters:
- Kubernetes 1.14: This version includes stable support for Durable Local Storage Management and Pod Priority, as well as the beta launch of Pid Limiting (see the release notes for all the details).
- Fine-grained IAM roles for service accounts: This gives you a sane, secure way to allow Kubernetes Pods to assume IAM roles, without any strange hacks, and without having to give any (shared) IAM permissions to the underlying worker nodes.
- Cluster tagging: You can now add custom tags to your EKS clusters. These tags can be used to control access to the EKS API for managing the cluster using IAM.
- EBS CSI Driver: Amazon has released a new driver that provides a CSI interface that allows Kubernetes to manage the lifecycle of Amazon EBS volumes for persistent volumes. The existing in-tree EBS plugin is still supported, but will be deprecated in the future.
What to do about it: Try out the new features above and let us know what you think!
Sunsetting Python 2
What happened: January 1, 2020, has been set as the official day that the Python maintainers will sunset Python 2.
Why it matters: After January 1, 2020, there will be no more improvements to Python 2—not even security fixes!
What to do about it: If you are still using Python 2, make sure to upgrade to Python 3 ASAP!
Improved VPC networking for Lambda functions
What happened: Amazon has announced that using Lambda functions with VPCs and ENIs will now be dramatically faster.
Why it matters: In the past, if you wanted to run your Lambda function within a VPC—e.g., so the function could access private resources within that VPC, such as a database—you would be faced with a massive cold-start overhead that could be as high as 20 seconds! With this update, there will be virtually no additional overhead for running Lambda functions in a VPC (other than a one-time setup per AWS account).
What to do about it: There’s nothing for you to do! This change will gradually roll out to all regions, allowing you to take advantage of much better Lambda function performance in VPCs.
Security Updates
Below is a list of critical security updates that may impact your services. We notify Gruntwork customers of these vulnerabilities as soon as we know of them via the Gruntwork Security Alerts mailing list. It is up to you to scan this list and decide which of these apply and what to do about them, but most of these are severe vulnerabilities, and we recommend patching them ASAP.
Python
- USN-4127–1 and USN-4127–2: A number of vulnerabilities were found in Python 2.7 and 3.4–3.7, including some that may be considered critical, depending on how you’re using Python. E.g., One vulnerability may allow an attacker to trick Python into sending cookies to the wrong domain and another allows CRLF injection attacks. If you’re using Python, we strongly recommend updating to the latest version.
Apache
- USN-4113–1: Several vulnerabilities were found in
apache2
, some of which could allow an attacker to expose sensitive information. If you’re using Apache, we strongly recommend updating to the latest version.