Terraform: how can I check if another resource is available - amazon-web-services

I have a Terraform setup that looks basically like this:
Project
├──common
│ └─── cloudfront.tf
│ └─── lambda1.tf
│ └─── lambda2.tf
│
├──staging
│ └─── main.tf
│ └─── symlink to ../common/cloudfront.tf
│ └─── symlink to ../common/lambda2.tf
│
└──prod
└─── main.tf
└─── symlink to ../common/cloudfront.tf
└─── symlink to ../common/lambda1.tf
└─── symlink to ../common/lambda2.tf
So to be able to reuse the different files for staging and/or prod.
Problem I now have is, that in this example staging only has lambda2.tf but not lambda1.tf but the cloudfront.tf has to conditionally create a dynamic block based on whether or not the resource from lambda1.tf is "available" or not.
I tried something like this (with and without the try()):
dynamic "blockname" {
for_each = try( aws_lambda_function.myname, null ) != null ? [1] : []
# ...
}
but as it says in the docs:
The try function will not catch errors relating to constructs that are probably invalid even before dynamic expression evaluation, such as a malformed reference or a reference to a top-level object that has not been declared
I don't want to add an extra variable to toggle the creation of the dynamic block.
Is there a way to achieve what I am trying?

You would have to create custom data source to query a pre-existance status of a resource. Otherwise, you can't do that in TF.

Related

Qt How to add dynamic resource files to project without using .qrc?

My qt project is like this. While the program is running, the "config.xml" will be edited, then the "run.bat" file will be called and produce a lot of data under this folder.
BTW, The size of output data may be over 100GB. I don't have to use them in the program.
│ mainWindow.cpp
│ mainWindow.ui
│ mainWindow.h
│
└─Resource
├─bin
│ │ core.exe
│ │ gencase.exe
│
└─work
├─task1
│ │ config.xml
│ │ run.bat
│ └─ output
│ │ datafiles
│
├─task2
└─...
I want to easily use the relative path of these files, so the "run.bat" can call the "core.exe" and show the output data.
But the files under the work folder are big and should be editable, I don't think adding all the files into .qrc is a good idea.
I don't know how to handle this situation.
Qt Resource files (.qrc) are for static resources (i.e. available at compile time).
Files created during runtime are often stored inside one of the following locations:
QStandardPaths::TempLocation
QStandardPaths::AppLocalDataLocation
QStandardPaths::CacheLocation
QStandardPaths::AppDataLocation
QStandardPaths::GenericConfigLocation
See QStandardPaths for more information.
Storing those files relative to your program executable is often undesirable, as this location is often not writable for the end user (but may be handy in some cases).
If the user should be able to run or edit those files with an external editor, storing these files in a subfolder of the QStandardPaths::HomeLocation may be a good idea too. In that case, it may be desirable to allow the user to optionally change this location.

How to run tests in a multimodule Go project

I'm learning Go with the specialization Programming with Google Go. It has several courses, each of which has several modules.
My project looks like the following (made with https://ascii-tree-generator.com/):
google-golang/
├─ .github/
│ ├─ workflows/
│ │ ├─ ci.yml
├─ golang-getting-started/
│ ├─ module1/
│ │ ├─ main.go
│ │ ├─ main_test.go
│ ├─ module2/
│ │ ├─ trunc/
│ │ │ ├─ main.go
│ │ │ ├─ main_test.go
├─ .gitignore
├─ README.md
I'd like to run all the tests in the *_test.go files for every commit, and it's not clear to me how to do that from the root directory (google-golang). I don't see a need for one module to import another as the exercises can be done independently. This question has two answers, one suggests using submodules, another recommends using Go workspace, but neither provide specific instructions that someone new like me can learn from.
I'm not asking for help on GitHub Actions, I know how to write those. I'm looking for one or more commands that'll find and run the tests.
You seem confused about what a module is. The rule of thumb is, one go.mod file equals one module. Go Wiki, gomod:
A module is defined by a tree of Go source files with a go.mod file in the tree's root directory.
Based on your directory tree shown in your question, there is no go.mod file in sight, hence nothing there is a Go module. As a matter of fact, if you attempt running a module-aware command from google-golang or golang-getting-started you'll have:
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
If you want to run all tests from the root of a multi-module repo, as the title of your question says, with Go 1.17 you can:
init the sub-modules:
$ cd google-golang/golang-getting-started/module1
$ go mod init example.com/module1
$ cd ../module2
$ go mod init example.com/module2
use the trick suggested by Cerise Limón from the root dir of the multi-module project
$ cd google-golang
$ find . -name go.mod -execdir go test ./... \;
If you don't actually care about keeping the sub-repos as separate modules, you can init a module in the root repo and run all tests from there:
$ cd google-golang # or google-golang/golang-getting-started/
$ go mod init example.com/mainmod
$ go test ./...
...however, even this hack works right now, it doesn't make a lot of sense, because your repos named moduleN have main.go files, whose packages are supposedly named main, in each of them. So they are indeed organized as separate sub-modules.

Terragrunt path resolution - locally referenced modules - splitting into multiple environments

For business-related reasons, I am not able to split my infrastructure using versioned modules. As it is still beneficial to split the environments, and I would like to avoid the copy/paste root modules, which are basically just instantiation of child modules, over multiple directories, each representing its own environment, I would like to specify the source of root module in terragrunt.hcl
To make life easier, I have built a small part of the current infrastructure, just with a single module to speed up the development.
The current structure of the project looks like this:
├── config
│ ├── common.tfvars
│ └── terragrunt.hcl
├── environments
│ └── dev
├── infrastructure-modules
│ └── ecs
├── terraform-modules
│ ├── terraform-aws-ecr
All my infrastructure is described in infrastructure-modules/ecs/*.tf files, which are basically just instantiating child modules declared in terraform-modules/terraform-aws-*/.
With that, I can simply execute the terragrunt (terraform commands) from the infrastructure-modules/ecs directory.
To have a possibility to create the same environment in another account, I have introduced a new directory environments/dev/eu-central-1/ecs as shown on tree output from the root directory.
The environments/dev/eu-central-1/ecs, consists just of two files, terragrunt.hcl and common.tfvars.
I guess, that the usage of the common.tfvars is quite self-explanatory, where my terragrunt.hcl consists of remote_state {} and terraform {} blocks.
The important part of the terragrunt configuration file:
remote_state {}
terraform {
source = "../../../../infrastructure-modules/ecs"
{...}
}
Above I am basically referencing my root modules, declared in infrastructure-modules/ecs/*.tf. Where my root modules are instantiating child-modules declared in terraform-modules/terraform-aws-*/.
Child modules from infrastructure-modules/ecs/*.tf are instantianed like this:
module my_module {
source = "../../terraform-modules/terraform-aws-*"
{...}
}
In an ideal world, I would be able to execute terragrunt (terraform) commands from environments/dev/eu-central-1/ecs directory, but as I am using local (relative) paths, this is failing during the initialization of the modules, as the root module my_module loads the child module with following relative path:
module my_module {
source = "../../terraform-modules/terraform-aws-*"
{...}
}
This is causing a module instantiation in environments/dev/eu-central-1/ecs to fail as the relative path is different, based on parent module instantiation.
Initializing modules...
- my_module in
Error: Unreadable module directory
Unable to evaluate directory symlink: lstat ../../terraform-modules: no such
file or directory
So far, according to the documentation, path_relative_*, should be able to return the relative path between the path specified in its include block and the current terragrunt.hcl, but the problem here is that I am not having any include {} block(s) within my terragrunt.hcl files and thus this approach doesn't works. Symlinks are the last option.
EDIT
If I inspect the .terragrunt-cache/* on path environments/dev/eu-central-1/ecs I can confirm that all the "root" modules have been downloaded(copied over) into cache directory.
However, the module is being instantiated like this, and it tries to fetch the actual modules (Terraform modules) from directory two levels above.
module my_modules {
source = "../..//terraform-modules/terraform-aws-ecr"
So basically, I need to tell Terragrunt to download/fetch the modules from other path.
EDIT 2:
Inspecting .terragrunt-cache in the directory where I am running init shows, the the terraform-modules are never downloaded in the
terraform-infrastructure/environments/dev/eu-central-1/ecs/.terragrunt-cache/.
If I change my terraform-infrastructure/infrastructure-modules/ecs/ecr-repos.tf, from
module ecr_lz_ingestion {
source = "../../terraform-modules//terraform-aws-ecr"
{<MODULE_ARGUMENTS>}
}
}
to:
module ecr_lz_ingestion {
source = "../../../../../../../../terraform-modules//terraform-aws-ecr"
{<MODULE_ARGUMENTS>}
}
}
Terraform is able to initialize the child-modules as I have given a relative path to terraform-modules/ in the directory root, which is obviously a workaround.
Somehow I am expecting the Terragrunt to download both directories, terraform-modules and infrastructure-modules for the relative paths in module instantiation to work.
Based off the additional information you provided, I understand that this is your current directory structure:
terraform-infrastructure
├── config
│ ├── common.tfvars
│ └── terragrunt.hcl
├── environments
│ └── dev
│ └── eu-central-1
│ └── ecs
│ └── terragrunt.hcl
├── infrastructure-modules
│ └── ecs
├── terraform-modules
│ ├── terraform-aws-ecr
│
├── terragrunt.hcl
Notice the terragrunt.hcl in the parent directory that I added.
That terragrunt.hcl is considered the parent file and can include code that can be shared among other terragrunt files.
It can include something like this:
remote_state {}
In your eu-central-1/ecs folder, add the following to your terragrunt file:
include {
// searches up the directory tree from the current terragrunt.hcl file
// and returns the absolute path to the first terragrunt.hcl
path = find_in_parent_folders()
}
// using the path relative from the path stated in the include block
terraform {
source = "${path_relative_from_include()}//infrastructure-modules”
}
This should keep relative pathing intact when child modules are instantiating.
Edit:
From your GitHub issue, it would be best to either move the double slash to somewhere the modules share a common path with. Either that or to just consolidate your modules into a single folder.

Linking SDL-bgi in Code::Blocks on windows using a custom install dir

I have a program, that works on Linux using SDL-bgi. I have downloaded the SDL-bgi binaries from http://libxbgi.sourceforge.net/ , and can get it to compile, but I can't get it to link (giving me"undefined reference to ... errors). The download provides a DLL, but according to the answer to this question, I need a .lib. I can't find any .lib anywhere n the download.
Here is the output of tree /f in the folder extracted:
│ AUTHORS
│ BUGS
│ build.sh
│ ChangeLog
│ CMakeLists.txt
│ INSTALL.md
│ LICENSE
│ README.md
│ sdl_bgi.spec
│ TODO
│ VERSION
│
├───bin
│ ├───CodeBlocks
│ │ SDL_bgi.dll
│ │
│ ├───Dev-Cpp
│ │ SDL_bgi.dll
│ │
│ └───Mingw64
│ SDL_bgi.dll
│
├───doc
│ functions.md
│ functions.pdf
│ howto_CodeBlocks.md
│ howto_CodeBlocks.pdf
│ howto_Dev-Cpp.md
│ howto_Dev-Cpp.pdf
│ sdl_bgi-quickref.pdf
│ sdl_bgi-quickref.tex
│ SDL_bgi_logo.png
│ SDL_bgi_logo.svg
│ turtlegraphics.pdf
│ turtlegraphics.tex
│ using.md
│ using.pdf
│
├───src
│ graphics.h
│ Makefile
│ Makefile.CodeBlocks
│ Makefile.DevCpp
│ SDL_bgi.c
│ SDL_bgi.h
│
└───test
[... a bunch of c files]
I am trying to link to the library from where it is, instead of C:\CodeBlocks\MinGW\bin as recommended by the docs, because I don't have the right privileges.
First Method if you don't have installed old bordland graphics interface in Codeblocks then use this method other-wise you get error like multiple declaration because both library use same function declaration
step:1- Create a New c console project name it what ever you want then paste the
files from include folder from the zip below and paste it here
C:\Program Files (x86)\CodeBlocks\MinGW\include
then paste libsdlbgi.a from the zip file to this path
C:\Program Files (x86)\CodeBlocks\MinGW\lib
SDLBGI.zip
step:2-Go to the codeblocks then go to setting then select compiler go to linker option and click add then browse to previously pasted libsdlbgi.a file then add it then go to search directory linker and do same with libsdlbgi.a
again.
Step:3-Write any simple program and built and compile and run it.
Second method if you want both bgi and sdl bgi
Follow all the steps carefully to get it works
Step:1- Simply create a new project in Code-Block using SDL2 from the category click enter and give a title to the project then click next and finish to create to new project.
Step:2- Go to your directory where you have created your project then copy these files
'SDL_bgi.c' , 'SDL_bgi.h' and 'sdlbgidemo.c' , 'logo.bmp' from the "SDL_bgi-2.2.4" [src folder] and [test folder] to project folder.
Step:3-First delete default main.cpp file from codeblock project then add "sdlbgidemo.c" into the project then click ok in next window in CodeBlocks which ask for
select target file to "debug" and "release"
Step:4-select the sdlbgidemo.c in codeblock then open it in the code editor then change the #include <'graphics.h'> header to #include "SDL_bgi.c"
Step:5-Last Step press built and run button it will built and run the project and you will probably see the previously pasted logo.bmp on the screen then you can see demo of all SDL_bgi Library funtions.
Here it is Code-block project file [zip] for you with all the necessary modification so you can easily run it using Code-blocks.
[Code-Blocks Project File.zip]
if you don't want to repeat step:2 and step:3 every time you created new project you follow Step:5 to solve this problem.
Step:6-First go to the directory where you have installed your Codeblocks then browse through [Mingw] then [include] folder in this folder you can simply copy 'SDL_bgi.c' , 'SDL_bgi.h' or if you have already installed Old Borland Graphics library [BGI] then you have to create separate folder for SDL-BGI and have to paste all files which i tell you earlier in this newly created folder then if you want you to use or include these files in your project simply
type these lines #include "SDL_bgi.c" or #include "[Previously created folder]/SDL_bgi.c" to run your program.
Here is the link of zip file which have some screen shot of all the steps we have taken so far...
[ScreenShot.zip]
I hope this solve your problem and save your time.
At Last
That's all folks

Is it possible to install Fortran Compiler into flash drive?

Currently I'm running the gfortran compiler in my computer. But I'm just wondering if I'm able to install the fortran compiler in my flash drive. That way I can run fortran anywhere else without installing the compiler into the main computer. I try to search in Google but I'm not able to find a solution to it. Does that mean that I'm not able to do it just like any other compiler??
Edited:
Sorry currently I'm using Window 7 to run the Fortran Compiler. But I may run the compiler in Window Vista or XP if I'm able to install the compiler in my flash drive.
The flash drive size is 8 GB. I used about half of it already.
Thank you very much!
A flash drive is not an operating system. A compiler is simply a computer program, which itself has been compiled for a certain operating system. So you can put the compiled binary for a given operating system on a flash drive and execute it from the flash drive, but every computer that you use it on would have to be running the same operating system. If this solution does not work for you, you could look into making a bootable flash drive (which is an entire operating system hosted on a flash drive) and installing a Fortran compiler on that.
I hope this helped.
--- EDIT ---
After seeing your edit, it is very possible that you could install a compiler on your flash drive and then use it on other Windows 7 Machines or other compatible Windows machines. It is probably as simple as setting the installation directory to the flash drive during the time of installation, as long as the compiler doesn't rely on any registry values.
I don't know much about gfortran which I just use on the HPC(Linux OS) but I think u cna give g95 a try.
I simply copy the whole directory to some place and I wrote a .bat file to set the path, it works.
The only problem is , that program can not know where is the HOME dir.
my files:
D:\bin\g95>tree
卷 D: 的文件夹 PATH 列表
卷序列号为 00000200 5E6C:35EF
D:.
├─bin
├─doc
└─lib
└─gcc-lib
└─i686-pc-mingw32
└─4.1.2
D:\bin\g95>tree /f
卷 D: 的文件夹 PATH 列表
卷序列号为 00000200 5E6C:35EF
D:.
├─bin
│ a.exe
│ ar.exe
│ as.exe
│ b.f
│ b.zip
│ f.dat
│ g95.exe
│ h.ctl
│ h.grd
│ ld.exe
│ mingwm10.dll
│ ranlib.exe
│ rm.dat
│ strip.exe
│ ua.dat
│ uc.dat
│ va.dat
│ vc.dat
│ za.dat
│ zc.dat
│
├─doc
│ bg.gif
│ COPYING.txt
│ docs.html
│ g95.bmp
│ G95Manual.pdf
│ Readme.html
│ README.txt
│
└─lib
│ crt1.o
│ crt2.o
│ dllcrt2.o
│ libadvapi32.a
│ libgdi32.a
│ libkernel32.a
│ libm.a
│ libmingw32.a
│ libmingwex.a
│ libmoldname.a
│ libmsvcrt.a
│ libshell32.a
│ libuser32.a
│ libws2_32.a
│
└─gcc-lib
└─i686-pc-mingw32
└─4.1.2
cc1.lnk
f951.exe
libf95.a
libgcc.a
and my setg95.bat file:
set PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;d:\bin\g95\bin;d:\bin\vim\vim63;d:\bin\bin;
SET LIBRARY_PATH = d:\bin\g95\lib
set G95_LIBRARY_PATH=d:\bin\g95\lib
d:
rem under win32 :
rem g95 -ffree-form -fendian=big -o readv3 readv3.f
cmd