I have the below terraform code which works but every time I merge to master and run the github action to call terraform apply the deployment takes 30mins+. As far as I can see the logs are full of google_app_engine_flexible_app_version.myapp: Still creating... [15m0s elapsed]
and
google_app_engine_service_split_traffic.myapp: Still modifying... [id=apps/myproject/services/myapp, 13m40s elapsed]
It's not exactly release often and quickly is it? Is there anything you can see on why this is taking so long?
resource "google_app_engine_flexible_app_version" "myapp" {
project = var.GCP_PROJECT
service = "myapp"
runtime = "custom"
version_id = "v${formatdate("YYYYMMDD-hhmmss",timestamp())}"
noop_on_destroy = false
lifecycle {
create_before_destroy = true
}
resources {
cpu = 1
memory_gb = 1
disk_gb = 10
}
deployment {
container {
image = "eu.gcr.io/${var.GCP_PROJECT}/myapp:${var.GIT_SHA}"
}
}
env_variables = {
ASPNETCORE_ENVIRONMENT = var.ENVIRONMENT
}
beta_settings = {
cloud_sql_instances = "${google_sql_database_instance.gps.connection_name}=tcp:5432"
}
manual_scaling {
instances = 1
}
liveness_check {
path = "/liveness_check"
}
readiness_check {
path = "/readiness_check"
app_start_timeout = "1800s"
}
}
resource "google_app_engine_service_split_traffic" "myapp" {
service = google_app_engine_flexible_app_version.myapp.service
migrate_traffic = false
split {
allocations = {
(google_app_engine_flexible_app_version.myapp.version_id) = 1.0
}
}
}
resource "google_dns_record_set" "myapp" {
name = "${local.myapp_domain_name}."
managed_zone = var.DNS_ZONE_NAME
type = "CNAME"
ttl = 300
rrdatas = ["ghs.googlehosted.com."]
}
resource "google_app_engine_domain_mapping" "myapp" {
domain_name = local.myapp_domain_name
override_strategy = "OVERRIDE"
ssl_settings {
ssl_management_type = "AUTOMATIC"
}
}
Related
I am trying to create routes in Transit gateway route table using a json template. However, while fetching each string value from an array of string defined in json template, getting error as below;
Error: Incorrect attribute value type\n\n on main.tf line 90, in resource \"aws_ec2_transit_gateway_route\" \"ip_route\":\n 90: destination_cidr_block = each.value.ip_network\n |----------------\n | each.value.ip_network is tuple with 3 elements\n\nInappropriate value for attribute \"destination_cidr_block\": string require
Here below is my code -->
resource "aws_ec2_transit_gateway_route" "ip_route" {
for_each = jsondecode(file("templates/my.json"))
destination_cidr_block = each.value.ip_network
transit_gateway_attachment_id = "tgw-attach-123"
transit_gateway_route_table_id = each.value.tgw_rt_id
}
json file -->
{
"RT-1": {
"tgw_rt_id": "tgw-rtb-00128",
"ip_network": [
"1.1.1.0/24",
"1.1.2.0/24",
"1.1.3.0/24"
]
},
"RT-2": {
"tgw_rt_id": "tgw-rtb-01f1b",
"ip_network": [
"1.1.1.0/24",
"1.1.2.0/24",
"1.1.3.0/24"
]
}
}
I am able to get the "destination_cidr_block" value as "string" if only single string is passed in "ip_network" (eg: "ip_network": "1.1.1.0/24") but failed to fetch when defined with array of string.
As you've identified, the destination_cidr_block only accepts a single CIDR block (a string), not multiple CIDR blocks. You need to create a separate aws_ec2_transit_gateway_route for each CIDR block for each route table. You can do this by flattening the map so there's one element for each RT/CIDR combination.
locals {
route_tables = jsondecode(file("templates/my.json"))
rt_cidr_blocks = merge([
for k, rt in local.route_tables:
{
for i, ip_network in rt.ip_network:
"${k}-${i}" => {
tgw_rt_id = rt.tgw_rt_id
ip_network = ip_network
}
}
]...)
}
resource "aws_ec2_transit_gateway_route" "ip_route" {
for_each = local.rt_cidr_blocks
destination_cidr_block = each.value.ip_network
transit_gateway_attachment_id = each.key
transit_gateway_route_table_id = each.value.tgw_rt_id
}
If you want to see what the flattened map looks like now:
output "rt_cidr_blocks" {
value = local.rt_cidr_blocks
}
Output:
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
blocks = {
"RT-1-0" = {
"ip_network" = "1.1.1.0/24"
"tgw_rt_id" = "tgw-rtb-00128"
}
"RT-1-1" = {
"ip_network" = "1.1.2.0/24"
"tgw_rt_id" = "tgw-rtb-00128"
}
"RT-1-2" = {
"ip_network" = "1.1.3.0/24"
"tgw_rt_id" = "tgw-rtb-00128"
}
"RT-2-0" = {
"ip_network" = "1.1.1.0/24"
"tgw_rt_id" = "tgw-rtb-01f1b"
}
"RT-2-1" = {
"ip_network" = "1.1.2.0/24"
"tgw_rt_id" = "tgw-rtb-01f1b"
}
"RT-2-2" = {
"ip_network" = "1.1.3.0/24"
"tgw_rt_id" = "tgw-rtb-01f1b"
}
}
I use React-Intl in my app and it works great, but to be easier to manage new keys to translate I started using "react-intl-translations-manager".
My problem is that some of my translations are used through a notification system and the babel extractor don't recognize them because it's outside of his scan scope.
So when I run "react-intl-translations-manager" it deletes all the keys relatives to notifications and other non-scanned translations.
Here is my question: is there any method to "say" to "react-intl-translations-manager" that it's forbidden to delete those keys ?
I tried multiple solutions including whitelists and other but nothing is working.
Here is my translationRunner.js (the configuration file)
const manageTranslations = require('react-intl-translations-manager').default;
manageTranslations({
messagesDirectory: 'src/messages/',
translationsDirectory: 'src/locales/',
languages: ['en_GB', 'fr_FR']
});
There are two ways to do this. One is to use hooks and another way is to override the module where deletion of the actual code happens.
To do the same we can override the getLanguageReport module from react-intl-translations-manager/dist/getLanguageReport
getLanguageReport = require('react-intl-translations-manager/dist/getLanguageReport');
getLanguageReport.original = getLanguageReport.default
getLanguageReport.default = function(defaultMessages, languageMessages, languageWhitelist) {
data = getLanguageReport.original(defaultMessages, languageMessages, languageWhitelist)
// this whitelist ids can be read through a config file as well
whitelisted_id = ['helloworld2', 'helloworld']
deleted = data.deleted;
re_add = []
for (var i=0; i < deleted.length; ) {
if (whitelisted_id.indexOf(deleted[i].key)>=0) {
// we are removing a record so lets not increment i
removed_element = deleted.splice(i,1)[0];
data.fileOutput[removed_element.key] = removed_element.message;
} else {
i++;
}
}
return data;
}
const manageTranslations = require('react-intl-translations-manager').default;
manageTranslations({
messagesDirectory: 'build/messages/src/extracted/',
translationsDirectory: 'src/translations/locales/',
languages: ['de'] // Any translation --- don't include the default language
}
);
This method works fine and will keep the helloworld2 message even if it is not there in new code.
Hooks approach
In this we use the hook reportLanguage and override it to change the data
const manageTranslations = require('react-intl-translations-manager').default;
const writeFileSync = require('fs').writeFileSync
const stringify = require('react-intl-translations-manager/dist/stringify').default;
stringifyOpts = {
sortKeys: true,
space: 2,
trailingNewline: false,
};
manageTranslations({
messagesDirectory: 'build/messages/src/extracted/',
translationsDirectory: 'src/translations/locales/',
languages: ['de'], // Any translation --- don't include the default language
overrideCoreMethods: {
reportLanguage: function(langResults) {
data = langResults.report;
// this whitelist ids can be read through a config file as well
whitelisted_id = ['helloworld2', 'helloworld']
deleted = data.deleted;
re_add = []
for (var i=0; i < deleted.length; ) {
if (whitelisted_id.indexOf(deleted[i].key)>=0) {
// we are removing a record so lets not increment i
removed_element = deleted.splice(i,1)[0];
data.fileOutput[removed_element.key] = removed_element.message;
} else {
i++;
}
}
// original definition of reportLanguage from manageTranslations.js
// unfortunately the original core method is not exposed for us to re-use
// so we need to copy the code again
if (
!langResults.report.noTranslationFile &&
!langResults.report.noWhitelistFile
) {
// printers.printLanguageReport(langResults);
writeFileSync(
langResults.languageFilepath,
stringify(langResults.report.fileOutput, stringifyOpts)
);
writeFileSync(
langResults.whitelistFilepath,
stringify(langResults.report.whitelistOutput, stringifyOpts)
);
} else {
if (langResults.report.noTranslationFile) {
printers.printNoLanguageFile(langResults);
writeFileSync(
langResults,
stringify(langResults.report.fileOutput, stringifyOpts)
);
}
if (langResults.report.noWhitelistFile) {
printers.printNoLanguageWhitelistFile(langResults);
writeFileSync(
langResults.whitelistFilepath,
stringify([], stringifyOpts)
);
}
}
}
}
});
I am writing an application with search functionalities. There are many filters to be applied so I want to build the filter query outside the find() function in CakePHP 3.4 Application
This is what I want to achieve
$start_year = $this->request->getQuery('start_year');
$end_year = $this->request->getQuery('end_year');
$keyword = $this->request->getQuery('keyword');
$make = $this->request->getQuery('make');
$query_builder = [];
if (!empty($keyword)) {
$query_builder['keyword'] = $keyword;
}
if (!empty($make)) {
$query_builder['make'] = $make;
}
if (!empty($start_year) && empty($end_year))
{
$query_builder['year >'] = $start_year;
}
if (empty($start_year) && !empty($end_year)) {
$query_builder['year <'] = $end_year;
}
if (!empty($start_year) && !empty($end_year)) {
// how to written in BETWEEN query here on year column
}
$results = $this->Model->find()
->where($query_builder);
How to build query in array for IN BETWEEN query ?
if (!empty($start_year) && !empty($end_year)) {
$query_builder['year >='] = $start_year;
$query_builder['year <='] = $end_year;
}
I have a function as $scope.submit() in my angular js application. Following is the code.
scope.submit = function () {
var reqDate = dateFilter(scope.first.date, scope.df);
this.formData.locale = scope.optlang.code;
this.formData.active = this.formData.active || false;
this.formData.dateFormat = scope.df;
this.formData.activationDate = reqDate;
if (routeParams.groupId) {
this.formData.groupId = routeParams.groupId;
}
if (routeParams.officeId) {
this.formData.officeId = routeParams.officeId;
}
if (scope.first.submitondate) {
reqDate = dateFilter(scope.first.submitondate, scope.df);
this.formData.submittedOnDate = reqDate;
}
if (scope.first.dateOfBirth) {
this.formData.dateOfBirth = dateFilter(scope.first.dateOfBirth, scope.df);
}
if (!scope.opensavingsproduct) {
this.formData.savingsProductId = null;
}
resourceFactory.clientResource.save(this.formData, function (data) {
scope.newid = data.clientId;
return scope.newid
});
resourceFactory.clientIdenfierResource.save({
clientId: scope.newid
}, this.formData2, function (data) {
location.path('/viewclient/' + data.clientId);
});
};
The first resourceFactory.clientResource.save creates a client and pass the client id. The second resourceFactory.clientIdenfierResource.save creates the identifier like passport number and check if another client with the same passport number exists.
i wanted to roll back first one if the second doesn't finish. Like if we have a transaction,
save 1 = first transaction
save 2 = second transaction
if save 2 has finished then commit rest of the transaction. How can i do it in angular. Please advise.
I am using the WMD editor's original code (not the Stack Overflow version) since I need multiple of them on the same page and Stack Overflow's version makes heavy use of element IDs internally since they aren't going to be having more than one editor instance per page.
The code runs fine in Firefox 3.5, etc. However, when I run it in Internet Explorer 8 (in Internet Explorer 7 compatibility mode), it freezes the whole browser for about 3 sec. before a new instance shows up. I tried profiling it with Internet Explorer's development tools, and it seems that the getWidth() function on line 520 of the minified version of the code is taking up all the time. However, when I tried to hard-code the return (since it was always returning the same thing), the bottleneck shifted to the getHeight() function.
I am attaching the code I am using to convert it to a jQuery plugin.
jQuery.fn.wmd = function(params) {
function createInstance(container, params) {
/* Make sure WMD has finished loading */
if (!Attacklab || !Attacklab.wmd) {
alert("WMD hasn't finished loading!");
return;
}
var defaultParams = {
width : "600px",
rows : 6,
autogrow : false,
preview : false,
previewDivClassName: "wmd-preview-div"
};
if (typeof(params) == "undefined") {
var params = defaultParams;
}
else {
var params = jQuery.extend({}, defaultParams, params);
}
/* Build the DOM elements */
var textarea = document.createElement("textarea");
textarea.style.width = params.width;
textarea.rows = params.rows;
jQuery(container).append(textarea);
var previewDiv = document.createElement("div");
if (params.preview) {
jQuery(previewDiv).addClass(params.previewDivClassName);
jQuery(container).append(previewDiv);
}
/* Build the preview manager */
var panes = {input:textarea, preview:previewDiv, output:null};
var previewManager = new Attacklab.wmd.previewManager(panes);
/* Build the editor and tell it to refresh the preview after commands */
var editor = new Attacklab.wmd.editor(textarea,previewManager.refresh);
/* Save everything so we can destroy it all later */
var wmdInstance = {ta:textarea, div:previewDiv, ed:editor, pm:previewManager};
var wmdInstanceId = $(container).attr('postID');
wmdInstanceProcs.add(wmdInstanceId, wmdInstance);
if (params.autogrow) {
// $(textarea).autogrow();
}
};
if (jQuery(this).html().length > 0) {
var wmdInstanceId = jQuery(this).attr('postID');
var inst = wmdInstanceProcs.get(wmdInstanceId);
jQuery(inst.ta).show();
}
else {
createInstance(this, params);
}
}
jQuery.fn.unwmd = function(params) {
var wmdInstanceId = $(this).attr('postID');
var inst = wmdInstanceProcs.get(wmdInstanceId);
if (inst != null) {
jQuery(inst.ta).hide();
}
}
wmdInstanceProcs = function() {
var wmdInstances = { };
var getProc = function(wmdInstanceId) {
var inst = wmdInstances[wmdInstanceId];
if (typeof(inst) != "undefined") {
return inst;
}
else {
return null;
}
};
var addProc = function(wmdInstanceId, wmdInstance) {
wmdInstances[wmdInstanceId] = wmdInstance;
};
return {
add: addProc,
get: getProc
};
}();
Any help would be much appreciated.
Maybe the freeze in load time is due to IE 7 rendering the JavaScript. Firefox may be faster at rendering and so it makes IE appear to freeze.