Getting Resource as null while creating AWS Cloudformation Stack using template - amazon-web-services

I am trying to create Stack using AWS Cloudformation.
I used below Roles and Policy.
I think I have proper indentation for the Resource which it is complaining. I saw another similar issue in StackOverflow but it seems like mine is not the same issue as that of the posted question in stack overflow.
AWSTemplateFormatVersion: 2010-09-09
Description: A CCL EBS template
Resources:
  CodeForCCLEBSAPI:
    Type: AWS::IAM::Role
    Properties:
      RoleName: 'ccl-ebs-role-1'
      AssumeRolePolicyDocument:
        Statement:
        - Action: ['sts:AssumeRole']
          Effect: Allow
          Principal:
            Service: [codebuild.amazonaws.com]
        Version: '2012-10-17'
      Path: /
      Policies:
        - PolicyName: CodeForCCLEBSAPI
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
- Action:
- elasticbeanstalk:CreateApplication
- elasticbeanstalk:CreateEnvironment
- elasticbeanstalk:DeleteApplication
- elasticbeanstalk:RebuildEnvironment
- elasticbeanstalk:SwapEnvironmentCNAMEs
- elasticbeanstalk:TerminateEnvironment
Effect: Allow
Resource: "*"
- Action:
- elasticbeanstalk:*
- ec2:*
- elasticloadbalancing:*
- autoscaling:*
- cloudwatch:*
- s3:*
- sns:*
- rds:*
- cloudformation:*
Effect: Allow
Resource: "*"
I am getting below error
[/Resources] 'null' values are not allowed in templates

There is absolutely nothing wrong with your template nor the role. The template deploys perfectly fine (I tested it).

Related

(AWS) Terraform: "no matching Route53Zone found"

Im currently trying to set up an AWS EC2 Instance & integrated API-Gateway with terraform.
I watched the tutorial of Anton Putra: https://www.youtube.com/watch?v=XhS2JbPg8jA&t=287s
and also cloned his code: https://github.com/antonputra/tutorials/tree/main/lessons/118
I simply wanted to rename some of the resources and apply the terraform.
"terraform init" works but when i run "terraform apply", i get this message:
CMD Error Message
This is the code from the file its complaining about:
resource "aws_acm_certificate" "gradebook" {
    domain_name          = "gradebook.bmeisn.com"
    validation_method = "DNS"
} 
data "aws_route53_zone" "gradebook-r53z" {
    name              = "bmeisn.com"
    private_zone      = false
} 
resource "aws_route53_record" "gradebook-r53r" {
    for_each = {
        for dvo in aws_acm_certificate.gradebook.domain_validation_options : dvo.domain_name => {
            name    = dvo.resource_record_name
            record    = dvo.resource_record_value
            type    = dvo.resource_record_type
        }
    }    
allow_overwrite = true
    name            = each.value.name
    records            = [each.value.record]
    ttl                = 60
    type            = each.value.type
    zone_id            = data.aws_route53_zone.gradebook-r53z.zone_id
} 
resource "aws_acm_certificate_validation" "gradebook" {
    certificate_arn            = aws_acm_certificate.gradebook.arn
    validation_record_fqdns    = [for record in aws_route53_record.gradebook-r53r : record.fqdn ]
}
I read that it might be because of the domain so heres the tf file for that aswell:
resource "aws_apigatewayv2_domain_name" "gradebook" {
  domain_name = "gradebook.bmeisn.com"   domain_name_configuration {
    certificate_arn = aws_acm_certificate.gradebook.arn
    endpoint_type   = "REGIONAL"
    security_policy = "TLS_1_2"
  }  
depends_on = [aws_acm_certificate_validation.gradebook]
} 
resource "aws_route53_record" "gradebook-r53r-02" {
  name    = aws_apigatewayv2_domain_name.gradebook.domain_name
  type    = "A"
  zone_id = data.aws_route53_zone.gradebook-r53z.zone_id   alias {
    name                   = aws_apigatewayv2_domain_name.gradebook.domain_name_configuration[0].target_domain_name
    zone_id                = aws_apigatewayv2_domain_name.gradebook.domain_name_configuration[0].hosted_zone_id
    evaluate_target_health = false
  }
} 
resource "aws_apigatewayv2_api_mapping" "gradebook-map" {
  api_id      = aws_apigatewayv2_api.gradebook-agw.id
  domain_name = aws_apigatewayv2_domain_name.gradebook.id
  stage       = aws_apigatewayv2_stage.dev.id
} 
output "custom_domain_api-v2" {
  value = "https://${aws_apigatewayv2_api_mapping.gradebook-map.domain_name}/health"
}
The whole setup around it seems to work so im assuming i did something wrong here, i just cant figure out what exactly as im not very experienced with this technology.
Also if this question is missing any important info, let me know.
As pointed out in the comments, you aren't exactly creating your Route 53 zone. If you're committed to do it via Terraform (I'd personally advise against it but it's your choice to make) aws_route53_zone resource is what you seek, it also has example on how to reference a zone you're to create.
In case you still get messages about it being absent AFTER referencing zone resource you are creating (Terraform borking the resource creating order), then just use depends_on and call it a day.

GCP - "Terraform Import" on VPC SC Perimeter removing Access List

I am trying to import VPC SC Perimeter in to terraform state, but the plan shows removing one Access Level(test_ent_perim_access_002) in the perimeter, not sure why. Also Access List "test_ent_perim_access_001" is getting removed and again added.
Below is the resource
resource "google_access_context_manager_service_perimeter" "test-ent-prod-perim-001" {
    parent         = "accessPolicies/263896276372"
    name           = "accessPolicies/263896276372/servicePerimeters/test_ent_prod_perim_001"
    title          = "test_ent_prod_perim_001"
    description = "Test Org VPC SC perimeter"
    perimeter_type = "PERIMETER_TYPE_REGULAR"
    status {
      resources = ["7654356728263"]
      restricted_services = ["bigquery.googleapis.com"]
          access_levels       = [
              "accessPolicies/263896276372/accessLevels/test_onprem_ipwhitelist",
              "accessPolicies/263896276372/accessLevels/test_ent_cmn_perim_access_001",
              "accessPolicies/263896276372/accessLevels/test_ent_perim_access_001",
              "accessPolicies/263896276372/accessLevels/test_ent_perim_access_002",
              ]
    }
  }
Below is the import command
- terraform import --var-file=$VARS --var-file=$BACKEND --var-file=vars/$ENV/terraform.tfvars google_access_context_manager_service_perimeter.test-ent-prod-perim-001 accessPolicies/263896276372/servicePerimeters/test_ent_prod_perim_001 
Below is the plan where it shows the removal of Access Level
Terraform will perform the following actions:
# google_access_context_manager_service_perimeter.test-ent-prod-perim-001 will be updated in-place
~ resource "google_access_context_manager_service_perimeter" "test-ent-prod-perim-001" {
~ description = "Perimeter shielding projects" -> "Prod VPC perimeter"
id = "accessPolicies/263896276372/servicePerimeters/test_ent_prod_perim_001"
name = "accessPolicies/263896276372/servicePerimeters/test_ent_prod_perim_001"
# (4 unchanged attributes hidden)
~ status {
~ access_levels = [
- "accessPolicies/263896276372/accessLevels/test_ent_perim_access_001",
"accessPolicies/263896276372/accessLevels/test_onprem_ipwhitelist",
# (1 unchanged element hidden)
"accessPolicies/263896276372/accessLevels/test_ent_perim_access_002",
- "accessPolicies/263896276372/accessLevels/test_ent_perim_access_002",
+ "accessPolicies/263896276372/accessLevels/test_ent_perim_access_001",
]
# (2 unchanged attributes hidden)
}
# (1 unchanged block hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.

Terraform : Invalid dynamic for_each value => Cannot use a set of object value in for_each. An iterable collection is required

In terraform version 1.1.9 am facing the below issue while doing terraform apply.
Help me to fix how this for_each can be done without error.
rke_nodes values sample will be :
# Outputs
output "rancher_nodes" {
  value = [
        for instance in flatten([[aws_instance.node_all], [aws_instance.node_master], [aws_instance.node_worker]]): {
    public_ip  = instance.public_ip
    private_ip = instance.private_ip
    hostname   = instance.id
    user       = var.node_username
    roles      = split(",", instance.tags.K8sRoles)
    ssh_key    = file(var.ssh_key_file)
    }
  ]
  sensitive = true
}
I have variable.tf :
variable "rke_nodes" {
type = list(object({
public_ip = string
private_ip = string
hostname = string
roles = list(string)
user = string
ssh_key = string
}))
description = "Node info to install RKE cluster"
}
main.tf :
# Provision RKE cluster on provided infrastructure
resource "rke_cluster" "rancher_cluster" {
cluster_name = var.rke.cluster_name
dynamic nodes {
for_each = var.rke_nodes
content {
address = nodes.value.public_ip
internal_address = nodes.value.private_ip
hostname_override = nodes.value.hostname
user = nodes.value.user
role = nodes.value.roles
ssh_key = nodes.value.ssh_key
}
}
upgrade_strategy {
drain = false
max_unavailable_controlplane = "1"
max_unavailable_worker = "10%"
}
kubernetes_version = var.rke.kubernetes_version
}
I got error when terraform apply :
╷
│ Error: Invalid dynamic for_each value
│
│ on .terraform/modules/rke-cluster/main.tf line 6, in resource "rke_cluster" "rancher_cluster":
│ 6: for_each = var.rke_nodes
│ ├────────────────
│ │ var.rke_nodes has a sensitive value
│
│ Cannot use a list of object value in for_each. An iterable collection is required.
Actual Value when apply it can be list in sometimes:
- nodes {
- address = "65.2.140.68" -> null
- hostname_override = "i-0d5bf5f22fb84f5d4" -> null
- internal_address = "10.30.8.120" -> null
- labels = {} -> null
- role = [
- "controlplane",
- "etcd",
- "worker",
] -> null
- ssh_agent_auth = false -> null
- ssh_key = (sensitive value)
- user = (sensitive value)
}
You don't need index. It just should be:
for_each = var.rke_nodes
Note: This works only for dynamic blocks. If you use for_each in resource blocks, this form of for_each (list of maps) will not work.

Terraform -ssh: handshake failed: ssh: │ unable to authenticate, attempted methods [none publickey], no supported methods remain ╵

I have my terraform code to ssh into a ec2 instance and i keep getting the error as below. Also, I am able to ssh into the instance from my local machine.
timeout - last error: SSH authentication failed (kali#:22): ssh: handshake failed: ssh:
│ unable to authenticate, attempted methods [none publickey], no supported methods remain
here is my code:
resource "aws_key_pair" "public_key" {
  key_name   = "public_key”
  public_key = "ssh-rsa xxxxxxxxxxxxx"
}
data "template_file" "user_data" {
  template = file("../kali_linux_aws/payload.sh")
}
resource "aws_default_subnet" "default" {
    availability_zone = var.availability_zone
}
resource "aws_default_vpc" "default" {
  tags = {
    Name = "Default VPC"
  }
}
resource "aws_security_group" "kali_security_group" {
  name        = "allow_tls"
  description = "Allow TLS inbound traffic"
  vpc_id      = aws_default_vpc.default.id
  ingress {
    description      = "ssh"
    from_port        = 22
    to_port          = 22
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }
  ingress {
    description      = "rdp"
    from_port        = 3389
    to_port          = 3389
    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"]
    ipv6_cidr_blocks = ["::/0"]
  }
  tags = {
    Name = "kali_security_group"
  }
}
resource "aws_instance" "kali_linux" {
  ami                         = "ami-0f226738ik68873d1"
  instance_type               = var.instance_type
  availability_zone           = var.availability_zone
  associate_public_ip_address = true
  key_name                    = aws_key_pair.public_key.key_name
  user_data                   = data.template_file.user_data.rendered
  subnet_id                   = var.subnet_id == null ? aws_default_subnet.default.id : var.subnet_id
  vpc_security_group_ids      = [aws_security_group.kali_security_group.id]
 
  root_block_device {
    volume_size = var.volume_size
  }
}
resource "null_resource" "provision"{
  connection {
    type = "ssh"
    user = "kali"
    private_key = "${file("/Users/path/to/id_rsa")}"
    host = aws_instance.kali_linux.public_ip
  }
  provisioner "remote-exec" {
    inline = [
      "sudo apt-get update"
    ]
}
}
All i am trying to do is to create a kali linux EC2 instance on AWS and run some remote-exec commands. Can someone please help? Also if there are any workarounds please suggest as well. Thank you in advance.

How to invoke a new EC2 instance with existing IAM role? / JavaScript AWS SDK v3 - RunInstancesCommand

How can I launch an EC2 instance with attached (existing) IAM Role in JavaScript?
I know this question has been asked for other languages, but I couldn't find an example for JavaScript.
My JS Lambda code currently looks like:
const { EC2Client } = require( "#aws-sdk/client-ec2");
const ec2Client = new EC2Client({ region: "eu-central-1" });
const {
CreateTagsCommand,
RunInstancesCommand,
TerminateInstancesCommand,
RunInstancesRequest
} = require("#aws-sdk/client-ec2");
const instanceParams = {
ImageId: "ami-00a844bXXXXXXXXXX",
InstanceType: "a1.xlarge",
KeyName: "YourKeyName",
MinCount: 1,
MaxCount: 1,
SecurityGroupIds: ["sg-XXXXXXXXXXXXX"],
IamInstanceProfile: "arn:aws:iam::390000000000:instance-profile/NAME" // doesn't work
};
const run = async () => {
try {
const data = await ec2Client.send(new RunInstancesCommand(instanceParams));
console.log(data.Instances[0].InstanceId);
} catch (err) {
console.log("Error", err);
}
}
var ret = await run();
Documentation:
https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-ec2/interfaces/runinstancescommandinput.html#iaminstanceprofile
"#aws-sdk/client-ec2": "^3.44.0",
"#aws-sdk/client-lambda": "^3.45.0",
The code above runs, but the IAM Role under the EC2 > Instances > Security tab remains empty in all my tries.
For IamInstanceProfile field you need to specify the ARN or name. Try with any of these options:
const instanceParams = {
ImageId: "ami-00a844bXXXXXXXXXX",
InstanceType: "a1.xlarge",
KeyName: "YourKeyName",
MinCount: 1,
MaxCount: 1,
SecurityGroupIds: ["sg-XXXXXXXXXXXXX"],
IamInstanceProfile:
{
Name: "NAME"
}
};
or
const instanceParams = {
ImageId: "ami-00a844bXXXXXXXXXX",
InstanceType: "a1.xlarge",
KeyName: "YourKeyName",
MinCount: 1,
MaxCount: 1,
SecurityGroupIds: ["sg-XXXXXXXXXXXXX"],
IamInstanceProfile:
{
Arn: "arn:aws:iam::390000000000:instance-profile/NAME"
}
};
JavaScript SDK runInstances