feat: experiment with localstack
This commit is contained in:
@@ -0,0 +1,52 @@
|
|||||||
|
# resource "aws_instance" "Test" {
|
||||||
|
# ami = data.aws_ami.this.id
|
||||||
|
# instance_type = "t4g.large"
|
||||||
|
#
|
||||||
|
# tags = {
|
||||||
|
# Name : "TestInstance001"
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
module "TestInstance" {
|
||||||
|
source = "../../../modules/compute/ec2"
|
||||||
|
|
||||||
|
additional-tags = {}
|
||||||
|
ami-id = data.aws_ami.this.id
|
||||||
|
asso-eip = false
|
||||||
|
asso-public-ip = false
|
||||||
|
data-volumes = {}
|
||||||
|
instance-name = "TestInstance001"
|
||||||
|
instance-type = "t4g.large"
|
||||||
|
kms-key-id = module.KmsKeys.cmks["allpurpose"].arn
|
||||||
|
root-volume-size = 20
|
||||||
|
security-groups = []
|
||||||
|
subnet-id = data.terraform_remote_state.vpc.outputs.private_subnets[0]
|
||||||
|
user-data = <<EOF
|
||||||
|
#!/bin/bash
|
||||||
|
dnf -y install git
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
data "aws_ami" "this" {
|
||||||
|
most_recent = true
|
||||||
|
name_regex = "^al2023-ami-2023.*-kernel-6.1-arm64"
|
||||||
|
owners = ["amazon"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "random_pet" "this" {
|
||||||
|
length = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
module "KmsKeys" {
|
||||||
|
source = "../../../modules/security_identity_compliance/CustomerManagedKmsKeys"
|
||||||
|
|
||||||
|
create-allpurpose-key = true
|
||||||
|
create-backup-key = false
|
||||||
|
create-database-key = false
|
||||||
|
create-eksebs-key = false
|
||||||
|
create-log-key = false
|
||||||
|
create-notify-key = false
|
||||||
|
create-secret-key = false
|
||||||
|
create-storage-key = false
|
||||||
|
deletion_window_in_days = 7
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
output "instance_info" {
|
||||||
|
value = module.TestInstance.ec2-id-ip
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
provider "aws" {
|
||||||
|
region = var.aws-region
|
||||||
|
|
||||||
|
# localstack config
|
||||||
|
access_key = "test"
|
||||||
|
secret_key = "test"
|
||||||
|
skip_credentials_validation = true
|
||||||
|
skip_metadata_api_check = true
|
||||||
|
skip_requesting_account_id = true
|
||||||
|
|
||||||
|
# localstack endpoints https://docs.localstack.cloud/aws/integrations/infrastructure-as-code/terraform/#:~:text=tflocal%20is%20a%20small%20wrapper,unmodified%20Terraform%20scripts%20against%20LocalStack.
|
||||||
|
endpoints {
|
||||||
|
apigateway = "http://192.168.86.96:4566"
|
||||||
|
apigatewayv2 = "http://192.168.86.96:4566"
|
||||||
|
cloudformation = "http://192.168.86.96:4566"
|
||||||
|
cloudwatch = "http://192.168.86.96:4566"
|
||||||
|
dynamodb = "http://192.168.86.96:4566"
|
||||||
|
ec2 = "http://192.168.86.96:4566"
|
||||||
|
es = "http://192.168.86.96:4566"
|
||||||
|
elasticache = "http://192.168.86.96:4566"
|
||||||
|
firehose = "http://192.168.86.96:4566"
|
||||||
|
iam = "http://192.168.86.96:4566"
|
||||||
|
kinesis = "http://192.168.86.96:4566"
|
||||||
|
kms = "http://192.168.86.96:4566"
|
||||||
|
lambda = "http://192.168.86.96:4566"
|
||||||
|
rds = "http://192.168.86.96:4566"
|
||||||
|
redshift = "http://192.168.86.96:4566"
|
||||||
|
route53 = "http://192.168.86.96:4566"
|
||||||
|
s3 = "http://192.168.86.96:4566"
|
||||||
|
secretsmanager = "http://192.168.86.96:4566"
|
||||||
|
ses = "http://192.168.86.96:4566"
|
||||||
|
sns = "http://192.168.86.96:4566"
|
||||||
|
sqs = "http://192.168.86.96:4566"
|
||||||
|
ssm = "http://192.168.86.96:4566"
|
||||||
|
stepfunctions = "http://192.168.86.96:4566"
|
||||||
|
sts = "http://192.168.86.96:4566"
|
||||||
|
}
|
||||||
|
|
||||||
|
default_tags {
|
||||||
|
tags = {
|
||||||
|
Environment = var.environment
|
||||||
|
Project = var.project
|
||||||
|
Application = var.application
|
||||||
|
LocalStack = true
|
||||||
|
TerraformDir = join("/", reverse(slice(reverse(split("/", path.cwd)), 0, 2)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 1.11.0"
|
||||||
|
required_providers {
|
||||||
|
aws = {
|
||||||
|
source = "hashicorp/aws"
|
||||||
|
version = "~> 6.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# data aws_caller_identity current {}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
data "terraform_remote_state" "vpc" {
|
||||||
|
backend = "local"
|
||||||
|
config = {
|
||||||
|
path = "${path.module}/../../Network/LabVpc/terraform.tfstate"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
application = "localstack"
|
||||||
|
environment = "locallab"
|
||||||
|
project = "iac"
|
||||||
|
aws-region = "us-east-1"
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
variable "aws-region" {}
|
||||||
|
variable "environment" {}
|
||||||
|
variable "project" {}
|
||||||
|
variable "application" {}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
data "aws_region" "this" {}
|
||||||
|
|
||||||
|
# Eks Vpc on IPv6
|
||||||
|
resource "random_pet" "pet" {
|
||||||
|
length = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
vpc_cidr = "10.18.0.0/16"
|
||||||
|
# ensure there is room for future expansion
|
||||||
|
private_net_start = cidrsubnet(local.vpc_cidr, 2, 1)
|
||||||
|
public_net_start = cidrsubnet(local.vpc_cidr, 2, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
data "aws_availability_zones" "this" {
|
||||||
|
state = "available"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "random_shuffle" "Select2Az" {
|
||||||
|
input = data.aws_availability_zones.this.names
|
||||||
|
result_count = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
module "vpc" {
|
||||||
|
source = "terraform-aws-modules/vpc/aws"
|
||||||
|
version = "6.6.0"
|
||||||
|
|
||||||
|
name = "lab-vpc"
|
||||||
|
cidr = local.vpc_cidr
|
||||||
|
|
||||||
|
azs = random_shuffle.Select2Az.result
|
||||||
|
# ipv6 doesn't work with localstack
|
||||||
|
enable_ipv6 = false
|
||||||
|
public_subnet_assign_ipv6_address_on_creation = true
|
||||||
|
private_subnet_assign_ipv6_address_on_creation = true
|
||||||
|
private_subnets = cidrsubnets(local.private_net_start, 4, 4) # EKS requires free IPv4 addresses. see README
|
||||||
|
public_subnets = cidrsubnets(local.public_net_start, 8, 8) # 2 AZ required by eks lbc
|
||||||
|
public_subnet_tags = {
|
||||||
|
"kubernetes.io/role/elb" = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_dns_hostnames = true
|
||||||
|
enable_dns_support = true
|
||||||
|
|
||||||
|
# nat gateway and eigw (vpc module creates the dns64 /64 route to NGW)
|
||||||
|
enable_nat_gateway = true # AWS public endpoints do not support IPv6
|
||||||
|
single_nat_gateway = true
|
||||||
|
create_egress_only_igw = true
|
||||||
|
|
||||||
|
enable_flow_log = false
|
||||||
|
create_flow_log_cloudwatch_log_group = false
|
||||||
|
create_flow_log_cloudwatch_iam_role = false
|
||||||
|
manage_default_network_acl = false
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
output "private_subnets" {
|
||||||
|
value = module.vpc.private_subnets
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
provider "aws" {
|
||||||
|
region = var.aws-region
|
||||||
|
|
||||||
|
# localstack config
|
||||||
|
access_key = "test"
|
||||||
|
secret_key = "test"
|
||||||
|
skip_credentials_validation = true
|
||||||
|
skip_metadata_api_check = true
|
||||||
|
skip_requesting_account_id = true
|
||||||
|
|
||||||
|
# localstack endpoints https://docs.localstack.cloud/aws/integrations/infrastructure-as-code/terraform/#:~:text=tflocal%20is%20a%20small%20wrapper,unmodified%20Terraform%20scripts%20against%20LocalStack.
|
||||||
|
endpoints {
|
||||||
|
apigateway = "http://192.168.86.96:4566"
|
||||||
|
apigatewayv2 = "http://192.168.86.96:4566"
|
||||||
|
cloudformation = "http://192.168.86.96:4566"
|
||||||
|
cloudwatch = "http://192.168.86.96:4566"
|
||||||
|
dynamodb = "http://192.168.86.96:4566"
|
||||||
|
ec2 = "http://192.168.86.96:4566"
|
||||||
|
es = "http://192.168.86.96:4566"
|
||||||
|
elasticache = "http://192.168.86.96:4566"
|
||||||
|
firehose = "http://192.168.86.96:4566"
|
||||||
|
iam = "http://192.168.86.96:4566"
|
||||||
|
kinesis = "http://192.168.86.96:4566"
|
||||||
|
lambda = "http://192.168.86.96:4566"
|
||||||
|
rds = "http://192.168.86.96:4566"
|
||||||
|
redshift = "http://192.168.86.96:4566"
|
||||||
|
route53 = "http://192.168.86.96:4566"
|
||||||
|
s3 = "http://192.168.86.96:4566"
|
||||||
|
secretsmanager = "http://192.168.86.96:4566"
|
||||||
|
ses = "http://192.168.86.96:4566"
|
||||||
|
sns = "http://192.168.86.96:4566"
|
||||||
|
sqs = "http://192.168.86.96:4566"
|
||||||
|
ssm = "http://192.168.86.96:4566"
|
||||||
|
stepfunctions = "http://192.168.86.96:4566"
|
||||||
|
sts = "http://192.168.86.96:4566"
|
||||||
|
}
|
||||||
|
|
||||||
|
default_tags {
|
||||||
|
tags = {
|
||||||
|
Environment = var.environment
|
||||||
|
Project = var.project
|
||||||
|
Application = var.application
|
||||||
|
LocalStack = true
|
||||||
|
TerraformDir = join("/", reverse(slice(reverse(split("/", path.cwd)), 0, 2)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 1.11.0"
|
||||||
|
required_providers {
|
||||||
|
aws = {
|
||||||
|
source = "hashicorp/aws"
|
||||||
|
version = "~> 6.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# data aws_caller_identity current {}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
application = "localstack"
|
||||||
|
environment = "locallab"
|
||||||
|
project = "iac"
|
||||||
|
aws-region = "us-east-1"
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
variable "aws-region" {}
|
||||||
|
variable "environment" {}
|
||||||
|
variable "project" {}
|
||||||
|
variable "application" {}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# LocalStack
|
||||||
|
## Setup
|
||||||
|
Sign up for localstack and obtain the auth token. Then fire up a container:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -e LOCALSTACK_AUTH_TOKEN=ls-xxx-yyy-zzz-aaa-bbb -it \
|
||||||
|
--name localstack --network macvlan localstack/localstack-pro localstack
|
||||||
|
```
|
||||||
|
|
||||||
|
In terraform, configure aws endpoints to go to localstack and add localstack required configurations:
|
||||||
|
```hcl
|
||||||
|
provider "aws" {
|
||||||
|
region = var.aws-region
|
||||||
|
|
||||||
|
# localstack config
|
||||||
|
access_key = "test"
|
||||||
|
secret_key = "test"
|
||||||
|
skip_credentials_validation = true
|
||||||
|
skip_metadata_api_check = true
|
||||||
|
skip_requesting_account_id = true
|
||||||
|
|
||||||
|
# localstack endpoints https://docs.localstack.cloud/aws/integrations/infrastructure-as-code/terraform/#:~:text=tflocal%20is%20a%20small%20wrapper,unmodified%20Terraform%20scripts%20against%20LocalStack.
|
||||||
|
endpoints {
|
||||||
|
apigateway = "http://192.168.86.96:4566"
|
||||||
|
apigatewayv2 = "http://192.168.86.96:4566"
|
||||||
|
cloudformation = "http://192.168.86.96:4566"
|
||||||
|
cloudwatch = "http://192.168.86.96:4566"
|
||||||
|
dynamodb = "http://192.168.86.96:4566"
|
||||||
|
ec2 = "http://192.168.86.96:4566"
|
||||||
|
es = "http://192.168.86.96:4566"
|
||||||
|
elasticache = "http://192.168.86.96:4566"
|
||||||
|
firehose = "http://192.168.86.96:4566"
|
||||||
|
iam = "http://192.168.86.96:4566"
|
||||||
|
kinesis = "http://192.168.86.96:4566"
|
||||||
|
lambda = "http://192.168.86.96:4566"
|
||||||
|
rds = "http://192.168.86.96:4566"
|
||||||
|
redshift = "http://192.168.86.96:4566"
|
||||||
|
route53 = "http://192.168.86.96:4566"
|
||||||
|
s3 = "http://192.168.86.96:4566"
|
||||||
|
secretsmanager = "http://192.168.86.96:4566"
|
||||||
|
ses = "http://192.168.86.96:4566"
|
||||||
|
sns = "http://192.168.86.96:4566"
|
||||||
|
sqs = "http://192.168.86.96:4566"
|
||||||
|
ssm = "http://192.168.86.96:4566"
|
||||||
|
stepfunctions = "http://192.168.86.96:4566"
|
||||||
|
sts = "http://192.168.86.96:4566"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
At time of writing, localstack seems very limited. Many basic layers would not run.
|
||||||
|
For example, vpc with ipv6 could not be created. It failed with the following error
|
||||||
|
|
||||||
|
```text
|
||||||
|
│ Error: waiting for EC2 Subnet (subnet-c113e8c02abd344e0) EnableDns64 update: timeout while waiting for state to become 'true' (last state: 'false', timeout: 5m0s)
|
||||||
|
│
|
||||||
|
│ with module.vpc.aws_subnet.private[1],
|
||||||
|
│ on .terraform/modules/vpc/main.tf line 293, in resource "aws_subnet" "private":
|
||||||
|
│ 293: resource "aws_subnet" "private" {
|
||||||
|
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user