debugterraformMinor
Cloud-Init Script Won't Run?
Viewed 0 times
scriptinitcloudwonrun
Problem
I am working through this Terraform tutorial, which boots up a Go web app on an EC2 instance, using Terraform and cloud-init. This is my Terraform config file:
```
terraform {
required_version = ">= 0.13"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = var.region
}
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-20-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_vpc" "vpc" {
cidr_block = var.cidr_vpc
enable_dns_support = true
enable_dns_hostnames = true
}
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.vpc.id
}
resource "aws_subnet" "subnet_public" {
vpc_id = aws_vpc.vpc.id
cidr_block = var.cidr_subnet
}
resource "aws_route_table" "rtb_public" {
vpc_id = aws_vpc.vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
}
resource "aws_route_table_association" "rta_subnet_public" {
subnet_id = aws_subnet.subnet_public.id
route_table_id = aws_route_table.rtb_public.id
}
resource "aws_security_group" "sg_22_80" {
name = "sg_22"
vpc_id = aws_vpc.vpc.id
# SSH access from the VPC
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
data "template_file" "user_data" {
template = file("../scripts/add-ssh-web-app.yaml")
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
```
terraform {
required_version = ">= 0.13"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = var.region
}
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-20-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_vpc" "vpc" {
cidr_block = var.cidr_vpc
enable_dns_support = true
enable_dns_hostnames = true
}
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.vpc.id
}
resource "aws_subnet" "subnet_public" {
vpc_id = aws_vpc.vpc.id
cidr_block = var.cidr_subnet
}
resource "aws_route_table" "rtb_public" {
vpc_id = aws_vpc.vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
}
resource "aws_route_table_association" "rta_subnet_public" {
subnet_id = aws_subnet.subnet_public.id
route_table_id = aws_route_table.rtb_public.id
}
resource "aws_security_group" "sg_22_80" {
name = "sg_22"
vpc_id = aws_vpc.vpc.id
# SSH access from the VPC
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
data "template_file" "user_data" {
template = file("../scripts/add-ssh-web-app.yaml")
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
Solution
There are a few issues with this cloud-init script.
So you either need to remove the
Fixing all of these issues, we should get a resulting cloud-init script that looks something like this:
#groupsis commented out, so the list beneath it makes it invalid YAML.
- Even if we uncomment groups,
- ubuntu: [root,sys]is invalid because the default user already has a group specification. If you look near the bottom of/etc/cloud/cloud.cfgon a launched instance, you should see something like:
system_info:
# This will affect which distro class gets used
distro: ubuntu
# Default user name + that default users groups (if added/used)
default_user:
name: ubuntu
lock_passwd: True
gecos: Ubuntu
groups: [adm, audio, cdrom, dialout, dip, floppy, lxd, netdev, plugdev, sudo, video]
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
shell: /bin/bash
So you either need to remove the
ubuntu line from your groups definition, or remove - default from your user definition and define the ubuntu user manually.- Your ssh key is also pasted as invalid YAML. Keep it as a single line
- In your runcmd,
sudo sudoesn't work that way in a script. Instead you shouldsudo -ufor an individual user to run an individual command. Additionally,sudoisn't needed for root permissions as all user scripts run as root already.
Fixing all of these issues, we should get a resulting cloud-init script that looks something like this:
#cloud-config
# Add the empty group hashicorp.
groups:
- hashicorp
# Add users to the system. Users are added after groups are added.
users:
- default
- name: terraform
gecos: terraform
shell: /bin/bash
primary_group: hashicorp
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users, admin
lock_passwd: false
ssh_authorized_keys:
- ssh rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCMT6uYfhWx8jOmiGR9ryIPKcWy2ceqvyZ4Q4+q5QTiZtlbWxbP37YZnT8uQhyjB4QRR1cjOyvGKC3Zu0Isy0eHIx2lGm/7B04bsoWWAUqhJmYWMZlivnHtJJJ4P5gnvXiRNmFg9iK07C7ClggNBAQZZHUeA5wcnvvHT/pDkGUjMUqgLvmWRJqJM9qLT717e229F1Fyh+sYtAj08qmcFF1JCs2D33R46RQ8YBMpQqmWLfjuJDUrjdvMu7Mv3aPpaeUWuYoC90iHR9XMeNonrtRlx21nY3CoMZ0AOpeNl999UzyMJrsvN4qm6byK2Pc6jrEyKr9jI8SvMEGdSWgqr/Hd
# Downloads the golang package
packages:
- golang-go
# Sets the GOPATH & downloads the demo payload
runcmd:
- mkdir /home/terraform/go
- chown terraform:hashicorp /home/terraform/go
- sudo GOPATH=/home/terraform/go -u terraform go install github.com/hashicorp/learn-go-webapp-demo@latest
Context
StackExchange DevOps Q#15837, answer score: 3
Revisions (0)
No revisions yet.