I am getting an invalid ARN from Terraform - terraform

I have an issue where I am not getting the instance-profile in the ARN path. Code snippet:
resource "aws_launch_template" "launch-template" {
image_id = data.aws_ami.ecs.id
instance_type = "c5.large"
iam_instance_profile {
arn = aws_iam_role.ecsInstanceRole.arn
}
}
resource "aws_iam_role" "ecsInstanceRole" {
name = "assess-instance-role"
assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json
}
I get the following error:
Error: error creating EC2 Launch Template (lt-12344444444444) Version: InvalidIamInstanceProfileArn.Malformed: The ARN ‘arn:aws:iam::1234444444444:role/assess-instance-role’ is not valid. The expected format is arn:aws:iam:::instance-profile/ (this is followed by < instance-profile-name > but the formatting it not letting me write it.
I am on the following version:
Terraform v1.2.3
on darwin_arm64
+ provider registry.terraform.io/hashicorp/aws v3.75.2

As Jordanm pointed out in the comment, you can't attach a role to an ec2, you must create an instance profile from the role: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile

Related

Why am I getting this 404 Authorization error on Terraform OCI?

Trying to provision a network in OCI and I'm getting this same error for every single subnet even though the "terraform plan" is successful with no issues. Anybody know what the problem is here?
Error: 404-NotAuthorizedOrNotFound, Authorization failed or requested resource not found.
Suggestion: Either the resource has been deleted or service Core Subnet need policy to access this resource. Policy reference: https://docs.oracle.com/en-us/iaas/Content/Identity/Reference/policyreference.htm
Documentation: https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_subnet
API Reference: https://docs.oracle.com/iaas/api/#/en/iaas/xxxxxxxx/Subnet/CreateSubnet
Request Target: POST https://iaas.us-ashburn-1.oraclecloud.com/xxxxxxxx/subnets
Provider version: 4.88.1, released on 2022-08-11.
Service: Core Subnet
Operation Name: CreateSubnet
OPC request ID: xx/xx/xx
on .terraform/modules/network/main-region2.tf line 899, in resource "oci_core_subnet" "subnets_sec":
899: resource "oci_core_subnet" "subnets_sec" {
This is what I'm using for my subnet resource block:
resource "oci_core_subnet" "subnets_sec" {
// Description: a subnet will be created for each key within the subnet_params_sec variable
provider = oci.region_sec
for_each = var.subnet_params_sec
display_name = each.key
compartment_id = oci_core_virtual_network.vcn_sec[each.value.vcn_name].compartment_id
vcn_id = oci_core_virtual_network.vcn_sec[each.value.vcn_name].id
cidr_block = each.value.cidr_block
dns_label = each.value.dns_label
dhcp_options_id = lookup(var.dhcp_params_sec, each.key, null) != null ? oci_core_dhcp_options.default_dhcp_vcnres_sec[each.value.vcn_name].id : ""
prohibit_public_ip_on_vnic = each.value.is_subnet_private
route_table_id = each.value.rt_name
}
Last important piece of info is that this was being deployed to an empty compartment so I don't know how a resource can be missing or deleted.

How to include a policy json file in Terraform?

Downloaded this iam policy file and save it in the root path besides main.tf in Terraform:
https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.2.1/docs/install/iam_policy.json
Made this creation want to call the policy file
resource "aws_iam_policy" "worker_policy" {
name = "worker-policy"
policy = file("iam-policy.json")
}
The tflint got this error:
15:36:27 server.go:418: rpc: gob error encoding body: gob: type not registered for interface: tfdiags.diagnosticsAsError
Failed to check ruleset. An error occurred:
Error: Failed to check `aws_iam_policy_invalid_policy` rule: reading body EOF
I also tried this way, the same result:
policy = jsondecode(file("iam-policy.json"))
Did you use the latest version of tflint?
Because I've tried and everything was OK for me
There were my steps:
NOTE: tflint v0.31.0 and terraform v1.0.2
[1] wget https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.2.1/docs/install/iam_policy.json
[2] In my main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_iam_policy" "worker_policy" {
name = "worker-policy"
policy = file("iam_policy.json")
}
[3] Run terraform plan
[4] Have gotten
Terraform will perform the following actions:
# aws_iam_policy.worker_policy will be created + resource "aws_iam_policy" "worker_policy" {
+ arn = (known after apply)
+ id = (known after apply)
+ name = "worker-policy"
+ path = "/"
+ policy = jsonencode(
{
+ Statement = [
+ {
+ Action = [
+ "iam:CreateServiceLinkedRole",
+ "ec2:DescribeAccountAttributes",
+ "ec2:DescribeAddresses",
...
[5] Run tflint
~/Work/Other/test ❯ tflint --init
Plugin `aws` is already installed
~/Work/Other/test ❯ tflint
~/Work/Other/test ❯

Terraform simple script says "Error: Error launching source instance: VPCIdNotSpecified: No default VPC for this user"

Getting started on Terraform. I am trying to provision an EC2 instance using the following .tf file. I have a default VPC already in my account in the AZ I am trying to provision the EC2 instance.
# Terraform Settings Block
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
#version = "~> 3.21" # Optional but recommended in production
}
}
}
# Provider Block
provider "aws" {
profile = "default"
region = "us-east-1"
}
# Resource Block
resource "aws_instance" "ec2demo" {
ami = "ami-c998b6b2"
instance_type = "t2.micro"
}
I do the following Terraform commands.
terraform init
terraform plan
terraform apply
aws_instance.ec2demo: Creating...
Error: Error launching source instance: VPCIdNotSpecified: No default VPC for this user. GroupName is only supported for EC2-Classic and default VPC.
status code: 400, request id: 04274b8c-9fc2-47c0-8d51-5b627e6cf7cc
on ec2-instance.tf line 18, in resource "aws_instance" "ec2demo":
18: resource "aws_instance" "ec2demo" {
As the error suggests, it doesn't find the default VPC in the us-east-1 region.
You can provide the subnet_id within your VPC to create your instance as below.
resource "aws_instance" "ec2demo" {
ami = "ami-c998b6b2"
instance_type = "t2.micro"
subnet_id = "subnet-0b1250d733767bafe"
}
I'm only create a Default VPC in AWS
AWS VPC
actions
create default VPC
it's done, you try again now
terraform plan
terraform apply
As of now if there is any default VPC available in the AWS account then using terraform resource aws_instance instance can be created without any network spec input.
Official AWS-terraform example:
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#basic-example-using-ami-lookup
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id ## Or use static AMI ID for testing.
instance_type = "t3.micro"
}
The error message: Error: Error launching source instance: VPCIdNotSpecified: No default VPC for this user. states that the EC2 instance did not find any networking configuration in your terraform code where it needs to create the instance.
This is probably because of the missing default VPC in your AWS account and it seems that you are not passing any network config input to terraform resource.
Basically, you have two ways to fix this
Create a default VPC and then use the same code.
Document: https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html#create-default-vpc
Another and better way would be to inject the network config to aws_instance resource. I have used the example from the official aws_instance resource. Feel free to update any attributes accordingly.
resource "aws_vpc" "my_vpc" {
cidr_block = "172.16.0.0/16"
tags = {
Name = "tf-example"
}
}
resource "aws_subnet" "my_subnet" {
vpc_id = aws_vpc.my_vpc.id
cidr_block = "172.16.10.0/24"
availability_zone = "us-west-2a"
tags = {
Name = "tf-example"
}
}
resource "aws_network_interface" "foo" {
subnet_id = aws_subnet.my_subnet.id
private_ips = ["172.16.10.100"]
tags = {
Name = "primary_network_interface"
}
}
resource "aws_instance" "foo" {
ami = "ami-005e54dee72cc1d00" # us-west-2
instance_type = "t2.micro"
network_interface {
network_interface_id = aws_network_interface.foo.id
device_index = 0
}
credit_specification {
cpu_credits = "unlimited"
}
}
Another way of passing network config to ec2 instance is to use subnet_id in aws_instance resource as suggested by others.
Are there probabilities that you deleted the default vpc, if u did u can recreate going to the VPC Section -> My Vpcs -> At the right corner you will see a dropdown called actions click and select create a default vpc
As the AWS announcement last year On August 15, 2022 we expect all migrations to be complete, with no remaining EC2-Classic resources present in any AWS account. From now on you will need to specify while you are creating any new resources the subnet_id and declare it inside your while creating.
Example :
resource "aws_instance" "test" {
ami = "ami-xxxxx"
instance_type = var.instance_type
vpc_security_group_ids = ["sg-xxxxxxx"]
subnet_id = "subnet-xxxxxx"

Why does Terraform want to create the custom attribute again?

I am try to use the Vsphere_custom_attribute resource. On the first run on an VSphere it runs fine but on the second run I get the error below.
Do you have any ideas how to solve this ?
or did i just use it wrong ?
I use this Version of Terraform and Vsphere provider.
Terraform v0.12.12
provider.template v2.1.2
provider.vsphere v1.13.0
These are the code parts where i create the custom attributes and where i use it.
resource "vsphere_custom_attribute" "hostname" {
name = "hypervisor.hostname"
managed_object_type = "VirtualMachine"
}
resource "vsphere_virtual_machine" "vm" {
...
custom_attributes = "${map(vsphere_custom_attribute.hostname.id, "${var.vsphere_name}${var.vsphere_dom}" )}"
...
}
Error :
Error: could not create custom attribute: ServerFaultCode: The name 'hypervisor.hostname' already exists.
on main.tf line 32, in resource "vsphere_custom_attribute" "hostname":
32: resource "vsphere_custom_attribute" "hostname" {
terraform plan:
I do not understand why Terraform want to create it the custom attribute as it already exists.
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# vsphere_custom_attribute.hostname will be created
+ resource "vsphere_custom_attribute" "hostname" {
+ id = (known after apply)
+ managed_object_type = "VirtualMachine"
+ name = "hypervisor.hostname"
}
This is because you're saying create the 'resource' instead of pulling the 'data' from vsphere. I had this confusion as well until understanding the 'vsphere_datastore' input required.
Try something like this (im using octopus deploy for variable replacement so ignore that im using invalid #{, should be ${ or just straight string for 0.12.x
...
data "vsphere_custom_attribute" "consul_backend_path" {
name = "consul.backend.path"
}
...
resource "vsphere_virtual_machine" "windows_virtual_machine" {
...
custom_attributes = map(data.vsphere_custom_attribute.consul_backend_path.id, "custom_attribute_value")
...
}
Keep in mind, this requires the resource of the custom attribute to be in vcenter before this virtual_machine resource is created. Otherwise you will need to do a logic test to validate if the tag is required.

Unknown resource referenced in variable with Terraform

I am a beginner to Terraform.
I am trying to execute following code from Terraform Getting started guide.
provider "aws" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}
resource "aws_instance" "example" {
ami = "${lookup(var.amis, var.region)}"
instance_type = "t2.micro"
tags {
Name = "newprovisionerstest"
}
provisioner "local-exec" {
command = "echo ${aws_instance.example.public_ip} > ip_address.txt"
}
}
output "ip" {
value = "${aws_eip.ip.public_ip}"
}
When I run
terraform apply
or
terraform refresh
It gives following error:
Error: output 'ip': unknown resource 'aws_eip.ip' referenced in variable aws_eip.ip.public_ip
Why is it so? Is it because "aws_eip" resource is not declared anywhere?
Like you said it yourself, there is no aws_eip resource called ip.
If you use the
aws_instance.example.public_ip
it should work totally fine

Resources